devs-cli 5.0.5__py3-none-any.whl → 6.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.
- devs/cli.py +145 -170
- {devs_cli-5.0.5.dist-info → devs_cli-6.0.0.dist-info}/METADATA +1 -1
- {devs_cli-5.0.5.dist-info → devs_cli-6.0.0.dist-info}/RECORD +7 -7
- {devs_cli-5.0.5.dist-info → devs_cli-6.0.0.dist-info}/WHEEL +0 -0
- {devs_cli-5.0.5.dist-info → devs_cli-6.0.0.dist-info}/entry_points.txt +0 -0
- {devs_cli-5.0.5.dist-info → devs_cli-6.0.0.dist-info}/licenses/LICENSE +0 -0
- {devs_cli-5.0.5.dist-info → devs_cli-6.0.0.dist-info}/top_level.txt +0 -0
devs/cli.py
CHANGED
|
@@ -5,6 +5,7 @@ import sys
|
|
|
5
5
|
import subprocess
|
|
6
6
|
import traceback
|
|
7
7
|
from functools import wraps
|
|
8
|
+
from typing import Callable, Sequence
|
|
8
9
|
from importlib.metadata import version, PackageNotFoundError
|
|
9
10
|
|
|
10
11
|
import click
|
|
@@ -14,6 +15,7 @@ from rich.table import Table
|
|
|
14
15
|
from .config import config
|
|
15
16
|
from .core import Project, ContainerManager, WorkspaceManager
|
|
16
17
|
from .core.integration import VSCodeIntegration, ExternalToolIntegration
|
|
18
|
+
from devs_common.agents import AgentSpec, get_agent
|
|
17
19
|
from devs_common.devs_config import DevsConfigLoader
|
|
18
20
|
from devs_common.utils.repo_cache import RepoCache
|
|
19
21
|
from .exceptions import (
|
|
@@ -379,9 +381,21 @@ def stop(dev_names: tuple) -> None:
|
|
|
379
381
|
|
|
380
382
|
container_manager = ContainerManager(project, config)
|
|
381
383
|
|
|
384
|
+
failed = []
|
|
382
385
|
for dev_name in dev_names:
|
|
383
386
|
console.print(f" Stopping: {dev_name}")
|
|
384
|
-
|
|
387
|
+
# Keep going past a failure so one bad container doesn't leave the rest running.
|
|
388
|
+
# stop_container reports Docker errors and missing containers itself, returning False.
|
|
389
|
+
try:
|
|
390
|
+
stopped = container_manager.stop_container(dev_name, remove=False)
|
|
391
|
+
except ContainerError as e:
|
|
392
|
+
console.print(f" ❌ Error stopping {dev_name}: {e}")
|
|
393
|
+
stopped = False
|
|
394
|
+
if stopped is False:
|
|
395
|
+
failed.append(dev_name)
|
|
396
|
+
|
|
397
|
+
if failed:
|
|
398
|
+
sys.exit(1)
|
|
385
399
|
|
|
386
400
|
|
|
387
401
|
@cli.command()
|
|
@@ -424,46 +438,8 @@ def shell(dev_name: str, live: bool, env: tuple, debug: bool) -> None:
|
|
|
424
438
|
sys.exit(1)
|
|
425
439
|
|
|
426
440
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
@click.argument('prompt', required=False)
|
|
430
|
-
@click.option('--auth', is_flag=True, help='Show Claude authentication setup instructions')
|
|
431
|
-
@click.option('--reset-workspace', is_flag=True, help='Reset workspace contents before execution')
|
|
432
|
-
@click.option('--live', is_flag=True, help='Start container with current directory mounted as workspace')
|
|
433
|
-
@click.option('--env', multiple=True, help='Environment variables to pass to container (format: VAR=value)')
|
|
434
|
-
@debug_option
|
|
435
|
-
def claude(dev_name: str, prompt: str, auth: bool, reset_workspace: bool, live: bool, env: tuple, debug: bool) -> None:
|
|
436
|
-
"""Execute Claude CLI in devcontainer or set up authentication.
|
|
437
|
-
|
|
438
|
-
DEV_NAME: Development environment name
|
|
439
|
-
PROMPT: Prompt to send to Claude
|
|
440
|
-
|
|
441
|
-
Example: devs claude sally "Summarize this codebase"
|
|
442
|
-
Example: devs claude sally "Fix the tests" --reset-workspace
|
|
443
|
-
Example: devs claude sally "Fix the tests" --live # Run with current directory
|
|
444
|
-
Example: devs claude sally "Start the server" --env QUART_PORT=5001
|
|
445
|
-
Example: devs claude --auth # Show auth setup instructions
|
|
446
|
-
"""
|
|
447
|
-
# Handle authentication mode
|
|
448
|
-
if auth:
|
|
449
|
-
console.print("🔐 Claude authentication for devcontainers")
|
|
450
|
-
console.print("")
|
|
451
|
-
console.print("1. Generate a token (on a machine with a browser):")
|
|
452
|
-
console.print(" [cyan]claude setup-token[/cyan]")
|
|
453
|
-
console.print("")
|
|
454
|
-
console.print("2. Add the token to your environment:")
|
|
455
|
-
console.print(" [cyan]export CLAUDE_CODE_OAUTH_TOKEN=<token>[/cyan]")
|
|
456
|
-
console.print("")
|
|
457
|
-
console.print(" Or add it to [cyan]~/.devs/envs/default/.env[/cyan]:")
|
|
458
|
-
console.print(" [dim]CLAUDE_CODE_OAUTH_TOKEN=<token>[/dim]")
|
|
459
|
-
console.print("")
|
|
460
|
-
console.print("The token will be automatically passed to all devcontainers.")
|
|
461
|
-
return
|
|
462
|
-
|
|
463
|
-
# Validate required arguments for execution mode
|
|
464
|
-
if not dev_name or not prompt:
|
|
465
|
-
raise click.UsageError("DEV_NAME and PROMPT are required unless using --auth")
|
|
466
|
-
|
|
441
|
+
def _run_agent(agent: AgentSpec, dev_name: str, prompt: str, reset_workspace: bool, live: bool, env: tuple, debug: bool) -> None:
|
|
442
|
+
"""Run a coding agent against a prompt in a devcontainer, streaming its output."""
|
|
467
443
|
check_dependencies()
|
|
468
444
|
project = get_project()
|
|
469
445
|
|
|
@@ -482,14 +458,15 @@ def claude(dev_name: str, prompt: str, auth: bool, reset_workspace: bool, live:
|
|
|
482
458
|
# Ensure workspace exists (handles live mode and reset internally)
|
|
483
459
|
workspace_dir = workspace_manager.create_workspace(dev_name, reset_contents=reset_workspace, live=live)
|
|
484
460
|
|
|
485
|
-
# Execute
|
|
486
|
-
console.print(f"🤖 Executing
|
|
461
|
+
# Execute the agent (ensure_container_running is called internally)
|
|
462
|
+
console.print(f"🤖 Executing {agent.display_name} in {dev_name}...")
|
|
487
463
|
if reset_workspace and not live:
|
|
488
464
|
console.print("🗑️ Workspace contents reset")
|
|
489
465
|
console.print(f"📝 Prompt: {prompt}")
|
|
490
466
|
console.print("")
|
|
491
467
|
|
|
492
|
-
success, output, error, _ = container_manager.
|
|
468
|
+
success, output, error, _ = container_manager.exec_agent(
|
|
469
|
+
agent,
|
|
493
470
|
dev_name=dev_name,
|
|
494
471
|
workspace_dir=workspace_dir,
|
|
495
472
|
prompt=prompt,
|
|
@@ -501,9 +478,9 @@ def claude(dev_name: str, prompt: str, auth: bool, reset_workspace: bool, live:
|
|
|
501
478
|
|
|
502
479
|
console.print("") # Add spacing after streamed output
|
|
503
480
|
if success:
|
|
504
|
-
console.print("✅
|
|
481
|
+
console.print(f"✅ {agent.display_name} execution completed")
|
|
505
482
|
else:
|
|
506
|
-
console.print("❌
|
|
483
|
+
console.print(f"❌ {agent.display_name} execution failed")
|
|
507
484
|
if error:
|
|
508
485
|
console.print("")
|
|
509
486
|
console.print("🚫 Error:")
|
|
@@ -511,98 +488,99 @@ def claude(dev_name: str, prompt: str, auth: bool, reset_workspace: bool, live:
|
|
|
511
488
|
sys.exit(1)
|
|
512
489
|
|
|
513
490
|
except (ContainerError, WorkspaceError) as e:
|
|
514
|
-
console.print(f"❌ Error executing
|
|
491
|
+
console.print(f"❌ Error executing {agent.display_name} in {dev_name}: {e}")
|
|
515
492
|
sys.exit(1)
|
|
516
493
|
|
|
517
494
|
|
|
495
|
+
def _add_agent_command(
|
|
496
|
+
name: str,
|
|
497
|
+
auth_help: str,
|
|
498
|
+
handle_auth: Callable[..., None],
|
|
499
|
+
auth_options: Sequence[Callable] = (),
|
|
500
|
+
auth_examples: Sequence[str] = (),
|
|
501
|
+
) -> None:
|
|
502
|
+
"""Register a `devs <agent> DEV_NAME PROMPT` command for an agent in devs_common.agents.
|
|
518
503
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
@cli.command()
|
|
527
|
-
@click.argument('dev_name', required=False)
|
|
528
|
-
@click.argument('prompt', required=False)
|
|
529
|
-
@click.option('--auth', is_flag=True, help='Set up Codex authentication for devcontainers')
|
|
530
|
-
@click.option('--api-key', help='OpenAI API key to authenticate with (use with --auth)')
|
|
531
|
-
@click.option('--reset-workspace', is_flag=True, help='Reset workspace contents before execution')
|
|
532
|
-
@click.option('--live', is_flag=True, help='Start container with current directory mounted as workspace')
|
|
533
|
-
@click.option('--env', multiple=True, help='Environment variables to pass to container (format: VAR=value)')
|
|
534
|
-
@debug_option
|
|
535
|
-
def codex(dev_name: str, prompt: str, auth: bool, api_key: str, reset_workspace: bool, live: bool, env: tuple, debug: bool) -> None:
|
|
536
|
-
"""Execute OpenAI Codex CLI in devcontainer or set up authentication.
|
|
537
|
-
|
|
538
|
-
DEV_NAME: Development environment name
|
|
539
|
-
PROMPT: Prompt to send to Codex
|
|
540
|
-
|
|
541
|
-
Example: devs codex sally "Summarize this codebase"
|
|
542
|
-
Example: devs codex sally "Fix the tests" --reset-workspace
|
|
543
|
-
Example: devs codex sally "Fix the tests" --live # Run with current directory
|
|
544
|
-
Example: devs codex sally "Start the server" --env QUART_PORT=5001
|
|
545
|
-
Example: devs codex --auth # Interactive authentication
|
|
546
|
-
Example: devs codex --auth --api-key <YOUR_KEY> # API key authentication
|
|
504
|
+
Args:
|
|
505
|
+
name: Agent name in the AGENTS registry
|
|
506
|
+
auth_help: Help text for the --auth flag
|
|
507
|
+
handle_auth: Called for `--auth` with debug= plus any auth_options values
|
|
508
|
+
auth_options: Extra click options that only apply to --auth (e.g. --api-key)
|
|
509
|
+
auth_examples: Extra `devs <agent> --auth ...` example lines for the help text
|
|
547
510
|
"""
|
|
548
|
-
|
|
549
|
-
if auth:
|
|
550
|
-
_handle_codex_auth(api_key=api_key, debug=debug)
|
|
551
|
-
return
|
|
552
|
-
|
|
553
|
-
# Validate required arguments for execution mode
|
|
554
|
-
if not dev_name or not prompt:
|
|
555
|
-
raise click.UsageError("DEV_NAME and PROMPT are required unless using --auth")
|
|
556
|
-
|
|
557
|
-
check_dependencies()
|
|
558
|
-
project = get_project()
|
|
559
|
-
|
|
560
|
-
# Load environment variables from DEVS.yml and merge with CLI --env flags
|
|
561
|
-
devs_env = DevsConfigLoader.load_env_vars(dev_name, project.info.name)
|
|
562
|
-
cli_env = parse_env_vars(env) if env else {}
|
|
563
|
-
extra_env = merge_env_vars(devs_env, cli_env) if devs_env or cli_env else None
|
|
564
|
-
|
|
565
|
-
if extra_env:
|
|
566
|
-
console.print(f"🔧 Environment variables: {', '.join(f'{k}={v}' for k, v in extra_env.items())}")
|
|
567
|
-
|
|
568
|
-
container_manager = ContainerManager(project, config)
|
|
569
|
-
workspace_manager = WorkspaceManager(project, config)
|
|
511
|
+
agent = get_agent(name)
|
|
570
512
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
if
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
513
|
+
def command(dev_name: str, prompt: str, auth: bool, reset_workspace: bool, live: bool,
|
|
514
|
+
env: tuple, debug: bool, **auth_values) -> None:
|
|
515
|
+
if auth:
|
|
516
|
+
handle_auth(debug=debug, **auth_values)
|
|
517
|
+
return
|
|
518
|
+
# Validate required arguments for execution mode
|
|
519
|
+
if not dev_name or not prompt:
|
|
520
|
+
raise click.UsageError("DEV_NAME and PROMPT are required unless using --auth")
|
|
521
|
+
_run_agent(agent, dev_name, prompt, reset_workspace, live, env, debug)
|
|
522
|
+
|
|
523
|
+
examples = [
|
|
524
|
+
f'devs {name} sally "Summarize this codebase"',
|
|
525
|
+
f'devs {name} sally "Fix the tests" --reset-workspace',
|
|
526
|
+
f'devs {name} sally "Fix the tests" --live # Run with current directory',
|
|
527
|
+
f'devs {name} sally "Start the server" --env QUART_PORT=5001',
|
|
528
|
+
f'devs {name} --auth',
|
|
529
|
+
*auth_examples,
|
|
530
|
+
]
|
|
531
|
+
command.__name__ = name
|
|
532
|
+
command.__doc__ = (
|
|
533
|
+
f"Execute {agent.description} in devcontainer or set up authentication.\n\n"
|
|
534
|
+
f"DEV_NAME: Development environment name\n\n"
|
|
535
|
+
f"PROMPT: Prompt to send to {agent.display_name}\n\n"
|
|
536
|
+
+ "\n\n".join(f"Example: {example}" for example in examples)
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
decorators = [
|
|
540
|
+
cli.command(name=name),
|
|
541
|
+
click.argument('dev_name', required=False),
|
|
542
|
+
click.argument('prompt', required=False),
|
|
543
|
+
click.option('--auth', is_flag=True, help=auth_help),
|
|
544
|
+
*auth_options,
|
|
545
|
+
click.option('--reset-workspace', is_flag=True, help='Reset workspace contents before execution'),
|
|
546
|
+
click.option('--live', is_flag=True, help='Start container with current directory mounted as workspace'),
|
|
547
|
+
click.option('--env', multiple=True, help='Environment variables to pass to container (format: VAR=value)'),
|
|
548
|
+
debug_option,
|
|
549
|
+
]
|
|
550
|
+
for decorator in reversed(decorators):
|
|
551
|
+
command = decorator(command)
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
def _show_claude_auth(debug: bool) -> None:
|
|
555
|
+
"""Explain how to give devcontainers a Claude token."""
|
|
556
|
+
console.print("🔐 Claude authentication for devcontainers")
|
|
557
|
+
console.print("")
|
|
558
|
+
console.print("1. Generate a token (on a machine with a browser):")
|
|
559
|
+
console.print(" [cyan]claude setup-token[/cyan]")
|
|
560
|
+
console.print("")
|
|
561
|
+
console.print("2. Add the token to your environment:")
|
|
562
|
+
console.print(" [cyan]export CLAUDE_CODE_OAUTH_TOKEN=<token>[/cyan]")
|
|
563
|
+
console.print("")
|
|
564
|
+
console.print(" Or add it to [cyan]~/.devs/envs/default/.env[/cyan]:")
|
|
565
|
+
console.print(" [dim]CLAUDE_CODE_OAUTH_TOKEN=<token>[/dim]")
|
|
566
|
+
console.print("")
|
|
567
|
+
console.print("The token will be automatically passed to all devcontainers.")
|
|
591
568
|
|
|
592
|
-
console.print("") # Add spacing after streamed output
|
|
593
|
-
if success:
|
|
594
|
-
console.print("✅ Codex execution completed")
|
|
595
|
-
else:
|
|
596
|
-
console.print("❌ Codex execution failed")
|
|
597
|
-
if error:
|
|
598
|
-
console.print("")
|
|
599
|
-
console.print("🚫 Error:")
|
|
600
|
-
console.print(error)
|
|
601
|
-
sys.exit(1)
|
|
602
569
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
570
|
+
def _show_hermes_auth(debug: bool) -> None:
|
|
571
|
+
"""Explain how to give devcontainers an OpenRouter key for Hermes."""
|
|
572
|
+
console.print("🔐 Hermes Agent authentication for devcontainers")
|
|
573
|
+
console.print("")
|
|
574
|
+
console.print("Hermes runs against OpenRouter. Create an API key at:")
|
|
575
|
+
console.print(" [cyan]https://openrouter.ai/keys[/cyan]")
|
|
576
|
+
console.print("")
|
|
577
|
+
console.print("Add it to [cyan]~/.devs/envs/default/.env[/cyan] (or a project-specific env dir):")
|
|
578
|
+
console.print(" [dim]OPENROUTER_API_KEY=<key>[/dim]")
|
|
579
|
+
console.print("")
|
|
580
|
+
console.print("The default model is [cyan]z-ai/glm-5.3[/cyan]. To use another OpenRouter model:")
|
|
581
|
+
console.print(" [dim]HERMES_INFERENCE_MODEL=<provider/model>[/dim]")
|
|
582
|
+
console.print("")
|
|
583
|
+
console.print("The env file is mounted into every devcontainer and loaded on each shell.")
|
|
606
584
|
|
|
607
585
|
|
|
608
586
|
def _handle_codex_auth(api_key: str, debug: bool) -> None:
|
|
@@ -619,54 +597,32 @@ def _handle_codex_auth(api_key: str, debug: bool) -> None:
|
|
|
619
597
|
console.print("🔐 Setting up Codex authentication...")
|
|
620
598
|
console.print(f" Configuration will be saved to: {config.codex_config_dir}")
|
|
621
599
|
|
|
600
|
+
# Codex reads its state directory from CODEX_HOME (default ~/.codex); pointing it
|
|
601
|
+
# at the directory that is bind-mounted into containers shares the login with them.
|
|
602
|
+
env = os.environ.copy()
|
|
603
|
+
env['CODEX_HOME'] = str(config.codex_config_dir)
|
|
604
|
+
|
|
622
605
|
if api_key:
|
|
623
|
-
# Set API key directly using Codex CLI
|
|
624
606
|
console.print(" Using provided API key...")
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
env = os.environ.copy()
|
|
628
|
-
env['CODEX_CONFIG_HOME'] = str(config.codex_config_dir)
|
|
629
|
-
|
|
630
|
-
cmd = ['codex', 'auth', '--api-key', api_key]
|
|
631
|
-
|
|
632
|
-
if debug:
|
|
633
|
-
console.print(f"[dim]Running: {' '.join(cmd)}[/dim]")
|
|
634
|
-
console.print(f"[dim]CODEX_CONFIG_HOME: {config.codex_config_dir}[/dim]")
|
|
635
|
-
|
|
636
|
-
result = subprocess.run(
|
|
637
|
-
cmd,
|
|
638
|
-
env=env,
|
|
639
|
-
capture_output=True,
|
|
640
|
-
text=True
|
|
641
|
-
)
|
|
642
|
-
|
|
643
|
-
if result.returncode != 0:
|
|
644
|
-
error_msg = result.stderr or result.stdout or "Unknown error"
|
|
645
|
-
raise Exception(f"Codex authentication failed: {error_msg}")
|
|
646
|
-
|
|
607
|
+
# The key goes in on stdin so it never shows up in the process list
|
|
608
|
+
cmd = ['codex', 'login', '--with-api-key']
|
|
647
609
|
else:
|
|
648
|
-
# Interactive authentication
|
|
649
610
|
console.print(" Starting interactive authentication...")
|
|
650
611
|
console.print(" Follow the prompts to authenticate with Codex")
|
|
651
612
|
console.print("")
|
|
613
|
+
cmd = ['codex', 'login']
|
|
652
614
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
cmd = ['codex', 'auth']
|
|
658
|
-
|
|
659
|
-
if debug:
|
|
660
|
-
console.print(f"[dim]Running: {' '.join(cmd)}[/dim]")
|
|
661
|
-
console.print(f"[dim]CODEX_CONFIG_HOME: {config.codex_config_dir}[/dim]")
|
|
662
|
-
|
|
663
|
-
# Run interactively
|
|
664
|
-
result = subprocess.run(
|
|
665
|
-
cmd,
|
|
666
|
-
env=env,
|
|
667
|
-
check=False
|
|
668
|
-
)
|
|
615
|
+
if debug:
|
|
616
|
+
console.print(f"[dim]Running: {' '.join(cmd)}[/dim]")
|
|
617
|
+
console.print(f"[dim]CODEX_HOME: {config.codex_config_dir}[/dim]")
|
|
669
618
|
|
|
619
|
+
if api_key:
|
|
620
|
+
result = subprocess.run(cmd, env=env, input=api_key, capture_output=True, text=True)
|
|
621
|
+
if result.returncode != 0:
|
|
622
|
+
error_msg = result.stderr or result.stdout or "Unknown error"
|
|
623
|
+
raise Exception(f"Codex authentication failed: {error_msg}")
|
|
624
|
+
else:
|
|
625
|
+
result = subprocess.run(cmd, env=env, check=False)
|
|
670
626
|
if result.returncode != 0:
|
|
671
627
|
raise Exception("Codex authentication was cancelled or failed")
|
|
672
628
|
|
|
@@ -695,6 +651,25 @@ def _handle_codex_auth(api_key: str, debug: bool) -> None:
|
|
|
695
651
|
sys.exit(1)
|
|
696
652
|
|
|
697
653
|
|
|
654
|
+
_add_agent_command(
|
|
655
|
+
"claude",
|
|
656
|
+
auth_help='Show Claude authentication setup instructions',
|
|
657
|
+
handle_auth=_show_claude_auth,
|
|
658
|
+
)
|
|
659
|
+
_add_agent_command(
|
|
660
|
+
"codex",
|
|
661
|
+
auth_help='Set up Codex authentication for devcontainers',
|
|
662
|
+
handle_auth=_handle_codex_auth,
|
|
663
|
+
auth_options=[click.option('--api-key', help='OpenAI API key to authenticate with (use with --auth)')],
|
|
664
|
+
auth_examples=['devs codex --auth --api-key <YOUR_KEY> # API key authentication'],
|
|
665
|
+
)
|
|
666
|
+
_add_agent_command(
|
|
667
|
+
"hermes",
|
|
668
|
+
auth_help='Show Hermes (OpenRouter) authentication setup instructions',
|
|
669
|
+
handle_auth=_show_hermes_auth,
|
|
670
|
+
)
|
|
671
|
+
|
|
672
|
+
|
|
698
673
|
@cli.command()
|
|
699
674
|
@click.argument('dev_name')
|
|
700
675
|
@click.option('--reset-workspace', is_flag=True, help='Reset workspace contents before execution')
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
devs/__init__.py,sha256=dMk0J_JrmBmknPvt6HNUa04qxgHYpxhnIXa3PZFk_N0,571
|
|
2
|
-
devs/cli.py,sha256=
|
|
2
|
+
devs/cli.py,sha256=zBnWCQeby2aCAIW96ilnI246gbN1DQlps7J9a14vJ7g,44360
|
|
3
3
|
devs/config.py,sha256=DaS2_1x0h63cHn34RmWbEhUx_1u3-sAo16tM3AXMKfQ,1561
|
|
4
4
|
devs/exceptions.py,sha256=7xO7ihJu_U6CupZPMv89B4N5EBSUcdj2OdA6GPAFPEE,490
|
|
5
5
|
devs/core/__init__.py,sha256=TPy3eZi-AEztci_QZ37YAAl2zvUQlwBALpyiQx2ED7Q,363
|
|
6
6
|
devs/core/integration.py,sha256=_zT5kJi_L34uU3yhLinLI7bbjI5Q27dX9ABxgwHkx2Y,16557
|
|
7
7
|
devs/utils/__init__.py,sha256=f-sEWETPfW2Xkaxgd-l6FS-jIQAorLlQZOicIZvp-W0,638
|
|
8
|
-
devs_cli-
|
|
9
|
-
devs_cli-
|
|
10
|
-
devs_cli-
|
|
11
|
-
devs_cli-
|
|
12
|
-
devs_cli-
|
|
13
|
-
devs_cli-
|
|
8
|
+
devs_cli-6.0.0.dist-info/licenses/LICENSE,sha256=bi2EUiv-lmC_quQVkNqzTYXJpjVarkPsVKfqhJl7ccQ,1067
|
|
9
|
+
devs_cli-6.0.0.dist-info/METADATA,sha256=Jy_OaQ3IuSWwwguszCd1OcWQOi5KLmeGrMWrsAJAS58,5282
|
|
10
|
+
devs_cli-6.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
11
|
+
devs_cli-6.0.0.dist-info/entry_points.txt,sha256=s8-pgqZ1QvzPJgHP9vNxwBYdezmGsFdRUHacJPZ4WOs,39
|
|
12
|
+
devs_cli-6.0.0.dist-info/top_level.txt,sha256=9RIVUPVGuOdO84qkBh_9XcKoTV7773o3py78wz2-IZk,5
|
|
13
|
+
devs_cli-6.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|