The CLI is the main entrypoint for end users and for the interactive bot menu.
openenv.cli¶
openenv.cli
¶
Command line interface for OpenClawenv.
build_parser()
¶
Create the CLI parser.
Source code in src/openenv/cli.py
def build_parser() -> argparse.ArgumentParser:
"""Create the CLI parser."""
parser = argparse.ArgumentParser(prog="clawopenenv", description="OpenClawenv CLI")
subparsers = parser.add_subparsers(dest="command", required=True)
init_parser = subparsers.add_parser("init", help=f"Create a starter {DEFAULT_MANIFEST_FILENAME}")
init_parser.add_argument("--path", default=DEFAULT_MANIFEST_FILENAME, help="Manifest output path")
init_parser.add_argument(
"--force",
action="store_true",
help="Overwrite an existing manifest file",
)
validate_parser = subparsers.add_parser("validate", help=f"Validate {DEFAULT_MANIFEST_FILENAME}")
validate_parser.add_argument("--path", default=DEFAULT_MANIFEST_FILENAME, help="Manifest path")
lock_parser = subparsers.add_parser("lock", help=f"Generate {DEFAULT_LOCKFILE_FILENAME}")
lock_parser.add_argument("--path", default=DEFAULT_MANIFEST_FILENAME, help="Manifest path")
lock_parser.add_argument("--output", default=DEFAULT_LOCKFILE_FILENAME, help="Lockfile output path")
scan_parser = subparsers.add_parser("scan", help="Run skill-scanner against inline skills")
scan_parser.add_argument("--path", default=DEFAULT_MANIFEST_FILENAME, help="Manifest path")
scan_parser.add_argument(
"--scanner-bin",
default="skill-scanner",
help="Path to the skill-scanner executable",
)
scan_parser.add_argument(
"--keep-artifacts",
action="store_true",
help=f"Keep the materialized skill directory in {DEFAULT_SCAN_ARTIFACTS_DIRNAME}",
)
scan_parser.add_argument(
"scanner_args",
nargs=argparse.REMAINDER,
help="Additional arguments passed to skill-scanner after --",
)
export_parser = subparsers.add_parser("export", help="Export generated artifacts")
export_subparsers = export_parser.add_subparsers(dest="export_command", required=True)
dockerfile_parser = export_subparsers.add_parser(
"dockerfile",
help="Render the deterministic Dockerfile",
)
dockerfile_parser.add_argument("--path", default=DEFAULT_MANIFEST_FILENAME, help="Manifest path")
dockerfile_parser.add_argument("--lock", default=DEFAULT_LOCKFILE_FILENAME, help="Lockfile path")
dockerfile_parser.add_argument("--output", help="Optional Dockerfile output path")
compose_parser = export_subparsers.add_parser(
"compose",
help="Render the docker-compose file for the bot image",
)
compose_parser.add_argument("--path", default=DEFAULT_MANIFEST_FILENAME, help="Manifest path")
compose_parser.add_argument("--lock", default=DEFAULT_LOCKFILE_FILENAME, help="Lockfile path")
compose_parser.add_argument("--tag", help="Docker image tag to reference")
compose_parser.add_argument("--output", help="Optional compose output path")
build_parser_cmd = subparsers.add_parser("build", help="Build the Docker image")
build_parser_cmd.add_argument("--path", default=DEFAULT_MANIFEST_FILENAME, help="Manifest path")
build_parser_cmd.add_argument("--lock", default=DEFAULT_LOCKFILE_FILENAME, help="Lockfile path")
build_parser_cmd.add_argument("--tag", help="Docker image tag")
build_parser_cmd.add_argument(
"--scan-format",
default=DEFAULT_SKILL_SCAN_FORMAT,
help="Build-time skill scan format passed to the Dockerfile",
)
build_parser_cmd.add_argument(
"--scan-policy",
default=DEFAULT_SKILL_SCAN_POLICY,
help="Build-time skill scan policy passed to the Dockerfile",
)
build_parser_cmd.add_argument(
"--scan-fail-on-severity",
default=DEFAULT_SKILL_SCAN_FAIL_ON_SEVERITY,
help="Build-time skill scan severity threshold passed to the Dockerfile",
)
return parser
main(argv=None)
¶
Program entry point.
Source code in src/openenv/cli.py
def main(argv: list[str] | None = None) -> int:
"""Program entry point."""
_configure_logging()
argv = sys.argv[1:] if argv is None else argv
if not argv:
return interactive_menu(Path.cwd())
parser = build_parser()
args = parser.parse_args(argv)
try:
if args.command == "init":
return _handle_init(args)
if args.command == "validate":
return _handle_validate(args)
if args.command == "lock":
return _handle_lock(args)
if args.command == "scan":
return _handle_scan(args)
if args.command == "export" and args.export_command == "dockerfile":
return _handle_export_dockerfile(args)
if args.command == "export" and args.export_command == "compose":
return _handle_export_compose(args)
if args.command == "build":
return _handle_build(args)
parser.error("unknown command")
except CommandError as exc:
logger.error("error: {}", exc)
return exc.exit_code or 1
except OpenEnvError as exc:
logger.error("error: {}", exc)
return 1
return 0