mcli-framework 7.11.0__py3-none-any.whl → 7.11.1__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 mcli-framework might be problematic. Click here for more details.

mcli/app/commands_cmd.py CHANGED
@@ -182,6 +182,261 @@ def workflow():
182
182
  commands = workflow
183
183
 
184
184
 
185
+ @workflow.command("init")
186
+ @click.option(
187
+ "--global", "-g", "is_global", is_flag=True, help="Initialize global workflows directory instead of local"
188
+ )
189
+ @click.option(
190
+ "--git", is_flag=True, help="Initialize git repository in workflows directory"
191
+ )
192
+ @click.option(
193
+ "--force", "-f", is_flag=True, help="Force initialization even if directory exists"
194
+ )
195
+ def init_workflows(is_global, git, force):
196
+ """
197
+ Initialize workflows directory structure.
198
+
199
+ Creates the necessary directories and configuration files for managing
200
+ custom workflows. By default, creates a local .mcli/workflows/ directory
201
+ if in a git repository, otherwise uses ~/.mcli/workflows/.
202
+
203
+ Examples:
204
+ mcli workflow init # Initialize local workflows (if in git repo)
205
+ mcli workflow init --global # Initialize global workflows
206
+ mcli workflow init --git # Also initialize git repository
207
+ """
208
+ from mcli.lib.paths import (
209
+ get_custom_commands_dir,
210
+ get_lockfile_path,
211
+ get_git_root,
212
+ is_git_repository,
213
+ )
214
+
215
+ # Determine if we're in a git repository
216
+ in_git_repo = is_git_repository() and not is_global
217
+ git_root = get_git_root() if in_git_repo else None
218
+
219
+ # Get the workflows directory
220
+ workflows_dir = get_custom_commands_dir(global_mode=is_global)
221
+ lockfile_path = get_lockfile_path(global_mode=is_global)
222
+
223
+ # Check if already initialized
224
+ if workflows_dir.exists() and not force:
225
+ if lockfile_path.exists():
226
+ console.print(f"[yellow]Workflows directory already initialized at:[/yellow] {workflows_dir}")
227
+ console.print(f"[dim]Use --force to reinitialize[/dim]")
228
+
229
+ should_continue = Prompt.ask(
230
+ "Continue anyway?", choices=["y", "n"], default="n"
231
+ )
232
+ if should_continue.lower() != "y":
233
+ return 0
234
+
235
+ # Create workflows directory
236
+ workflows_dir.mkdir(parents=True, exist_ok=True)
237
+ console.print(f"[green]✓[/green] Created workflows directory: {workflows_dir}")
238
+
239
+ # Create README.md
240
+ readme_path = workflows_dir / "README.md"
241
+ if not readme_path.exists() or force:
242
+ scope = "local" if in_git_repo else "global"
243
+ scope_desc = f"for repository: {git_root.name}" if in_git_repo else "globally"
244
+
245
+ readme_content = f"""# MCLI Custom Workflows
246
+
247
+ This directory contains custom workflow commands {scope_desc}.
248
+
249
+ ## Quick Start
250
+
251
+ ### Create a New Workflow
252
+
253
+ ```bash
254
+ # Python workflow
255
+ mcli workflow add my-workflow
256
+
257
+ # Shell workflow
258
+ mcli workflow add my-script --language shell
259
+ ```
260
+
261
+ ### List Workflows
262
+
263
+ ```bash
264
+ mcli workflow list --custom-only
265
+ ```
266
+
267
+ ### Execute a Workflow
268
+
269
+ ```bash
270
+ mcli workflows my-workflow
271
+ ```
272
+
273
+ ### Edit a Workflow
274
+
275
+ ```bash
276
+ mcli workflow edit my-workflow
277
+ ```
278
+
279
+ ### Export/Import Workflows
280
+
281
+ ```bash
282
+ # Export all workflows
283
+ mcli workflow export workflows-backup.json
284
+
285
+ # Import workflows
286
+ mcli workflow import workflows-backup.json
287
+ ```
288
+
289
+ ## Directory Structure
290
+
291
+ ```
292
+ {workflows_dir.name}/
293
+ ├── README.md # This file
294
+ ├── commands.lock.json # Lockfile for workflow state
295
+ └── *.json # Individual workflow definitions
296
+ ```
297
+
298
+ ## Workflow Format
299
+
300
+ Workflows are stored as JSON files with the following structure:
301
+
302
+ ```json
303
+ {{
304
+ "name": "workflow-name",
305
+ "description": "Workflow description",
306
+ "code": "Python or shell code",
307
+ "language": "python",
308
+ "group": "workflow",
309
+ "version": "1.0",
310
+ "created_at": "2025-10-30T...",
311
+ "updated_at": "2025-10-30T..."
312
+ }}
313
+ ```
314
+
315
+ ## Scope
316
+
317
+ - **Scope**: {'Local (repository-specific)' if in_git_repo else 'Global (user-wide)'}
318
+ - **Location**: `{workflows_dir}`
319
+ {f"- **Git Repository**: `{git_root}`" if git_root else ""}
320
+
321
+ ## Documentation
322
+
323
+ - [MCLI Documentation](https://github.com/gwicho38/mcli)
324
+ - [Workflow Guide](https://github.com/gwicho38/mcli/blob/main/docs/features/LOCAL_VS_GLOBAL_COMMANDS.md)
325
+
326
+ ---
327
+
328
+ *Initialized: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
329
+ """
330
+
331
+ readme_path.write_text(readme_content)
332
+ console.print(f"[green]✓[/green] Created README: {readme_path.name}")
333
+
334
+ # Initialize lockfile
335
+ if not lockfile_path.exists() or force:
336
+ lockfile_data = {
337
+ "version": "1.0",
338
+ "initialized_at": datetime.now().isoformat(),
339
+ "scope": "local" if in_git_repo else "global",
340
+ "commands": {}
341
+ }
342
+
343
+ with open(lockfile_path, "w") as f:
344
+ json.dump(lockfile_data, f, indent=2)
345
+
346
+ console.print(f"[green]✓[/green] Initialized lockfile: {lockfile_path.name}")
347
+
348
+ # Create .gitignore if in workflows directory
349
+ gitignore_path = workflows_dir / ".gitignore"
350
+ if not gitignore_path.exists() or force:
351
+ gitignore_content = """# Backup files
352
+ *.backup
353
+ *.bak
354
+
355
+ # Temporary files
356
+ *.tmp
357
+ *.temp
358
+
359
+ # OS files
360
+ .DS_Store
361
+ Thumbs.db
362
+
363
+ # Editor files
364
+ *.swp
365
+ *.swo
366
+ *~
367
+ .vscode/
368
+ .idea/
369
+ """
370
+ gitignore_path.write_text(gitignore_content)
371
+ console.print(f"[green]✓[/green] Created .gitignore")
372
+
373
+ # Initialize git if requested
374
+ if git and not (workflows_dir / ".git").exists():
375
+ try:
376
+ subprocess.run(
377
+ ["git", "init"],
378
+ cwd=workflows_dir,
379
+ check=True,
380
+ capture_output=True
381
+ )
382
+ console.print(f"[green]✓[/green] Initialized git repository in workflows directory")
383
+
384
+ # Create initial commit
385
+ subprocess.run(
386
+ ["git", "add", "."],
387
+ cwd=workflows_dir,
388
+ check=True,
389
+ capture_output=True
390
+ )
391
+ subprocess.run(
392
+ ["git", "commit", "-m", "Initial commit: Initialize workflows directory"],
393
+ cwd=workflows_dir,
394
+ check=True,
395
+ capture_output=True
396
+ )
397
+ console.print(f"[green]✓[/green] Created initial commit")
398
+
399
+ except subprocess.CalledProcessError as e:
400
+ console.print(f"[yellow]⚠[/yellow] Git initialization failed: {e}")
401
+ except FileNotFoundError:
402
+ console.print(f"[yellow]⚠[/yellow] Git not found. Skipping git initialization.")
403
+
404
+ # Summary
405
+ console.print()
406
+ console.print("[bold green]Workflows directory initialized successfully![/bold green]")
407
+ console.print()
408
+
409
+ # Display summary table
410
+ table = Table(title="Initialization Summary", show_header=False)
411
+ table.add_column("Property", style="cyan")
412
+ table.add_column("Value", style="green")
413
+
414
+ table.add_row("Scope", "Local (repository-specific)" if in_git_repo else "Global (user-wide)")
415
+ table.add_row("Location", str(workflows_dir))
416
+ if git_root:
417
+ table.add_row("Git Repository", str(git_root))
418
+ table.add_row("Lockfile", str(lockfile_path))
419
+ table.add_row("Git Initialized", "Yes" if git and (workflows_dir / ".git").exists() else "No")
420
+
421
+ console.print(table)
422
+ console.print()
423
+
424
+ # Next steps
425
+ console.print("[bold]Next Steps:[/bold]")
426
+ console.print(" 1. Create a workflow: [cyan]mcli workflow add my-workflow[/cyan]")
427
+ console.print(" 2. List workflows: [cyan]mcli workflow list --custom-only[/cyan]")
428
+ console.print(" 3. Execute workflow: [cyan]mcli workflows my-workflow[/cyan]")
429
+ console.print(" 4. View README: [cyan]cat {}/README.md[/cyan]".format(workflows_dir))
430
+ console.print()
431
+
432
+ if in_git_repo:
433
+ console.print(f"[dim]Tip: Workflows are local to this repository. Use --global for user-wide workflows.[/dim]")
434
+ else:
435
+ console.print(f"[dim]Tip: Use workflows in any git repository, or create local ones with 'mcli workflow init' inside repos.[/dim]")
436
+
437
+ return 0
438
+
439
+
185
440
  @workflow.command("list")
186
441
  @click.option("--include-groups", is_flag=True, help="Include command groups in listing")
187
442
  @click.option("--daemon-only", is_flag=True, help="Show only daemon database commands")
mcli/lib/paths.py CHANGED
@@ -158,9 +158,13 @@ def get_local_commands_dir() -> Optional[Path]:
158
158
  if workflows_dir.exists():
159
159
  return workflows_dir
160
160
 
161
- # Fall back to old commands directory for migration support
161
+ # Check if old commands directory exists (for migration support)
162
162
  commands_dir = local_mcli / "commands"
163
- return commands_dir
163
+ if commands_dir.exists():
164
+ return commands_dir
165
+
166
+ # If neither exists, return workflows path (for new installations)
167
+ return workflows_dir
164
168
  return None
165
169
 
166
170
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcli-framework
3
- Version: 7.11.0
3
+ Version: 7.11.1
4
4
  Summary: Portable workflow framework - transform any script into a versioned, schedulable command. Store in ~/.mcli/commands/, version with lockfile, run as daemon or cron job.
5
5
  Author-email: Luis Fernandez de la Vara <luis@lefv.io>
6
6
  Maintainer-email: Luis Fernandez de la Vara <luis@lefv.io>
@@ -216,6 +216,24 @@ pip install mcli-framework
216
216
  uv pip install mcli-framework
217
217
  ```
218
218
 
219
+ ### Initialize Workflows Directory
220
+
221
+ ```bash
222
+ # Initialize workflows in current git repository
223
+ mcli workflow init
224
+
225
+ # Or initialize global workflows
226
+ mcli workflow init --global
227
+
228
+ # Initialize with git repository for workflows
229
+ mcli workflow init --git
230
+ ```
231
+
232
+ This creates a `.mcli/workflows/` directory (local to your repo) or `~/.mcli/workflows/` (global) with:
233
+ - README.md with usage instructions
234
+ - commands.lock.json for version tracking
235
+ - .gitignore for backup files
236
+
219
237
  ### Create Your First Workflow
220
238
 
221
239
  #### Method 1: From a Python Script
@@ -3,7 +3,7 @@ mcli/__main__.py,sha256=nKdf3WqtXi5PhWhZGjpXKAT3a2yGUYkYCBgSLxk4hSQ,295
3
3
  mcli/cli.py,sha256=6KTyXn-pmVkAbCDu59PbiNKBwNra5su31ujFFZ6CBOM,389
4
4
  mcli/config.toml,sha256=263yEVvP_W9F2zOLssUBgy7amKaRAFQuBrfxcMhKxaQ,1706
5
5
  mcli/app/__init__.py,sha256=D4RiKk2gOEXwanbe_jXyNSb5zdgNi47kahtskMnEwjY,489
6
- mcli/app/commands_cmd.py,sha256=MQqIsvpJG9ev43nyD_q_QsViVXYhC40I-eTBpgCtTeU,68296
6
+ mcli/app/commands_cmd.py,sha256=ATjWgOToqPfJuNaCT1utw0TfMuLdamHu3a_brsn6lTc,75967
7
7
  mcli/app/completion_helpers.py,sha256=e62C6w2N-XoD66GYYHgtvKKoD3kYMuIeBBGzVKbuL04,7497
8
8
  mcli/app/main.py,sha256=CzF1iudFhVdAtC5d_KzRVAc6XT5Lkq6WZ1NnNKpdWnE,19165
9
9
  mcli/app/model_cmd.py,sha256=LQQD8FaebFoaJGK3u_kt19wZ3HJyo_ecwSMYyC2xIp8,2497
@@ -21,7 +21,7 @@ mcli/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  mcli/lib/custom_commands.py,sha256=oDgNuPHonjZ7ckwX4-38XsqZOcaR05ESpuSbSFMB-s4,21739
22
22
  mcli/lib/lib.py,sha256=-CFUfmcubYBxt3LDBY0uj9DF232pz8MPDu-Qg0Ocy8M,850
23
23
  mcli/lib/optional_deps.py,sha256=z6jPjU9mjK2ipMf8gzdc_izYSyqefQRzUZWgj_CumtM,7568
24
- mcli/lib/paths.py,sha256=PWDMj2aGVZO-cVc-TSV9eK_B3si5rGwl-LkJjGmV2eE,6264
24
+ mcli/lib/paths.py,sha256=3-yseYbqQ-711GUSO8qlI3Tnlwx4BFO48IeiUETIY-A,6412
25
25
  mcli/lib/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  mcli/lib/api/api.py,sha256=sPgAIYC8Z7AWV2TCBssNSKotbRggBqNLsbfzbjkhmUY,18558
27
27
  mcli/lib/api/daemon_client.py,sha256=Nq8sVvNKyIGvWp9G_O3NEFo9JDqA1TEx5FOB7iqslB4,7415
@@ -268,9 +268,9 @@ mcli/workflow/sync/test_cmd.py,sha256=neVgs9zEnKSxlvzDpFkuCGucqnzjrShm2OvJtHibsl
268
268
  mcli/workflow/videos/__init__.py,sha256=aV3DEoO7qdKJY4odWKoQbOKDQq4ludTeCLnZcupOFIM,25
269
269
  mcli/workflow/wakatime/__init__.py,sha256=wKG8cVIHVtMPhNRFGFtX43bRnocHqOMMkFMkmW-M6pU,2626
270
270
  mcli/workflow/wakatime/wakatime.py,sha256=sEjsUKa3-XyE8Ni6sAb_D3GAY5jDcA30KknW9YTbLTA,142
271
- mcli_framework-7.11.0.dist-info/licenses/LICENSE,sha256=sahwAMfrJv2-V66HNPTp7A9UmMjxtyejwTZZoWQvEcI,1075
272
- mcli_framework-7.11.0.dist-info/METADATA,sha256=I-WJjz8wDaJNvTojEHuQcp1kpJUH0h5I0jQIphxL14I,18190
273
- mcli_framework-7.11.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
274
- mcli_framework-7.11.0.dist-info/entry_points.txt,sha256=dYrZbDIm-KUPsl1wfv600Kx_8sMy89phMkCihbDRgP8,261
275
- mcli_framework-7.11.0.dist-info/top_level.txt,sha256=_bnO8J2EUkliWivey_1le0UrnocFKmyVMQjbQ8iVXjc,5
276
- mcli_framework-7.11.0.dist-info/RECORD,,
271
+ mcli_framework-7.11.1.dist-info/licenses/LICENSE,sha256=sahwAMfrJv2-V66HNPTp7A9UmMjxtyejwTZZoWQvEcI,1075
272
+ mcli_framework-7.11.1.dist-info/METADATA,sha256=KeSWCStVjxu_60X55omZy_Jq_3ciMZBLiNIVxc7xXv4,18655
273
+ mcli_framework-7.11.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
274
+ mcli_framework-7.11.1.dist-info/entry_points.txt,sha256=dYrZbDIm-KUPsl1wfv600Kx_8sMy89phMkCihbDRgP8,261
275
+ mcli_framework-7.11.1.dist-info/top_level.txt,sha256=_bnO8J2EUkliWivey_1le0UrnocFKmyVMQjbQ8iVXjc,5
276
+ mcli_framework-7.11.1.dist-info/RECORD,,