praisonai-code 0.0.39__tar.gz → 0.0.41__tar.gz
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.
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/PKG-INFO +5 -4
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/README.md +4 -3
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/__init__.py +1 -1
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/_wrapper_bridge.py +45 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/app.py +28 -1
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/agents.py +6 -36
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/auth.py +44 -7
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/call.py +2 -12
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/commit.py +2 -12
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/config.py +44 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/eval.py +10 -24
- praisonai_code-0.0.41/praisonai_code/cli/commands/hooks.py +44 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/memory.py +19 -48
- praisonai_code-0.0.41/praisonai_code/cli/commands/package.py +46 -0
- praisonai_code-0.0.41/praisonai_code/cli/commands/registry.py +54 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/research.py +2 -12
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/retrieval.py +20 -2
- praisonai_code-0.0.41/praisonai_code/cli/commands/rules.py +41 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/run.py +25 -6
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/skills.py +6 -36
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/templates.py +4 -24
- praisonai_code-0.0.41/praisonai_code/cli/commands/todo.py +44 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/workflow.py +6 -36
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/configuration/oauth.py +94 -6
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/configuration/resolver.py +107 -8
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/acp_checks.py +3 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/packaging_checks.py +56 -28
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/performance_checks.py +9 -0
- praisonai_code-0.0.41/praisonai_code/cli/features/registry.py +12 -0
- praisonai_code-0.0.41/praisonai_code/cli/help_categories.py +152 -0
- praisonai_code-0.0.41/praisonai_code/cli/utils/env_utils.py +221 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code.egg-info/PKG-INFO +5 -4
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code.egg-info/SOURCES.txt +2 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/pyproject.toml +1 -1
- praisonai_code-0.0.39/praisonai_code/cli/commands/hooks.py +0 -74
- praisonai_code-0.0.39/praisonai_code/cli/commands/package.py +0 -76
- praisonai_code-0.0.39/praisonai_code/cli/commands/registry.py +0 -59
- praisonai_code-0.0.39/praisonai_code/cli/commands/rules.py +0 -71
- praisonai_code-0.0.39/praisonai_code/cli/commands/todo.py +0 -74
- praisonai_code-0.0.39/praisonai_code/cli/utils/env_utils.py +0 -126
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/__main__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/_bot_bridge.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/_framework_availability.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/_logging.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/_registry.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/_safe_loader.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/_version.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/_forward_shim.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/_paths.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/_warnings.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/_wrapper_reexport.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/approval_backend.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/branding.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/acp.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/agent.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/attach.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/benchmark.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/browser.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/chat.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/checkpoint.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/code.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/command.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/completion.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/daemon.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/debug.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/deploy.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/diag.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/doctor.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/endpoints.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/environment.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/github.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/init.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/loop.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/lsp.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/models.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/obs.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/paths.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/permissions.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/plugins.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/port.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/publish.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/sandbox.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/serve.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/session.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/setup.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/test.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/tools.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/traces.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/tracker.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/ui.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/up.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/commands/version.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/config_loader.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/configuration/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/configuration/config.schema.json +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/configuration/credentials.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/configuration/loader.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/configuration/model_resolver.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/configuration/paths.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/configuration/schema.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/execution/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/execution/core.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/execution/profiler.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/execution/request.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/execution/result.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/fallback_schema.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/_approval_bridge.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/_endpoint_registry.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/_search_registry.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/action_orchestrator.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/agents.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/at_mentions.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/audit_cli.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/auto_memory.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/auto_mode.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/autonomy_mode.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/base.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/benchmark.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/capabilities.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/checkpoints.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/cli_profiler.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/code_intelligence.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/compaction.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/compare.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/config_hierarchy.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/context_manager.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/cost_tracker.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/csv_test_runner.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/custom_definitions.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/debug.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/diag.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/display_jsonl.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/_wrapper_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/bot_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/config_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/db_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/env_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/gateway_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/lsp_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/mcp_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/memory_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/network_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/obs_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/permissions_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/runtime_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/runtime_migration_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/selftest_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/serve_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/skills_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/checks/tools_checks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/engine.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/formatters.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/handler.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/models.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/doctor/registry.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/endpoints.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/examples.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/external_agents.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/fast_context.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/file_history.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/flow_display.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/git_attribution.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/git_integration.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/guardrail.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/handoff.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/hooks.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/hybrid_workflow.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/image.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/interactive_core_headless.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/interactive_runtime.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/interactive_test_harness.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/interactive_tools.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/interactive_tui.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/job_workflow.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/jobs.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/knowledge.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/knowledge_cli.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/lite.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/logs.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/lsp_cli.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/lsp_diagnostics.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/mcp.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/message_queue.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/metrics.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/migrate.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/migration_flow.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/migration_spec.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/n8n.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/observability.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/output_modes.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/output_style.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/package.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/performance.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/profiler/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/profiler/core.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/profiler/optimizations.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/profiler/suite.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/queue/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/queue/manager.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/queue/models.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/queue/persistence.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/queue/scheduler.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/queue/worker.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/recipe_creator.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/recipe_prompts.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/repo_map.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/router.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/safe_shell.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/sandbox_executor.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/sdk_knowledge.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/session.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/session_checkpoints.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/setup/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/setup/handler.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/setup/templates.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/skills.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/slash_commands.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/telemetry.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/thinking.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/todo.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tools.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/cli.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/config.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/debug.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/events.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/mock_provider.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/orchestrator.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/screens/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/screens/help.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/screens/main.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/screens/queue.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/screens/session.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/screens/settings.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/session_store.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/widgets/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/widgets/chat.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/widgets/command_popup.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/widgets/composer.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/widgets/file_popup.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/widgets/queue_panel.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/widgets/status.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/tui/widgets/tool_panel.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/wizard.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/workflow.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/features/yaml_utils.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/async_tui.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/command_registry.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/config.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/core.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/events.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/frontends/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/frontends/rich_frontend.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/frontends/textual_frontend.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/praison_io.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/repl.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/split_tui.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/interactive/tui_app.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/legacy/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/legacy/env_security.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/legacy/praison_ai.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/legacy/prompt_dispatch.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/main.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/output/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/output/console.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/output/event_bridge.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/schedule_cli.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/schema_provider.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/session/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/session/resume.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/session/unified.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/state/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/state/identifiers.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/state/project_sessions.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/state/sessions.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/ui/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/ui/config.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/ui/events.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/ui/mg_backend.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/ui/plain.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/ui/rich_backend.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/unified_schema.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/utils/project.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli/utils/stdin.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli_backends/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli_backends/claude.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/cli_backends/registry.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/llm/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/llm/catalogue.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/llm/config.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/llm/credentials.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/llm/env.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/runtime/__init__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/runtime/__main__.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/runtime/client.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/runtime/descriptor.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/runtime/server.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/tool_registry.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code/tool_resolver.py +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code.egg-info/dependency_links.txt +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code.egg-info/entry_points.txt +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code.egg-info/requires.txt +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/praisonai_code.egg-info/top_level.txt +0 -0
- {praisonai_code-0.0.39 → praisonai_code-0.0.41}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: praisonai-code
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.41
|
|
4
4
|
Summary: Agentic terminal CLI for PraisonAI — the terminal-native agent (run, chat, code, runtime, cli backends) extracted from the praisonai wrapper.
|
|
5
5
|
Author: Mervin Praison
|
|
6
6
|
License: MIT
|
|
@@ -80,9 +80,10 @@ importing the wrapper. Only commands in `_WRAPPER_RESIDENT_COMMANDS` (see
|
|
|
80
80
|
|---------|-------------------|-------|
|
|
81
81
|
| `praisonai-code --version` | Yes | |
|
|
82
82
|
| `run --help`, `config`, `doctor` | Yes | |
|
|
83
|
-
| `run --output
|
|
84
|
-
| `run "…"`
|
|
85
|
-
| `run
|
|
83
|
+
| `run --output actions "…"` | Yes | In-process `Agent` (structured events). `run` modes: `silent` (default), `plain`, `actions`, `verbose`, `json`, `stream`, `stream-json` |
|
|
84
|
+
| `run --output json/stream/stream-json "…"` | Yes | In-process `Agent` (structured output) |
|
|
85
|
+
| `run "…"` (default) | Needs `praisonai` | Human-readable text run delegates to the wrapper's `handle_direct_prompt`; standalone gates with an install hint pointing to `--output actions` |
|
|
86
|
+
| `run --output plain/verbose/silent "…"` | Needs `praisonai` | Same text path as default; standalone gates with an install hint |
|
|
86
87
|
| `chat --output plain "…"` | Yes | One-shot; interactive REPL also in code package. `chat` modes: `actions` (default), `plain`, `verbose`, `json`, `silent` |
|
|
87
88
|
| `code --help` | Yes | Full code assistant command registered |
|
|
88
89
|
| `daemon start` (foreground) | Yes | |
|
|
@@ -58,9 +58,10 @@ importing the wrapper. Only commands in `_WRAPPER_RESIDENT_COMMANDS` (see
|
|
|
58
58
|
|---------|-------------------|-------|
|
|
59
59
|
| `praisonai-code --version` | Yes | |
|
|
60
60
|
| `run --help`, `config`, `doctor` | Yes | |
|
|
61
|
-
| `run --output
|
|
62
|
-
| `run "…"`
|
|
63
|
-
| `run
|
|
61
|
+
| `run --output actions "…"` | Yes | In-process `Agent` (structured events). `run` modes: `silent` (default), `plain`, `actions`, `verbose`, `json`, `stream`, `stream-json` |
|
|
62
|
+
| `run --output json/stream/stream-json "…"` | Yes | In-process `Agent` (structured output) |
|
|
63
|
+
| `run "…"` (default) | Needs `praisonai` | Human-readable text run delegates to the wrapper's `handle_direct_prompt`; standalone gates with an install hint pointing to `--output actions` |
|
|
64
|
+
| `run --output plain/verbose/silent "…"` | Needs `praisonai` | Same text path as default; standalone gates with an install hint |
|
|
64
65
|
| `chat --output plain "…"` | Yes | One-shot; interactive REPL also in code package. `chat` modes: `actions` (default), `plain`, `verbose`, `json`, `silent` |
|
|
65
66
|
| `code --help` | Yes | Full code assistant command registered |
|
|
66
67
|
| `daemon start` (foreground) | Yes | |
|
|
@@ -51,3 +51,48 @@ def optional_wrapper_attr(module_name: str, attr: str, default: T | None = None)
|
|
|
51
51
|
return get_wrapper_attr(module_name, attr)
|
|
52
52
|
except (ImportError, AttributeError):
|
|
53
53
|
return default
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def run_wrapper_command(argv: list[str], *, feature: str) -> None:
|
|
57
|
+
"""Re-enter the legacy ``PraisonAI().main()`` for a wrapper-resident command.
|
|
58
|
+
|
|
59
|
+
Typer stub commands (``agents``, ``workflow``, ``registry`` and peers) still
|
|
60
|
+
dispatch to the legacy CLI by mutating ``sys.argv`` and calling
|
|
61
|
+
``PraisonAI().main()``. On a standalone ``pip install praisonai-code`` the
|
|
62
|
+
legacy path imports ``praisonai.cli.legacy.dispatch.argparse_builder`` which
|
|
63
|
+
is wrapper-only, so it raises a Rich ``ImportError`` traceback before any
|
|
64
|
+
feature handler runs (issue #2837).
|
|
65
|
+
|
|
66
|
+
This helper guards that re-entry: when the ``praisonai`` wrapper is not
|
|
67
|
+
installed it fails fast with a single-line install hint (exit code 1) instead
|
|
68
|
+
of a traceback. When the wrapper is present it performs the ``sys.argv``
|
|
69
|
+
mutation + ``main()`` call exactly as before, restoring ``sys.argv`` after.
|
|
70
|
+
A clean ``SystemExit`` (code ``0``/``None``) is swallowed so the calling
|
|
71
|
+
Typer command returns normally, while any non-zero exit code is re-raised so
|
|
72
|
+
the shell sees the wrapper's failure.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
argv: Legacy argv tokens (e.g. ``["agents", "list"]``) without the
|
|
76
|
+
leading program name.
|
|
77
|
+
feature: Command group name used in the standalone hint message.
|
|
78
|
+
"""
|
|
79
|
+
import sys
|
|
80
|
+
|
|
81
|
+
if not wrapper_available():
|
|
82
|
+
print(
|
|
83
|
+
f"{feature} requires the full wrapper. {_INSTALL_HINT}",
|
|
84
|
+
file=sys.stderr,
|
|
85
|
+
)
|
|
86
|
+
raise SystemExit(1)
|
|
87
|
+
|
|
88
|
+
from praisonai_code.cli.main import PraisonAI
|
|
89
|
+
|
|
90
|
+
original_argv = sys.argv
|
|
91
|
+
sys.argv = ["praisonai"] + argv
|
|
92
|
+
try:
|
|
93
|
+
PraisonAI().main()
|
|
94
|
+
except SystemExit as exc:
|
|
95
|
+
if exc.code:
|
|
96
|
+
raise
|
|
97
|
+
finally:
|
|
98
|
+
sys.argv = original_argv
|
|
@@ -15,6 +15,7 @@ from typer.main import get_command as typer_get_command
|
|
|
15
15
|
|
|
16
16
|
from .output.console import OutputController, OutputMode, set_output_controller
|
|
17
17
|
from .state.identifiers import create_context
|
|
18
|
+
from .help_categories import category_for
|
|
18
19
|
|
|
19
20
|
# Single source of truth for the terminal fallback model; entry points route
|
|
20
21
|
# through resolve_default_model() and never re-declare this literal.
|
|
@@ -116,6 +117,20 @@ def _setup_langextract_observability(*, verbose: bool = False) -> None:
|
|
|
116
117
|
typer.echo(f"Warning: failed to initialize langextract observability: {e}", err=True)
|
|
117
118
|
|
|
118
119
|
|
|
120
|
+
def _help_panel_unset(command: click.Command) -> bool:
|
|
121
|
+
"""Return True when ``command`` has no explicit ``rich_help_panel``.
|
|
122
|
+
|
|
123
|
+
Typer leaves the attribute as a ``DefaultPlaceholder`` (not ``None``) for
|
|
124
|
+
commands that don't set one, so both cases must be treated as "unset" before
|
|
125
|
+
we assign a category.
|
|
126
|
+
"""
|
|
127
|
+
panel = getattr(command, "rich_help_panel", None)
|
|
128
|
+
if panel is None:
|
|
129
|
+
return True
|
|
130
|
+
# ``DefaultPlaceholder`` is Typer's sentinel for "value not provided".
|
|
131
|
+
return type(panel).__name__ == "DefaultPlaceholder"
|
|
132
|
+
|
|
133
|
+
|
|
119
134
|
class OutputFormat(str, Enum):
|
|
120
135
|
"""Output format options."""
|
|
121
136
|
text = "text"
|
|
@@ -320,7 +335,19 @@ class LazyCommandGroup(TyperGroup):
|
|
|
320
335
|
return sorted(list(commands))
|
|
321
336
|
|
|
322
337
|
def get_command(self, ctx: click.Context, name: str) -> Optional[click.Command]:
|
|
323
|
-
"""Lazily import and return the command."""
|
|
338
|
+
"""Lazily import and return the command, tagged with its help category."""
|
|
339
|
+
command = self._resolve_command(ctx, name)
|
|
340
|
+
if command is not None and _help_panel_unset(command):
|
|
341
|
+
# Group the command into a categorised ``--help`` panel. This is the
|
|
342
|
+
# single hook Typer's rich renderer reads; setting it lazily here keeps
|
|
343
|
+
# the registry the source of truth without importing every command up
|
|
344
|
+
# front just to categorise it. Commands that explicitly declare their
|
|
345
|
+
# own ``rich_help_panel`` keep it.
|
|
346
|
+
command.rich_help_panel = category_for(name)
|
|
347
|
+
return command
|
|
348
|
+
|
|
349
|
+
def _resolve_command(self, ctx: click.Context, name: str) -> Optional[click.Command]:
|
|
350
|
+
"""Lazily import and return the command (without category tagging)."""
|
|
324
351
|
# First check if command is already registered (e.g., retrieval commands)
|
|
325
352
|
existing = super().get_command(ctx, name)
|
|
326
353
|
if existing is not None:
|
|
@@ -14,23 +14,13 @@ def agents_list(
|
|
|
14
14
|
verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed info"),
|
|
15
15
|
):
|
|
16
16
|
"""List available agents."""
|
|
17
|
-
from praisonai_code.
|
|
18
|
-
import sys
|
|
17
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
19
18
|
|
|
20
19
|
argv = ['agents', 'list']
|
|
21
20
|
if verbose:
|
|
22
21
|
argv.append('--verbose')
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
sys.argv = ['praisonai'] + argv
|
|
26
|
-
|
|
27
|
-
try:
|
|
28
|
-
praison = PraisonAI()
|
|
29
|
-
praison.main()
|
|
30
|
-
except SystemExit:
|
|
31
|
-
pass
|
|
32
|
-
finally:
|
|
33
|
-
sys.argv = original_argv
|
|
23
|
+
run_wrapper_command(argv, feature="agents")
|
|
34
24
|
|
|
35
25
|
|
|
36
26
|
@app.command("create")
|
|
@@ -39,23 +29,13 @@ def agents_create(
|
|
|
39
29
|
template: str = typer.Option(None, "--template", "-t", help="Template to use"),
|
|
40
30
|
):
|
|
41
31
|
"""Create a new agent."""
|
|
42
|
-
from praisonai_code.
|
|
43
|
-
import sys
|
|
32
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
44
33
|
|
|
45
34
|
argv = ['agents', 'create', name]
|
|
46
35
|
if template:
|
|
47
36
|
argv.extend(['--template', template])
|
|
48
37
|
|
|
49
|
-
|
|
50
|
-
sys.argv = ['praisonai'] + argv
|
|
51
|
-
|
|
52
|
-
try:
|
|
53
|
-
praison = PraisonAI()
|
|
54
|
-
praison.main()
|
|
55
|
-
except SystemExit:
|
|
56
|
-
pass
|
|
57
|
-
finally:
|
|
58
|
-
sys.argv = original_argv
|
|
38
|
+
run_wrapper_command(argv, feature="agents")
|
|
59
39
|
|
|
60
40
|
|
|
61
41
|
@app.command("info")
|
|
@@ -63,18 +43,8 @@ def agents_info(
|
|
|
63
43
|
name: str = typer.Argument(..., help="Agent name"),
|
|
64
44
|
):
|
|
65
45
|
"""Show agent information."""
|
|
66
|
-
from praisonai_code.
|
|
67
|
-
import sys
|
|
46
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
68
47
|
|
|
69
48
|
argv = ['agents', 'info', name]
|
|
70
49
|
|
|
71
|
-
|
|
72
|
-
sys.argv = ['praisonai'] + argv
|
|
73
|
-
|
|
74
|
-
try:
|
|
75
|
-
praison = PraisonAI()
|
|
76
|
-
praison.main()
|
|
77
|
-
except SystemExit:
|
|
78
|
-
pass
|
|
79
|
-
finally:
|
|
80
|
-
sys.argv = original_argv
|
|
50
|
+
run_wrapper_command(argv, feature="agents")
|
|
@@ -80,7 +80,14 @@ def _validate_with_live_call(provider: str, api_key: str, base_url: Optional[str
|
|
|
80
80
|
return False, f"API key invalid: {str(e)}"
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
def _run_oauth_login(
|
|
83
|
+
def _run_oauth_login(
|
|
84
|
+
provider: str,
|
|
85
|
+
output,
|
|
86
|
+
base_url,
|
|
87
|
+
model,
|
|
88
|
+
no_browser: bool,
|
|
89
|
+
overrides: Optional[dict] = None,
|
|
90
|
+
) -> None:
|
|
84
91
|
"""Run the browser/device-code OAuth flow and store the resulting tokens."""
|
|
85
92
|
from ..configuration.oauth import run_oauth_login
|
|
86
93
|
|
|
@@ -95,6 +102,7 @@ def _run_oauth_login(provider: str, output, base_url, model, no_browser: bool) -
|
|
|
95
102
|
try:
|
|
96
103
|
config, tokens = run_oauth_login(
|
|
97
104
|
provider,
|
|
105
|
+
overrides=overrides,
|
|
98
106
|
open_browser=not no_browser,
|
|
99
107
|
on_prompt=_on_prompt,
|
|
100
108
|
)
|
|
@@ -148,6 +156,11 @@ def auth_login(
|
|
|
148
156
|
model: Optional[str] = typer.Option(None, "--model", help="Default model for this provider"),
|
|
149
157
|
skip_validation: bool = typer.Option(False, "--skip-validation", help="Skip API key validation"),
|
|
150
158
|
no_browser: bool = typer.Option(False, "--no-browser", help="Do not auto-open the browser for OAuth"),
|
|
159
|
+
client_id: Optional[str] = typer.Option(None, "--client-id", help="OAuth client id (overrides the built-in provider entry)"),
|
|
160
|
+
token_url: Optional[str] = typer.Option(None, "--token-url", help="OAuth token endpoint (for providers not in the built-in registry)"),
|
|
161
|
+
device_authorization_url: Optional[str] = typer.Option(None, "--device-authorization-url", help="OAuth device-code endpoint (RFC 8628)"),
|
|
162
|
+
authorization_url: Optional[str] = typer.Option(None, "--authorization-url", help="OAuth authorization endpoint (RFC 7636 PKCE)"),
|
|
163
|
+
scope: Optional[str] = typer.Option(None, "--scope", help="OAuth scope(s) to request"),
|
|
151
164
|
):
|
|
152
165
|
"""
|
|
153
166
|
Store API credentials for a provider.
|
|
@@ -156,10 +169,22 @@ def auth_login(
|
|
|
156
169
|
praisonai auth login openai
|
|
157
170
|
praisonai auth login openai --key sk-...
|
|
158
171
|
echo "sk-..." | praisonai auth login openai --key-stdin
|
|
159
|
-
praisonai auth login
|
|
172
|
+
praisonai auth login github --method oauth --client-id <app-id>
|
|
160
173
|
"""
|
|
161
174
|
output = get_output_controller()
|
|
162
175
|
|
|
176
|
+
# Assemble any OAuth endpoint overrides supplied on the command line. These
|
|
177
|
+
# let users sign in to a built-in provider that needs an app client id, or
|
|
178
|
+
# to a provider not in the registry (e.g. a self-hosted gateway).
|
|
179
|
+
oauth_overrides = {
|
|
180
|
+
"client_id": client_id,
|
|
181
|
+
"token_url": token_url,
|
|
182
|
+
"device_authorization_url": device_authorization_url,
|
|
183
|
+
"authorization_url": authorization_url,
|
|
184
|
+
"scope": scope,
|
|
185
|
+
}
|
|
186
|
+
oauth_overrides = {k: v for k, v in oauth_overrides.items() if v is not None}
|
|
187
|
+
|
|
163
188
|
# Decide between OAuth and API-key login. ``auto`` selects OAuth only when
|
|
164
189
|
# the provider has an OAuth config AND no key was supplied; otherwise it
|
|
165
190
|
# falls back to the API-key path (unchanged behaviour).
|
|
@@ -168,14 +193,26 @@ def auth_login(
|
|
|
168
193
|
output.print_error("Invalid auth method. Use: auto, apikey, or oauth")
|
|
169
194
|
raise typer.Exit(1)
|
|
170
195
|
if method == "oauth":
|
|
171
|
-
_run_oauth_login(provider, output, base_url, model, no_browser)
|
|
196
|
+
_run_oauth_login(provider, output, base_url, model, no_browser, oauth_overrides)
|
|
172
197
|
return
|
|
173
198
|
if method == "auto" and not key and not key_stdin:
|
|
174
199
|
try:
|
|
175
|
-
from ..configuration.oauth import provider_supports_oauth
|
|
176
|
-
if provider_supports_oauth(provider):
|
|
177
|
-
|
|
178
|
-
|
|
200
|
+
from ..configuration.oauth import provider_supports_oauth, provider_requires_client_id
|
|
201
|
+
if provider_supports_oauth(provider, oauth_overrides):
|
|
202
|
+
# Don't silently start an OAuth flow that will immediately fail
|
|
203
|
+
# for lack of a client id; fall through to API-key login unless
|
|
204
|
+
# the user explicitly supplied one.
|
|
205
|
+
if not provider_requires_client_id(provider, oauth_overrides):
|
|
206
|
+
_run_oauth_login(provider, output, base_url, model, no_browser, oauth_overrides)
|
|
207
|
+
return
|
|
208
|
+
# Known OAuth provider but no client id yet: surface the OAuth
|
|
209
|
+
# path so the user isn't left wondering why they're being asked
|
|
210
|
+
# for an API key, then continue to the API-key fallback below.
|
|
211
|
+
output.print_info(
|
|
212
|
+
f"{provider} supports OAuth sign-in. To use it, re-run with: "
|
|
213
|
+
f"praisonai auth login {provider} --method oauth "
|
|
214
|
+
f"--client-id <your-oauth-app-client-id>"
|
|
215
|
+
)
|
|
179
216
|
except Exception:
|
|
180
217
|
# Fall through to API-key login on any OAuth detection error.
|
|
181
218
|
pass
|
|
@@ -24,8 +24,7 @@ def call_main(
|
|
|
24
24
|
praisonai call
|
|
25
25
|
praisonai call --model gpt-4o
|
|
26
26
|
"""
|
|
27
|
-
from praisonai_code.
|
|
28
|
-
import sys
|
|
27
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
29
28
|
|
|
30
29
|
argv = ['call']
|
|
31
30
|
if model:
|
|
@@ -33,13 +32,4 @@ def call_main(
|
|
|
33
32
|
if verbose:
|
|
34
33
|
argv.append('--verbose')
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
sys.argv = ['praisonai'] + argv
|
|
38
|
-
|
|
39
|
-
try:
|
|
40
|
-
praison = PraisonAI()
|
|
41
|
-
praison.main()
|
|
42
|
-
except SystemExit:
|
|
43
|
-
pass
|
|
44
|
-
finally:
|
|
45
|
-
sys.argv = original_argv
|
|
35
|
+
run_wrapper_command(argv, feature="call")
|
|
@@ -24,8 +24,7 @@ def commit_main(
|
|
|
24
24
|
praisonai commit -m "Fix bug"
|
|
25
25
|
praisonai commit --all --push
|
|
26
26
|
"""
|
|
27
|
-
from praisonai_code.
|
|
28
|
-
import sys
|
|
27
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
29
28
|
|
|
30
29
|
argv = ['commit']
|
|
31
30
|
if message:
|
|
@@ -35,13 +34,4 @@ def commit_main(
|
|
|
35
34
|
if push:
|
|
36
35
|
argv.append('--push')
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
sys.argv = ['praisonai'] + argv
|
|
40
|
-
|
|
41
|
-
try:
|
|
42
|
-
praison = PraisonAI()
|
|
43
|
-
praison.main()
|
|
44
|
-
except SystemExit:
|
|
45
|
-
pass
|
|
46
|
-
finally:
|
|
47
|
-
sys.argv = original_argv
|
|
37
|
+
run_wrapper_command(argv, feature="commit")
|
|
@@ -632,6 +632,50 @@ def config_validate(
|
|
|
632
632
|
raise typer.Exit(1) from e
|
|
633
633
|
|
|
634
634
|
|
|
635
|
+
@app.command("provenance")
|
|
636
|
+
def config_provenance(
|
|
637
|
+
key: Optional[str] = typer.Argument(
|
|
638
|
+
None,
|
|
639
|
+
help="Optional dotted key to inspect (e.g. agent.model). Omit for all keys.",
|
|
640
|
+
),
|
|
641
|
+
):
|
|
642
|
+
"""Show the resolved value of each key and which file/layer supplied it."""
|
|
643
|
+
output = get_output_controller()
|
|
644
|
+
|
|
645
|
+
try:
|
|
646
|
+
resolver = get_resolver()
|
|
647
|
+
provenance = resolver.resolve_with_provenance()
|
|
648
|
+
|
|
649
|
+
if key:
|
|
650
|
+
entry = provenance.get(key)
|
|
651
|
+
if entry is None:
|
|
652
|
+
output.print_error(f"Key not found: {key}")
|
|
653
|
+
raise typer.Exit(1)
|
|
654
|
+
if output.is_json_mode:
|
|
655
|
+
output.print_json({"key": key, **entry})
|
|
656
|
+
else:
|
|
657
|
+
source = entry["source"] or "(runtime)"
|
|
658
|
+
output.print(f"{key} = {entry['value']}")
|
|
659
|
+
output.print(f" [dim]layer:[/dim] {entry['layer']} [dim]source:[/dim] {source}")
|
|
660
|
+
return
|
|
661
|
+
|
|
662
|
+
if output.is_json_mode:
|
|
663
|
+
output.print_json(provenance)
|
|
664
|
+
return
|
|
665
|
+
|
|
666
|
+
output.print("[bold]Resolved configuration (per-key provenance):[/bold]\n")
|
|
667
|
+
for dotted in sorted(provenance):
|
|
668
|
+
entry = provenance[dotted]
|
|
669
|
+
source = entry["source"] or f"({entry['layer']})"
|
|
670
|
+
output.print(f" {dotted} = {entry['value']}")
|
|
671
|
+
output.print(f" [dim]{entry['layer']} · {source}[/dim]")
|
|
672
|
+
except typer.Exit:
|
|
673
|
+
raise
|
|
674
|
+
except Exception as e:
|
|
675
|
+
output.print_error(f"Failed to resolve provenance: {e}")
|
|
676
|
+
raise typer.Exit(1) from e
|
|
677
|
+
|
|
678
|
+
|
|
635
679
|
@app.command("sources")
|
|
636
680
|
def config_sources():
|
|
637
681
|
"""List all configuration sources in precedence order."""
|
|
@@ -17,21 +17,11 @@ def eval_accuracy(
|
|
|
17
17
|
iterations: int = typer.Option(3, "--iterations", "-n", help="Number of iterations"),
|
|
18
18
|
):
|
|
19
19
|
"""Run accuracy evaluation."""
|
|
20
|
-
from praisonai_code.
|
|
21
|
-
import sys
|
|
20
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
22
21
|
|
|
23
22
|
argv = ['eval', 'accuracy', agent, '--input', input_text, '--expected', expected]
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
sys.argv = ['praisonai'] + argv
|
|
27
|
-
|
|
28
|
-
try:
|
|
29
|
-
praison = PraisonAI()
|
|
30
|
-
praison.main()
|
|
31
|
-
except SystemExit:
|
|
32
|
-
pass
|
|
33
|
-
finally:
|
|
34
|
-
sys.argv = original_argv
|
|
24
|
+
run_wrapper_command(argv, feature="eval")
|
|
35
25
|
|
|
36
26
|
|
|
37
27
|
@app.command("performance")
|
|
@@ -40,21 +30,11 @@ def eval_performance(
|
|
|
40
30
|
iterations: int = typer.Option(50, "--iterations", "-n", help="Number of iterations"),
|
|
41
31
|
):
|
|
42
32
|
"""Run performance evaluation."""
|
|
43
|
-
from praisonai_code.
|
|
44
|
-
import sys
|
|
33
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
45
34
|
|
|
46
35
|
argv = ['eval', 'performance', agent, '--iterations', str(iterations)]
|
|
47
36
|
|
|
48
|
-
|
|
49
|
-
sys.argv = ['praisonai'] + argv
|
|
50
|
-
|
|
51
|
-
try:
|
|
52
|
-
praison = PraisonAI()
|
|
53
|
-
praison.main()
|
|
54
|
-
except SystemExit:
|
|
55
|
-
pass
|
|
56
|
-
finally:
|
|
57
|
-
sys.argv = original_argv
|
|
37
|
+
run_wrapper_command(argv, feature="eval")
|
|
58
38
|
|
|
59
39
|
|
|
60
40
|
@app.command("judge")
|
|
@@ -129,3 +109,9 @@ def list_judges_cmd():
|
|
|
129
109
|
typer.echo("Registered Judge Types:")
|
|
130
110
|
for name in judges:
|
|
131
111
|
typer.echo(f" - {name}")
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@app.command("list")
|
|
115
|
+
def eval_list():
|
|
116
|
+
"""List registered judge types (alias for list-judges)."""
|
|
117
|
+
list_judges_cmd()
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hooks command group for PraisonAI CLI.
|
|
3
|
+
|
|
4
|
+
Provides hook management commands.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="Hook management")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.command("list")
|
|
13
|
+
def hooks_list():
|
|
14
|
+
"""List available hooks."""
|
|
15
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
16
|
+
|
|
17
|
+
argv = ['hooks', 'list']
|
|
18
|
+
|
|
19
|
+
run_wrapper_command(argv, feature="hooks")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@app.command("add")
|
|
23
|
+
def hooks_add(
|
|
24
|
+
name: str = typer.Argument(..., help="Hook name"),
|
|
25
|
+
event: str = typer.Option(..., "--event", "-e", help="Event to hook into"),
|
|
26
|
+
):
|
|
27
|
+
"""Add a hook."""
|
|
28
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
29
|
+
|
|
30
|
+
argv = ['hooks', 'add', name, '--event', event]
|
|
31
|
+
|
|
32
|
+
run_wrapper_command(argv, feature="hooks")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@app.command("remove")
|
|
36
|
+
def hooks_remove(
|
|
37
|
+
name: str = typer.Argument(..., help="Hook name to remove"),
|
|
38
|
+
):
|
|
39
|
+
"""Remove a hook."""
|
|
40
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
41
|
+
|
|
42
|
+
argv = ['hooks', 'remove', name]
|
|
43
|
+
|
|
44
|
+
run_wrapper_command(argv, feature="hooks")
|
|
@@ -15,23 +15,24 @@ def memory_show(
|
|
|
15
15
|
limit: int = typer.Option(10, "--limit", "-l", help="Number of memories to show"),
|
|
16
16
|
):
|
|
17
17
|
"""Show stored memories."""
|
|
18
|
-
from praisonai_code.
|
|
19
|
-
import sys
|
|
18
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
20
19
|
|
|
21
20
|
argv = ['memory', 'show']
|
|
22
21
|
if user_id:
|
|
23
22
|
argv.extend(['--user-id', user_id])
|
|
23
|
+
if limit is not None:
|
|
24
|
+
argv.extend(['--limit', str(limit)])
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
run_wrapper_command(argv, feature="memory")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@app.command("list")
|
|
30
|
+
def memory_list(
|
|
31
|
+
user_id: str = typer.Option(None, "--user-id", help="User ID for memory isolation"),
|
|
32
|
+
limit: int = typer.Option(10, "--limit", "-l", help="Number of memories to show"),
|
|
33
|
+
):
|
|
34
|
+
"""List stored memories (alias for 'show')."""
|
|
35
|
+
memory_show(user_id=user_id, limit=limit)
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
@app.command("add")
|
|
@@ -40,23 +41,13 @@ def memory_add(
|
|
|
40
41
|
user_id: str = typer.Option(None, "--user-id", help="User ID for memory isolation"),
|
|
41
42
|
):
|
|
42
43
|
"""Add a memory."""
|
|
43
|
-
from praisonai_code.
|
|
44
|
-
import sys
|
|
44
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
45
45
|
|
|
46
46
|
argv = ['memory', 'add', content]
|
|
47
47
|
if user_id:
|
|
48
48
|
argv.extend(['--user-id', user_id])
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
sys.argv = ['praisonai'] + argv
|
|
52
|
-
|
|
53
|
-
try:
|
|
54
|
-
praison = PraisonAI()
|
|
55
|
-
praison.main()
|
|
56
|
-
except SystemExit:
|
|
57
|
-
pass
|
|
58
|
-
finally:
|
|
59
|
-
sys.argv = original_argv
|
|
50
|
+
run_wrapper_command(argv, feature="memory")
|
|
60
51
|
|
|
61
52
|
|
|
62
53
|
@app.command("search")
|
|
@@ -65,23 +56,13 @@ def memory_search(
|
|
|
65
56
|
user_id: str = typer.Option(None, "--user-id", help="User ID for memory isolation"),
|
|
66
57
|
):
|
|
67
58
|
"""Search memories."""
|
|
68
|
-
from praisonai_code.
|
|
69
|
-
import sys
|
|
59
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
70
60
|
|
|
71
61
|
argv = ['memory', 'search', query]
|
|
72
62
|
if user_id:
|
|
73
63
|
argv.extend(['--user-id', user_id])
|
|
74
64
|
|
|
75
|
-
|
|
76
|
-
sys.argv = ['praisonai'] + argv
|
|
77
|
-
|
|
78
|
-
try:
|
|
79
|
-
praison = PraisonAI()
|
|
80
|
-
praison.main()
|
|
81
|
-
except SystemExit:
|
|
82
|
-
pass
|
|
83
|
-
finally:
|
|
84
|
-
sys.argv = original_argv
|
|
65
|
+
run_wrapper_command(argv, feature="memory")
|
|
85
66
|
|
|
86
67
|
|
|
87
68
|
@app.command("clear")
|
|
@@ -90,23 +71,13 @@ def memory_clear(
|
|
|
90
71
|
force: bool = typer.Option(False, "--force", "-f", help="Force clear without confirmation"),
|
|
91
72
|
):
|
|
92
73
|
"""Clear all memories."""
|
|
93
|
-
from praisonai_code.
|
|
94
|
-
import sys
|
|
74
|
+
from praisonai_code._wrapper_bridge import run_wrapper_command
|
|
95
75
|
|
|
96
76
|
argv = ['memory', 'clear']
|
|
97
77
|
if user_id:
|
|
98
78
|
argv.extend(['--user-id', user_id])
|
|
99
79
|
|
|
100
|
-
|
|
101
|
-
sys.argv = ['praisonai'] + argv
|
|
102
|
-
|
|
103
|
-
try:
|
|
104
|
-
praison = PraisonAI()
|
|
105
|
-
praison.main()
|
|
106
|
-
except SystemExit:
|
|
107
|
-
pass
|
|
108
|
-
finally:
|
|
109
|
-
sys.argv = original_argv
|
|
80
|
+
run_wrapper_command(argv, feature="memory")
|
|
110
81
|
|
|
111
82
|
|
|
112
83
|
# Learn subcommand group
|