machineconfig 6.66__py3-none-any.whl → 6.67__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.

Potentially problematic release.


This version of machineconfig might be problematic. Click here for more details.

@@ -2178,6 +2178,23 @@
2178
2178
  }
2179
2179
  }
2180
2180
  },
2181
+ {
2182
+ "appName": "kilocode",
2183
+ "repoURL": "CMD",
2184
+ "doc": "Kilocode agent extension in the terminal",
2185
+ "fileNamePattern": {
2186
+ "amd64": {
2187
+ "linux": "npm install -g @kilocode/cli@alpha",
2188
+ "windows": "npm install -g @kilocode/cli@alpha",
2189
+ "macos": "npm install -g @kilocode/cli@alpha"
2190
+ },
2191
+ "arm64": {
2192
+ "linux": "npm install -g @kilocode/cli@alpha",
2193
+ "windows": "npm install -g @kilocode/cli@alpha",
2194
+ "macos": "npm install -g @kilocode/cli@alpha"
2195
+ }
2196
+ }
2197
+ },
2181
2198
  {
2182
2199
  "appName": "copilot",
2183
2200
  "repoURL": "CMD",
@@ -130,10 +130,6 @@ def run(ctx: typer.Context,
130
130
  print(f"❌ Unsupported platform: {platform.system()}")
131
131
 
132
132
 
133
- def kill_process():
134
- from machineconfig.utils.procs import main
135
- main()
136
-
137
133
  def get_app():
138
134
  layouts_app = typer.Typer(help="Layouts management subcommands", no_args_is_help=True, add_help_option=False, add_completion=False)
139
135
  from machineconfig.scripts.python.helpers_sessions.sessions_multiprocess import create_from_function
@@ -143,8 +139,6 @@ def get_app():
143
139
  layouts_app.command("r", no_args_is_help=True, help="Run the selected layout(s)", hidden=True)(run)
144
140
  layouts_app.command("balance-load", no_args_is_help=True, help="[b] Balance the load across sessions")(balance_load)
145
141
  layouts_app.command("b", no_args_is_help=True, help="Balance the load across sessions", hidden=True)(balance_load)
146
- layouts_app.command("kill-process", no_args_is_help=False, help="[k] Choose a process to kill")(kill_process)
147
- layouts_app.command("k", no_args_is_help=False, help="Choose a process to kill", hidden=True)(kill_process)
148
142
 
149
143
  return layouts_app
150
144
 
@@ -2,11 +2,49 @@
2
2
 
3
3
  from machineconfig.scripts.python.helpers_devops.cli_utils import download, merge_pdfs, get_machine_specs
4
4
  import typer
5
+ from typing import Annotated, Optional
6
+ from pathlib import Path
7
+
8
+
9
+ def kill_process(
10
+ # name: Annotated[Optional[str], typer.Option(..., "--name", "-n", help="Name of the process to kill")],
11
+ # command: Annotated[str, typer.Option(..., "--command", "-c", help="Match by command line instead of process name")] = "",
12
+ interactive: Annotated[bool, typer.Option(..., "--interactive", "-i", help="Interactively choose the process to kill")] = True):
13
+ from machineconfig.utils.procs import main, ProcessManager
14
+ if interactive:
15
+ main()
16
+ return
17
+ _ = ProcessManager
18
+ # pm = ProcessManager()
19
+ # if command:
20
+ # pm.filter_and_kill(name=command
21
+ # )
22
+
23
+
24
+ def add_dev_packages(repo_dir: Annotated[Optional[str], typer.Option(..., "--repo-dir", "-r", help="Path to the repository root directory")] = None):
25
+ if repo_dir is None:
26
+ r_dir = Path.cwd()
27
+ else:
28
+ r_dir = Path(repo_dir).resolve()
29
+ if not r_dir.exists() or not r_dir.is_dir() or not (r_dir / "pyproject.toml").exists():
30
+ typer.echo(f"❌ The provided repo directory `{r_dir}` is not valid or does not contain a `pyproject.toml` file.")
31
+ raise typer.Exit(code=1)
32
+ command = f"""
33
+ cd "{r_dir}" || exit 1
34
+ uv add nbformat ipdb ipykernel ipython pylint pyright mypy pyrefly ty pytest
35
+ """
36
+ from machineconfig.utils.code import run_shell_script
37
+ typer.echo(f"➡️ Installing dev packages in repo at `{r_dir}`...")
38
+ run_shell_script(command)
39
+ typer.echo(f"✅ Dev packages installed successfully in repo at `{r_dir}`.")
40
+ # TODO: see upgrade packages.
5
41
 
6
42
 
7
43
 
8
44
  def get_app() -> typer.Typer:
9
45
  app = typer.Typer(help="🛠️ utilities operations", no_args_is_help=True, add_help_option=False, add_completion=False)
46
+ app.command(name="kill-process", no_args_is_help=False, help="[k] Choose a process to kill")(kill_process)
47
+ app.command(name="k", no_args_is_help=False, help="Choose a process to kill", hidden=True)(kill_process)
10
48
  app.command(name="download", no_args_is_help=True, help="[d] Download a file from a URL and optionally decompress it.")(download)
11
49
  app.command(name="d", no_args_is_help=True, hidden=True)(download)
12
50
  app.command(name="merge-pdfs", no_args_is_help=True, help="[m] Merge two PDF files into one.")(merge_pdfs)
@@ -164,7 +164,7 @@ class CacheMemory[T]():
164
164
  def age(self) -> timedelta:
165
165
  return datetime.now() - self.time_produced
166
166
 
167
- def __call__(self, fresh: bool = False) -> T:
167
+ def __call__(self, fresh: bool = False, tolerance_seconds: int = 1000000000000) -> T:
168
168
  if fresh or not hasattr(self, "cache"):
169
169
  why = "There was an explicit fresh order." if fresh else "Previous cache never existed."
170
170
  t0 = time.time()
@@ -176,7 +176,7 @@ class CacheMemory[T]():
176
176
  self.time_produced = datetime.now()
177
177
  else:
178
178
  age = self.age
179
- if age > self.expire:
179
+ if (age > self.expire) or (fresh and (age.total_seconds() > tolerance_seconds)):
180
180
  self.logger.warning(f"""
181
181
  🔄 ════════════════════ CACHE UPDATE ════════════════════
182
182
  ⚠️ {self.name} cache: Updating cache from source func
@@ -214,14 +214,24 @@ class Cache[T](): # This class helps to accelrate access to latest data coming
214
214
  self.logger = logger
215
215
  self.expire = expire
216
216
  self.name = name if isinstance(name, str) else self.source_func.__name__
217
- @property
218
- def age(self):
219
- """Throws AttributeError if called before cache is populated and path doesn't exists"""
217
+ def get_age(self):
220
218
  return datetime.now() - self.time_produced
221
- def __call__(self, fresh: bool = False) -> T:
222
- if fresh or not hasattr(self, "cache"): # populate cache for the first time
223
- if not fresh and self.path.exists():
219
+ def __call__(self, fresh: bool = False, tolerance_seconds: int = 1000000000000) -> T:
220
+ if not hasattr(self, "cache"): # populate cache for the first time: we have two options, populate from disk or from source func.
221
+ if self.path.exists(): # prefer to read from disk over source func as a default source of cache.
224
222
  age = datetime.now() - datetime.fromtimestamp(self.path.stat().st_mtime)
223
+ if (age > self.expire) or (fresh and (age.total_seconds() > tolerance_seconds)): # cache is old or if fresh flag is raised
224
+ self.logger.warning(f"""
225
+ 🔄 ════════════════════ CACHE STALE ════════════════════
226
+ 📦 {self.name} cache: Populating fresh cache from source func
227
+ ⏱️ Lag = {age}""")
228
+ t0 = time.time()
229
+ self.cache = self.source_func() # fresh data.
230
+ self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
231
+ self.time_produced = datetime.now()
232
+ self.save(self.cache, self.path)
233
+ return self.cache
234
+
225
235
  msg1 = f"""
226
236
  📦 ════════════════════ CACHE OPERATION ════════════════════
227
237
  🔄 {self.name} cache: Reading cached values from `{self.path}`
@@ -240,10 +250,8 @@ class Cache[T](): # This class helps to accelrate access to latest data coming
240
250
  self.time_produced = datetime.now()
241
251
  self.save(self.cache, self.path)
242
252
  return self.cache
243
- return self(fresh=False) # may be the cache is old ==> check that by passing it through the logic again.
244
- else:
245
- # Previous cache never existed or there was an explicit fresh order.
246
- why = "There was an explicit fresh order." if fresh else "Previous cache never existed or is corrupted."
253
+ else: # disk cache does not exist, populate from source func.
254
+ why = "Previous cache never existed."
247
255
  self.logger.warning(f"""
248
256
  🆕 ════════════════════ NEW CACHE ════════════════════
249
257
  🔄 {self.name} cache: Populating fresh cache from source func
@@ -253,12 +261,9 @@ class Cache[T](): # This class helps to accelrate access to latest data coming
253
261
  self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
254
262
  self.time_produced = datetime.now()
255
263
  self.save(self.cache, self.path)
256
- else: # cache exists
257
- try:
258
- age = self.age
259
- except AttributeError: # path doesn't exist (may be deleted) ==> need to repopulate cache form source_func.
260
- return self(fresh=True)
261
- if age > self.expire:
264
+ else: # memory cache exists
265
+ age = self.get_age()
266
+ if (age > self.expire) or (fresh and (age.total_seconds() > tolerance_seconds)): # cache is old or if fresh flag is raised
262
267
  self.logger.warning(f"""
263
268
  🔄 ════════════════════ CACHE UPDATE ════════════════════
264
269
  ⚠️ {self.name} cache: Updating cache from source func
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machineconfig
3
- Version: 6.66
3
+ Version: 6.67
4
4
  Summary: Dotfiles management package
5
5
  Author-email: Alex Al-Saffar <programmer@usa.com>
6
6
  License: Apache 2.0
@@ -47,7 +47,7 @@ machineconfig/cluster/templates/cli_trogon.py,sha256=PFWGy8SFYIhT9r3ZV4oIEYfImsQ
47
47
  machineconfig/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
48
  machineconfig/jobs/installer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  machineconfig/jobs/installer/check_installations.py,sha256=hkHmmT7Bx3_QWRn2v8dCKOzAapFzqHRzbe-Q08GLnKE,10743
50
- machineconfig/jobs/installer/installer_data.json,sha256=h0k4xeqURIj1dl5BrZxAdAi-3ywbDHPxyDkWFPuZK-k,76471
50
+ machineconfig/jobs/installer/installer_data.json,sha256=PPpfmo2WZi6RSHMsb7YvqewRr9IQ81B5-tN7bCXjCFc,77032
51
51
  machineconfig/jobs/installer/package_groups.py,sha256=i4z83F_rk7BVsrwFhz5Vn4SLF0IHxyQBFSxpAaZBl8M,5270
52
52
  machineconfig/jobs/installer/custom/gh.py,sha256=gn7TUSrsLx7uqFqj1Z-iYglS0EYBSgtJ9jWHxaJIfXM,4119
53
53
  machineconfig/jobs/installer/custom/hx.py,sha256=YQClQXqWtGvon8BLFGf1Fp20JPkHgZeEZ6ebmCJQQfI,5838
@@ -129,8 +129,8 @@ machineconfig/scripts/python/entry.py,sha256=liCf186Msa6R-EjcQ0I6K80Km7Wi8qckJB6
129
129
  machineconfig/scripts/python/fire_jobs.py,sha256=My7sFn1R2vh21uIHGfNppgX99WTEitCFgJ1MSasBUOQ,13597
130
130
  machineconfig/scripts/python/ftpx.py,sha256=A13hL_tDYfcsaK9PkshK-0lrUS6KPhPCtwqWtLSo6IM,9764
131
131
  machineconfig/scripts/python/interactive.py,sha256=zt3g6nGKR_Y5A57UnR4Y5-JpLzrpnCOSaqU1bnaikK0,11666
132
- machineconfig/scripts/python/sessions.py,sha256=UERxO472EDtN7nKHEULbn6G3S5PJIpsDG9Gq3TlByqI,9823
133
- machineconfig/scripts/python/utils.py,sha256=c9HsKG40i5ggwqKuS3O-LCScuFpmxMVKqWpsFHx2dJc,934
132
+ machineconfig/scripts/python/sessions.py,sha256=JfN8M7r7f8DkfiGJ4jz2NfXvABm90nOZJmLGxPgw_2M,9518
133
+ machineconfig/scripts/python/utils.py,sha256=9ckI_2Nu9Z8W9cT6QNKreXVtwNA5RXD05nWemPb2sIg,2797
134
134
  machineconfig/scripts/python/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
135
135
  machineconfig/scripts/python/ai/generate_files.py,sha256=VfjKdwgF8O6E4oiRtfWNliibLmmwGe7f9ld6wpOsXTw,14498
136
136
  machineconfig/scripts/python/ai/initai.py,sha256=9SZtWOcRuwk8ZU3wHOfPzjInERD79ZTYFY8tVACgza4,2260
@@ -404,7 +404,7 @@ machineconfig/utils/options.py,sha256=vUO4Kej-vDOv64wHr2HNDyu6PATURpjd7xp6N8OOoJ
404
404
  machineconfig/utils/path_extended.py,sha256=WyJwoHnXdvSQQJ-yrxTX78FpqYmgVeKDYpNEB9UsRck,53223
405
405
  machineconfig/utils/path_helper.py,sha256=0e3Xh3BAEv27oqcezNeVLHJllGmLEgLH4T1l90m-650,8014
406
406
  machineconfig/utils/procs.py,sha256=YPA_vEYQGwPd_o_Lc6nOTBo5BrB1tSs8PJ42XiGpenM,10957
407
- machineconfig/utils/scheduler.py,sha256=44CASABJg3epccxhAwv2CX7TVgZh6zVy3K4vqHKTuf4,14228
407
+ machineconfig/utils/scheduler.py,sha256=vOdkk1wHz3A0hF6bGJJ84AbprhqAEv-69Wf65qPLnuo,14861
408
408
  machineconfig/utils/scheduling.py,sha256=6x5zLA7sY5gohrEtN6zGrXIqNFasMoyBfwLcOjrjiME,11109
409
409
  machineconfig/utils/source_of_truth.py,sha256=ZAnCRltiM07ig--P6g9_6nEAvNFC4X4ERFTVcvpIYsE,764
410
410
  machineconfig/utils/ssh.py,sha256=8LEH4n1H5CNEItuA3kWIc_B_doa9nieS31St7CWwkCo,38991
@@ -436,8 +436,8 @@ machineconfig/utils/schemas/installer/installer_types.py,sha256=QClRY61QaduBPJoS
436
436
  machineconfig/utils/schemas/layouts/layout_types.py,sha256=TcqlZdGVoH8htG5fHn1KWXhRdPueAcoyApppZsPAPto,2020
437
437
  machineconfig/utils/schemas/repos/repos_types.py,sha256=ECVr-3IVIo8yjmYmVXX2mnDDN1SLSwvQIhx4KDDQHBQ,405
438
438
  machineconfig/utils/ssh_utils/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
439
- machineconfig-6.66.dist-info/METADATA,sha256=x22tdOq0MAHHzJ37_cwFy6FDx4AY31YWmuIg7pgnQSM,2928
440
- machineconfig-6.66.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
441
- machineconfig-6.66.dist-info/entry_points.txt,sha256=NTW7hbUlpt5Vx9DdQrONLkYMCuBXpvYh1dt0AtlGxeI,466
442
- machineconfig-6.66.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
443
- machineconfig-6.66.dist-info/RECORD,,
439
+ machineconfig-6.67.dist-info/METADATA,sha256=pnBakIwJbF5CqCnGDgJikbFmsla3QmwkSY2n20edgx8,2928
440
+ machineconfig-6.67.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
441
+ machineconfig-6.67.dist-info/entry_points.txt,sha256=NTW7hbUlpt5Vx9DdQrONLkYMCuBXpvYh1dt0AtlGxeI,466
442
+ machineconfig-6.67.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
443
+ machineconfig-6.67.dist-info/RECORD,,