praisonai-code 0.0.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.
- praisonai_code/__init__.py +17 -0
- praisonai_code/cli/__init__.py +12 -0
- praisonai_code/cli/_forward_shim.py +10 -0
- praisonai_code/cli/_paths.py +88 -0
- praisonai_code/cli/_warnings.py +58 -0
- praisonai_code/cli/app.py +757 -0
- praisonai_code/cli/approval_backend.py +272 -0
- praisonai_code/cli/branding.py +94 -0
- praisonai_code/cli/commands/__init__.py +114 -0
- praisonai_code/cli/commands/acp.py +80 -0
- praisonai_code/cli/commands/agent.py +116 -0
- praisonai_code/cli/commands/agents.py +80 -0
- praisonai_code/cli/commands/app.py +139 -0
- praisonai_code/cli/commands/attach.py +95 -0
- praisonai_code/cli/commands/audit.py +102 -0
- praisonai_code/cli/commands/auth.py +508 -0
- praisonai_code/cli/commands/batch.py +848 -0
- praisonai_code/cli/commands/benchmark.py +286 -0
- praisonai_code/cli/commands/browser.py +299 -0
- praisonai_code/cli/commands/call.py +45 -0
- praisonai_code/cli/commands/chat.py +332 -0
- praisonai_code/cli/commands/checkpoint.py +170 -0
- praisonai_code/cli/commands/code.py +276 -0
- praisonai_code/cli/commands/command.py +114 -0
- praisonai_code/cli/commands/commit.py +47 -0
- praisonai_code/cli/commands/completion.py +333 -0
- praisonai_code/cli/commands/config.py +681 -0
- praisonai_code/cli/commands/context.py +414 -0
- praisonai_code/cli/commands/daemon.py +203 -0
- praisonai_code/cli/commands/debug.py +142 -0
- praisonai_code/cli/commands/deploy.py +71 -0
- praisonai_code/cli/commands/diag.py +55 -0
- praisonai_code/cli/commands/docs.py +1575 -0
- praisonai_code/cli/commands/doctor.py +332 -0
- praisonai_code/cli/commands/endpoints.py +51 -0
- praisonai_code/cli/commands/environment.py +179 -0
- praisonai_code/cli/commands/eval.py +131 -0
- praisonai_code/cli/commands/examples.py +953 -0
- praisonai_code/cli/commands/flow.py +436 -0
- praisonai_code/cli/commands/github.py +752 -0
- praisonai_code/cli/commands/hooks.py +74 -0
- praisonai_code/cli/commands/init.py +174 -0
- praisonai_code/cli/commands/knowledge.py +440 -0
- praisonai_code/cli/commands/langextract.py +120 -0
- praisonai_code/cli/commands/langfuse.py +984 -0
- praisonai_code/cli/commands/loop.py +211 -0
- praisonai_code/cli/commands/lsp.py +112 -0
- praisonai_code/cli/commands/managed.py +659 -0
- praisonai_code/cli/commands/mcp.py +763 -0
- praisonai_code/cli/commands/memory.py +298 -0
- praisonai_code/cli/commands/models.py +264 -0
- praisonai_code/cli/commands/n8n.py +326 -0
- praisonai_code/cli/commands/obs.py +19 -0
- praisonai_code/cli/commands/package.py +76 -0
- praisonai_code/cli/commands/paths.py +106 -0
- praisonai_code/cli/commands/permissions.py +272 -0
- praisonai_code/cli/commands/plugins.py +609 -0
- praisonai_code/cli/commands/port.py +530 -0
- praisonai_code/cli/commands/profile.py +466 -0
- praisonai_code/cli/commands/publish.py +193 -0
- praisonai_code/cli/commands/rag.py +913 -0
- praisonai_code/cli/commands/realtime.py +52 -0
- praisonai_code/cli/commands/recipe.py +684 -0
- praisonai_code/cli/commands/registry.py +59 -0
- praisonai_code/cli/commands/replay.py +830 -0
- praisonai_code/cli/commands/research.py +49 -0
- praisonai_code/cli/commands/retrieval.py +377 -0
- praisonai_code/cli/commands/rules.py +71 -0
- praisonai_code/cli/commands/run.py +1573 -0
- praisonai_code/cli/commands/sandbox.py +371 -0
- praisonai_code/cli/commands/schedule.py +529 -0
- praisonai_code/cli/commands/serve.py +690 -0
- praisonai_code/cli/commands/session.py +450 -0
- praisonai_code/cli/commands/setup.py +174 -0
- praisonai_code/cli/commands/skills.py +545 -0
- praisonai_code/cli/commands/standardise.py +711 -0
- praisonai_code/cli/commands/templates.py +54 -0
- praisonai_code/cli/commands/test.py +558 -0
- praisonai_code/cli/commands/todo.py +74 -0
- praisonai_code/cli/commands/tools.py +205 -0
- praisonai_code/cli/commands/traces.py +145 -0
- praisonai_code/cli/commands/tracker.py +852 -0
- praisonai_code/cli/commands/train.py +613 -0
- praisonai_code/cli/commands/ui.py +172 -0
- praisonai_code/cli/commands/up.py +354 -0
- praisonai_code/cli/commands/validate.py +291 -0
- praisonai_code/cli/commands/version.py +101 -0
- praisonai_code/cli/commands/workflow.py +97 -0
- praisonai_code/cli/config_loader.py +437 -0
- praisonai_code/cli/configuration/__init__.py +27 -0
- praisonai_code/cli/configuration/config.schema.json +57 -0
- praisonai_code/cli/configuration/credentials.py +446 -0
- praisonai_code/cli/configuration/loader.py +364 -0
- praisonai_code/cli/configuration/model_resolver.py +161 -0
- praisonai_code/cli/configuration/oauth.py +389 -0
- praisonai_code/cli/configuration/paths.py +224 -0
- praisonai_code/cli/configuration/resolver.py +687 -0
- praisonai_code/cli/configuration/schema.py +317 -0
- praisonai_code/cli/execution/__init__.py +99 -0
- praisonai_code/cli/execution/core.py +208 -0
- praisonai_code/cli/execution/profiler.py +898 -0
- praisonai_code/cli/execution/request.py +85 -0
- praisonai_code/cli/execution/result.py +74 -0
- praisonai_code/cli/fallback_schema.py +416 -0
- praisonai_code/cli/features/__init__.py +278 -0
- praisonai_code/cli/features/_endpoint_registry.py +64 -0
- praisonai_code/cli/features/_search_registry.py +43 -0
- praisonai_code/cli/features/acp.py +236 -0
- praisonai_code/cli/features/action_orchestrator.py +576 -0
- praisonai_code/cli/features/agent_scheduler.py +773 -0
- praisonai_code/cli/features/agent_tools.py +603 -0
- praisonai_code/cli/features/agents.py +397 -0
- praisonai_code/cli/features/at_mentions.py +471 -0
- praisonai_code/cli/features/audit_cli.py +270 -0
- praisonai_code/cli/features/auto_memory.py +182 -0
- praisonai_code/cli/features/auto_mode.py +552 -0
- praisonai_code/cli/features/autonomy_mode.py +546 -0
- praisonai_code/cli/features/background.py +356 -0
- praisonai_code/cli/features/base.py +168 -0
- praisonai_code/cli/features/benchmark.py +1462 -0
- praisonai_code/cli/features/capabilities.py +1326 -0
- praisonai_code/cli/features/checkpoints.py +345 -0
- praisonai_code/cli/features/cli_profiler.py +335 -0
- praisonai_code/cli/features/code_intelligence.py +666 -0
- praisonai_code/cli/features/compaction.py +294 -0
- praisonai_code/cli/features/compare.py +534 -0
- praisonai_code/cli/features/config_hierarchy.py +366 -0
- praisonai_code/cli/features/context_manager.py +597 -0
- praisonai_code/cli/features/cost_tracker.py +514 -0
- praisonai_code/cli/features/csv_test_runner.py +736 -0
- praisonai_code/cli/features/custom_definitions.py +790 -0
- praisonai_code/cli/features/debug.py +810 -0
- praisonai_code/cli/features/deploy.py +605 -0
- praisonai_code/cli/features/diag.py +289 -0
- praisonai_code/cli/features/display_jsonl.py +173 -0
- praisonai_code/cli/features/doctor/__init__.py +63 -0
- praisonai_code/cli/features/doctor/checks/__init__.py +29 -0
- praisonai_code/cli/features/doctor/checks/acp_checks.py +220 -0
- praisonai_code/cli/features/doctor/checks/bot_checks.py +340 -0
- praisonai_code/cli/features/doctor/checks/config_checks.py +373 -0
- praisonai_code/cli/features/doctor/checks/db_checks.py +366 -0
- praisonai_code/cli/features/doctor/checks/env_checks.py +637 -0
- praisonai_code/cli/features/doctor/checks/gateway_checks.py +387 -0
- praisonai_code/cli/features/doctor/checks/lsp_checks.py +231 -0
- praisonai_code/cli/features/doctor/checks/mcp_checks.py +367 -0
- praisonai_code/cli/features/doctor/checks/memory_checks.py +268 -0
- praisonai_code/cli/features/doctor/checks/network_checks.py +251 -0
- praisonai_code/cli/features/doctor/checks/obs_checks.py +328 -0
- praisonai_code/cli/features/doctor/checks/packaging_checks.py +422 -0
- praisonai_code/cli/features/doctor/checks/performance_checks.py +235 -0
- praisonai_code/cli/features/doctor/checks/permissions_checks.py +259 -0
- praisonai_code/cli/features/doctor/checks/runtime_checks.py +650 -0
- praisonai_code/cli/features/doctor/checks/runtime_migration_checks.py +220 -0
- praisonai_code/cli/features/doctor/checks/selftest_checks.py +322 -0
- praisonai_code/cli/features/doctor/checks/serve_checks.py +426 -0
- praisonai_code/cli/features/doctor/checks/skills_checks.py +327 -0
- praisonai_code/cli/features/doctor/checks/tools_checks.py +371 -0
- praisonai_code/cli/features/doctor/engine.py +266 -0
- praisonai_code/cli/features/doctor/formatters.py +377 -0
- praisonai_code/cli/features/doctor/handler.py +564 -0
- praisonai_code/cli/features/doctor/models.py +276 -0
- praisonai_code/cli/features/doctor/registry.py +239 -0
- praisonai_code/cli/features/endpoints.py +1016 -0
- praisonai_code/cli/features/eval.py +559 -0
- praisonai_code/cli/features/examples.py +707 -0
- praisonai_code/cli/features/external_agents.py +231 -0
- praisonai_code/cli/features/fast_context.py +410 -0
- praisonai_code/cli/features/file_history.py +320 -0
- praisonai_code/cli/features/flow_display.py +566 -0
- praisonai_code/cli/features/git_attribution.py +159 -0
- praisonai_code/cli/features/git_integration.py +651 -0
- praisonai_code/cli/features/guardrail.py +171 -0
- praisonai_code/cli/features/handoff.py +252 -0
- praisonai_code/cli/features/hooks.py +583 -0
- praisonai_code/cli/features/hybrid_workflow.py +391 -0
- praisonai_code/cli/features/image.py +384 -0
- praisonai_code/cli/features/interactive_core_headless.py +450 -0
- praisonai_code/cli/features/interactive_runtime.py +600 -0
- praisonai_code/cli/features/interactive_test_harness.py +537 -0
- praisonai_code/cli/features/interactive_tools.py +428 -0
- praisonai_code/cli/features/interactive_tui.py +603 -0
- praisonai_code/cli/features/job_workflow.py +906 -0
- praisonai_code/cli/features/jobs.py +632 -0
- praisonai_code/cli/features/knowledge.py +531 -0
- praisonai_code/cli/features/knowledge_cli.py +438 -0
- praisonai_code/cli/features/lite.py +244 -0
- praisonai_code/cli/features/logs.py +200 -0
- praisonai_code/cli/features/lsp_cli.py +225 -0
- praisonai_code/cli/features/lsp_diagnostics.py +185 -0
- praisonai_code/cli/features/mcp.py +344 -0
- praisonai_code/cli/features/message_queue.py +587 -0
- praisonai_code/cli/features/metrics.py +210 -0
- praisonai_code/cli/features/migrate.py +1329 -0
- praisonai_code/cli/features/migration_flow.py +463 -0
- praisonai_code/cli/features/migration_spec.py +276 -0
- praisonai_code/cli/features/n8n.py +703 -0
- praisonai_code/cli/features/observability.py +293 -0
- praisonai_code/cli/features/ollama.py +361 -0
- praisonai_code/cli/features/output_modes.py +155 -0
- praisonai_code/cli/features/output_style.py +273 -0
- praisonai_code/cli/features/package.py +631 -0
- praisonai_code/cli/features/performance.py +308 -0
- praisonai_code/cli/features/persistence.py +636 -0
- praisonai_code/cli/features/profiler/__init__.py +81 -0
- praisonai_code/cli/features/profiler/core.py +558 -0
- praisonai_code/cli/features/profiler/optimizations.py +652 -0
- praisonai_code/cli/features/profiler/suite.py +386 -0
- praisonai_code/cli/features/queue/__init__.py +73 -0
- praisonai_code/cli/features/queue/manager.py +435 -0
- praisonai_code/cli/features/queue/models.py +289 -0
- praisonai_code/cli/features/queue/persistence.py +564 -0
- praisonai_code/cli/features/queue/scheduler.py +529 -0
- praisonai_code/cli/features/queue/worker.py +400 -0
- praisonai_code/cli/features/recipe.py +2187 -0
- praisonai_code/cli/features/recipe_creator.py +996 -0
- praisonai_code/cli/features/recipe_optimizer.py +1364 -0
- praisonai_code/cli/features/recipe_prompts.py +226 -0
- praisonai_code/cli/features/registry.py +229 -0
- praisonai_code/cli/features/repo_map.py +860 -0
- praisonai_code/cli/features/router.py +466 -0
- praisonai_code/cli/features/safe_shell.py +427 -0
- praisonai_code/cli/features/sandbox_cli.py +283 -0
- praisonai_code/cli/features/sandbox_executor.py +536 -0
- praisonai_code/cli/features/sdk_knowledge.py +500 -0
- praisonai_code/cli/features/session.py +222 -0
- praisonai_code/cli/features/session_checkpoints.py +208 -0
- praisonai_code/cli/features/setup/__init__.py +9 -0
- praisonai_code/cli/features/setup/handler.py +355 -0
- praisonai_code/cli/features/setup/templates.py +62 -0
- praisonai_code/cli/features/skills.py +940 -0
- praisonai_code/cli/features/slash_commands.py +692 -0
- praisonai_code/cli/features/telemetry.py +179 -0
- praisonai_code/cli/features/templates.py +1390 -0
- praisonai_code/cli/features/thinking.py +343 -0
- praisonai_code/cli/features/todo.py +334 -0
- praisonai_code/cli/features/tools.py +680 -0
- praisonai_code/cli/features/tui/__init__.py +83 -0
- praisonai_code/cli/features/tui/app.py +871 -0
- praisonai_code/cli/features/tui/cli.py +580 -0
- praisonai_code/cli/features/tui/config.py +150 -0
- praisonai_code/cli/features/tui/debug.py +526 -0
- praisonai_code/cli/features/tui/events.py +99 -0
- praisonai_code/cli/features/tui/mock_provider.py +328 -0
- praisonai_code/cli/features/tui/orchestrator.py +652 -0
- praisonai_code/cli/features/tui/screens/__init__.py +50 -0
- praisonai_code/cli/features/tui/screens/help.py +157 -0
- praisonai_code/cli/features/tui/screens/main.py +568 -0
- praisonai_code/cli/features/tui/screens/queue.py +174 -0
- praisonai_code/cli/features/tui/screens/session.py +124 -0
- praisonai_code/cli/features/tui/screens/settings.py +148 -0
- praisonai_code/cli/features/tui/session_store.py +198 -0
- praisonai_code/cli/features/tui/widgets/__init__.py +56 -0
- praisonai_code/cli/features/tui/widgets/chat.py +263 -0
- praisonai_code/cli/features/tui/widgets/command_popup.py +258 -0
- praisonai_code/cli/features/tui/widgets/composer.py +292 -0
- praisonai_code/cli/features/tui/widgets/file_popup.py +207 -0
- praisonai_code/cli/features/tui/widgets/queue_panel.py +223 -0
- praisonai_code/cli/features/tui/widgets/status.py +181 -0
- praisonai_code/cli/features/tui/widgets/tool_panel.py +307 -0
- praisonai_code/cli/features/wizard.py +289 -0
- praisonai_code/cli/features/workflow.py +802 -0
- praisonai_code/cli/features/yaml_utils.py +321 -0
- praisonai_code/cli/interactive/__init__.py +48 -0
- praisonai_code/cli/interactive/async_tui.py +1218 -0
- praisonai_code/cli/interactive/config.py +139 -0
- praisonai_code/cli/interactive/core.py +618 -0
- praisonai_code/cli/interactive/events.py +131 -0
- praisonai_code/cli/interactive/frontends/__init__.py +31 -0
- praisonai_code/cli/interactive/frontends/rich_frontend.py +462 -0
- praisonai_code/cli/interactive/frontends/textual_frontend.py +157 -0
- praisonai_code/cli/interactive/praison_io.py +502 -0
- praisonai_code/cli/interactive/repl.py +297 -0
- praisonai_code/cli/interactive/split_tui.py +456 -0
- praisonai_code/cli/interactive/tui_app.py +457 -0
- praisonai_code/cli/langfuse_client.py +360 -0
- praisonai_code/cli/main.py +7421 -0
- praisonai_code/cli/output/__init__.py +25 -0
- praisonai_code/cli/output/console.py +456 -0
- praisonai_code/cli/output/event_bridge.py +191 -0
- praisonai_code/cli/schedule_cli.py +54 -0
- praisonai_code/cli/schema_provider.py +23 -0
- praisonai_code/cli/session/__init__.py +16 -0
- praisonai_code/cli/session/resume.py +148 -0
- praisonai_code/cli/session/unified.py +548 -0
- praisonai_code/cli/state/__init__.py +31 -0
- praisonai_code/cli/state/identifiers.py +161 -0
- praisonai_code/cli/state/project_sessions.py +383 -0
- praisonai_code/cli/state/sessions.py +390 -0
- praisonai_code/cli/ui/__init__.py +160 -0
- praisonai_code/cli/ui/config.py +46 -0
- praisonai_code/cli/ui/events.py +61 -0
- praisonai_code/cli/ui/mg_backend.py +342 -0
- praisonai_code/cli/ui/plain.py +133 -0
- praisonai_code/cli/ui/rich_backend.py +162 -0
- praisonai_code/cli/unified_schema.py +655 -0
- praisonai_code/cli/utils/env_utils.py +126 -0
- praisonai_code/cli/utils/project.py +131 -0
- praisonai_code/cli_backends/__init__.py +73 -0
- praisonai_code/cli_backends/claude.py +373 -0
- praisonai_code/cli_backends/registry.py +113 -0
- praisonai_code/runtime/__init__.py +36 -0
- praisonai_code/runtime/__main__.py +81 -0
- praisonai_code/runtime/client.py +131 -0
- praisonai_code/runtime/descriptor.py +209 -0
- praisonai_code/runtime/server.py +356 -0
- praisonai_code-0.0.1.dist-info/METADATA +80 -0
- praisonai_code-0.0.1.dist-info/RECORD +309 -0
- praisonai_code-0.0.1.dist-info/WHEEL +5 -0
- praisonai_code-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Code command group for PraisonAI CLI.
|
|
3
|
+
|
|
4
|
+
Provides terminal-native code assistant mode.
|
|
5
|
+
This command NEVER opens a browser - it runs entirely in the terminal.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import List, Optional
|
|
9
|
+
|
|
10
|
+
import typer
|
|
11
|
+
|
|
12
|
+
app = typer.Typer(help="Terminal-native code assistant mode")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@app.callback(invoke_without_command=True)
|
|
16
|
+
def code_main(
|
|
17
|
+
ctx: typer.Context,
|
|
18
|
+
prompt: Optional[str] = typer.Argument(None, help="Code task or question"),
|
|
19
|
+
model: Optional[str] = typer.Option(None, "--model", "-m", help="LLM model to use"),
|
|
20
|
+
verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"),
|
|
21
|
+
tools: Optional[str] = typer.Option(None, "--tools", "-t", help="Tools file path"),
|
|
22
|
+
workspace: Optional[str] = typer.Option(None, "--workspace", "-w", help="Workspace directory"),
|
|
23
|
+
file: Optional[List[str]] = typer.Option(None, "--file", "-f", help="Attach file(s) to context"),
|
|
24
|
+
no_acp: bool = typer.Option(False, "--no-acp", help="Disable ACP tools (file operations)"),
|
|
25
|
+
no_lsp: bool = typer.Option(False, "--no-lsp", help="Disable LSP tools (code intelligence)"),
|
|
26
|
+
safe_mode: bool = typer.Option(True, "--safe/--no-safe", help="Safe mode (default ON): require approval for file writes and commands"),
|
|
27
|
+
dangerously_skip_approval: bool = typer.Option(False, "--dangerously-skip-approval", help="Skip all approval prompts and run dangerous tools unguarded (restores legacy behaviour)"),
|
|
28
|
+
checkpoints: bool = typer.Option(False, "--checkpoints/--no-checkpoints", help="Auto-checkpoint the workspace before each file-mutating turn (enables in-session /undo and /revert)"),
|
|
29
|
+
revert: Optional[str] = typer.Option(None, "--revert", help="Restore the workspace to a prior checkpoint (id, short id, or 'last') and exit"),
|
|
30
|
+
session_id: Optional[str] = typer.Option(None, "--session", "-s", help="Session ID to resume"),
|
|
31
|
+
continue_session: bool = typer.Option(False, "--continue", "-c", help="Continue last session"),
|
|
32
|
+
agent: Optional[str] = typer.Option(None, "--agent", "-a", help="Use a named custom agent profile (applies its tools and permission/mode scope)"),
|
|
33
|
+
thinking: Optional[str] = typer.Option(None, "--thinking", help="Reasoning effort (off, minimal, low, medium, high)"),
|
|
34
|
+
autonomy: bool = typer.Option(True, "--autonomy/--no-autonomy", help="Enable agent autonomy for complex tasks"),
|
|
35
|
+
profile: bool = typer.Option(False, "--profile", help="Enable CLI profiling (timing breakdown)"),
|
|
36
|
+
profile_deep: bool = typer.Option(False, "--profile-deep", help="Enable deep profiling (cProfile stats, higher overhead)"),
|
|
37
|
+
):
|
|
38
|
+
"""
|
|
39
|
+
Start terminal-native code assistant mode.
|
|
40
|
+
|
|
41
|
+
This is a terminal-based code assistant with file awareness, diff display,
|
|
42
|
+
and ACP/LSP tools enabled by default. It NEVER opens a browser.
|
|
43
|
+
|
|
44
|
+
For browser-based code UI, use: praisonai ui code
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
praisonai code
|
|
48
|
+
praisonai code "Refactor this function"
|
|
49
|
+
praisonai code --model gpt-4o --workspace ./src
|
|
50
|
+
praisonai code "Fix the bug" --file main.py
|
|
51
|
+
praisonai code "What is 2+2?" --profile
|
|
52
|
+
"""
|
|
53
|
+
import os
|
|
54
|
+
import argparse
|
|
55
|
+
|
|
56
|
+
# Validate --thinking up front so an unknown value fails closed before any
|
|
57
|
+
# work is done (consistent with MODE_RULES validation on custom agents).
|
|
58
|
+
from praisonai.cli.features.thinking import thinking_to_budget
|
|
59
|
+
try:
|
|
60
|
+
thinking_budget = thinking_to_budget(thinking)
|
|
61
|
+
except ValueError as exc:
|
|
62
|
+
typer.echo(f"Error: {exc}", err=True)
|
|
63
|
+
raise typer.Exit(1)
|
|
64
|
+
|
|
65
|
+
# Resolve a named agent profile (tools + permission/mode scope). The profile
|
|
66
|
+
# reuses the same custom-definitions loader as `praisonai run --agent`, so a
|
|
67
|
+
# profile defined once in .praisonai/agents/<name>.md behaves identically
|
|
68
|
+
# across `code`, `run`, and the Python Agent(...) constructor.
|
|
69
|
+
agent_profile = None
|
|
70
|
+
if agent:
|
|
71
|
+
from praisonai.cli.features.custom_definitions import load_agent_from_name
|
|
72
|
+
agent_profile = load_agent_from_name(agent)
|
|
73
|
+
if not agent_profile:
|
|
74
|
+
typer.echo(f"Error: Agent '{agent}' not found", err=True)
|
|
75
|
+
raise typer.Exit(1)
|
|
76
|
+
|
|
77
|
+
# Set workspace if provided
|
|
78
|
+
if workspace:
|
|
79
|
+
os.environ["PRAISONAI_WORKSPACE"] = workspace
|
|
80
|
+
|
|
81
|
+
# --revert: restore the workspace to a prior checkpoint and exit before
|
|
82
|
+
# starting a session. Reuses the existing CheckpointsHandler so the same
|
|
83
|
+
# 'last'/short-id/prefix resolution as `praisonai checkpoint restore`
|
|
84
|
+
# applies. This is a one-shot CLI path, not the interactive /revert.
|
|
85
|
+
if revert is not None:
|
|
86
|
+
_revert_workspace(revert, workspace or os.getcwd(), verbose)
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
# --checkpoints opts the session into turn-aware auto-checkpointing,
|
|
90
|
+
# surfaced to the interactive loop via the env override the session
|
|
91
|
+
# checkpoint manager reads. Default off keeps zero overhead.
|
|
92
|
+
if checkpoints:
|
|
93
|
+
os.environ["PRAISONAI_CHECKPOINTS"] = "on"
|
|
94
|
+
|
|
95
|
+
# Enable code-specific environment
|
|
96
|
+
os.environ["PRAISONAI_CODE_MODE"] = "true"
|
|
97
|
+
|
|
98
|
+
# Set approval mode based on --safe flag.
|
|
99
|
+
# Safe-by-default: dangerous tools (shell exec, file writes) are gated
|
|
100
|
+
# behind an interactive approval prompt unless the user explicitly opts
|
|
101
|
+
# out with --no-safe or --dangerously-skip-approval. The latter also sets
|
|
102
|
+
# PRAISONAI_TOOL_SAFETY=off so the core runtime skips its safe-by-default
|
|
103
|
+
# ask path (see Agent.__init__ approval handling).
|
|
104
|
+
if dangerously_skip_approval or not safe_mode:
|
|
105
|
+
os.environ["PRAISON_APPROVAL_MODE"] = "auto"
|
|
106
|
+
os.environ["PRAISONAI_TOOL_SAFETY"] = "off"
|
|
107
|
+
else:
|
|
108
|
+
os.environ["PRAISON_APPROVAL_MODE"] = "prompt"
|
|
109
|
+
# Clear any stale bypass from a previous --no-safe run in the same
|
|
110
|
+
# process (REPL/worker/test). Leaving PRAISONAI_TOOL_SAFETY=off would
|
|
111
|
+
# silently keep later safe-default agents unguarded.
|
|
112
|
+
os.environ.pop("PRAISONAI_TOOL_SAFETY", None)
|
|
113
|
+
|
|
114
|
+
# Handle profiling for single prompt mode
|
|
115
|
+
if prompt and (profile or profile_deep):
|
|
116
|
+
_run_profiled_code(
|
|
117
|
+
prompt=prompt,
|
|
118
|
+
model=model,
|
|
119
|
+
verbose=verbose,
|
|
120
|
+
profile_deep=profile_deep,
|
|
121
|
+
thinking_budget=thinking_budget,
|
|
122
|
+
)
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
# Warn if profiling requested without prompt (REPL mode doesn't support profiling)
|
|
126
|
+
if (profile or profile_deep) and not prompt:
|
|
127
|
+
typer.echo("⚠️ Profiling is only supported for single prompt mode.", err=True)
|
|
128
|
+
typer.echo(" Use: praisonai code \"your prompt\" --profile", err=True)
|
|
129
|
+
|
|
130
|
+
# Build args namespace for _start_interactive_mode
|
|
131
|
+
args = argparse.Namespace()
|
|
132
|
+
args.llm = model
|
|
133
|
+
args.verbose = verbose
|
|
134
|
+
args.tools = tools
|
|
135
|
+
args.no_acp = no_acp
|
|
136
|
+
args.no_lsp = no_lsp
|
|
137
|
+
args.resume_session = session_id if session_id else ('last' if continue_session else None)
|
|
138
|
+
# Reasoning effort (mapped to the core thinking_budget) and named agent
|
|
139
|
+
# profile (tools + permission/mode scope), consumed when the agent is built.
|
|
140
|
+
args.thinking_budget = thinking_budget
|
|
141
|
+
args.agent_profile = agent_profile
|
|
142
|
+
|
|
143
|
+
# Resolve the named profile's permission/mode scope into an approval config
|
|
144
|
+
# so the code session runs least-privilege (e.g. `--agent plan` is rejected
|
|
145
|
+
# for write/edit/shell). Reuses the same engine as `praisonai run --agent`.
|
|
146
|
+
args.agent_approval = None
|
|
147
|
+
if agent_profile:
|
|
148
|
+
permission_config = agent_profile.get("permissions")
|
|
149
|
+
if permission_config:
|
|
150
|
+
from praisonai.cli.features.approval import resolve_approval_config
|
|
151
|
+
has_ask_rules = any(
|
|
152
|
+
str(action).strip().lower() == "ask"
|
|
153
|
+
for action in permission_config.values()
|
|
154
|
+
)
|
|
155
|
+
args.agent_approval = resolve_approval_config(
|
|
156
|
+
"console",
|
|
157
|
+
non_interactive=not has_ask_rules,
|
|
158
|
+
permissions_config=permission_config,
|
|
159
|
+
)
|
|
160
|
+
# Apply the profile's model unless the user overrode it with --model.
|
|
161
|
+
if not model and agent_profile.get("llm"):
|
|
162
|
+
args.llm = agent_profile["llm"]
|
|
163
|
+
|
|
164
|
+
# Import and run the terminal-native interactive mode
|
|
165
|
+
from praisonai.cli.main import PraisonAI
|
|
166
|
+
|
|
167
|
+
praison = PraisonAI()
|
|
168
|
+
|
|
169
|
+
if prompt:
|
|
170
|
+
# Single prompt mode - use _run_chat_mode with code context
|
|
171
|
+
praison._run_chat_mode(prompt, args)
|
|
172
|
+
else:
|
|
173
|
+
# Interactive REPL mode - use _start_interactive_mode
|
|
174
|
+
praison._start_interactive_mode(args)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _run_profiled_code(
|
|
178
|
+
prompt: str,
|
|
179
|
+
model: Optional[str] = None,
|
|
180
|
+
verbose: bool = False,
|
|
181
|
+
profile_deep: bool = False,
|
|
182
|
+
thinking_budget: Optional[int] = None,
|
|
183
|
+
):
|
|
184
|
+
"""Run code assistant with profiling enabled."""
|
|
185
|
+
from praisonai.cli.features.cli_profiler import (
|
|
186
|
+
CLIProfileConfig,
|
|
187
|
+
CLIProfiler,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
config = CLIProfileConfig(enabled=True, deep=profile_deep)
|
|
191
|
+
profiler = CLIProfiler(config)
|
|
192
|
+
|
|
193
|
+
if profile_deep:
|
|
194
|
+
typer.echo("⚠️ Deep profiling enabled - this adds significant overhead", err=True)
|
|
195
|
+
|
|
196
|
+
profiler.start()
|
|
197
|
+
|
|
198
|
+
# Import phase
|
|
199
|
+
profiler.mark_import_start()
|
|
200
|
+
try:
|
|
201
|
+
from praisonaiagents import Agent
|
|
202
|
+
except ImportError:
|
|
203
|
+
typer.echo("Error: praisonaiagents not installed", err=True)
|
|
204
|
+
raise typer.Exit(1)
|
|
205
|
+
profiler.mark_import_end()
|
|
206
|
+
|
|
207
|
+
# Agent initialization phase
|
|
208
|
+
profiler.mark_init_start()
|
|
209
|
+
agent_config = {
|
|
210
|
+
"name": "CodeAgent",
|
|
211
|
+
"role": "Code Assistant",
|
|
212
|
+
"goal": "Help with coding tasks",
|
|
213
|
+
"verbose": verbose,
|
|
214
|
+
}
|
|
215
|
+
if model:
|
|
216
|
+
agent_config["llm"] = model
|
|
217
|
+
|
|
218
|
+
agent = Agent(**agent_config)
|
|
219
|
+
# thinking_budget is set post-construction via the property setter (the
|
|
220
|
+
# Agent constructor does not accept it as a keyword argument).
|
|
221
|
+
if thinking_budget is not None:
|
|
222
|
+
agent.thinking_budget = thinking_budget
|
|
223
|
+
profiler.mark_init_end()
|
|
224
|
+
|
|
225
|
+
# Execution phase
|
|
226
|
+
profiler.mark_exec_start()
|
|
227
|
+
response = agent.start(prompt)
|
|
228
|
+
profiler.mark_exec_end()
|
|
229
|
+
|
|
230
|
+
profiler.stop()
|
|
231
|
+
|
|
232
|
+
# Print response
|
|
233
|
+
if response:
|
|
234
|
+
print(response)
|
|
235
|
+
|
|
236
|
+
# Print profiling report
|
|
237
|
+
profiler.print_report()
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def _revert_workspace(ref: str, workspace: str, verbose: bool = False) -> None:
|
|
241
|
+
"""Restore the workspace to a checkpoint (one-shot ``code --revert``).
|
|
242
|
+
|
|
243
|
+
Resolves ``ref`` ('last'/short id/prefix) the same way
|
|
244
|
+
``praisonai checkpoint restore`` does, previews the diff, then restores.
|
|
245
|
+
"""
|
|
246
|
+
import asyncio
|
|
247
|
+
|
|
248
|
+
from praisonai.cli.commands.checkpoint import _resolve_checkpoint_id
|
|
249
|
+
from praisonai.cli.features.checkpoints import CheckpointsHandler
|
|
250
|
+
|
|
251
|
+
# Honor a configured checkpoints.storage_dir so this one-shot restore reads
|
|
252
|
+
# from the same store the interactive session writes to.
|
|
253
|
+
storage_dir = None
|
|
254
|
+
try:
|
|
255
|
+
from ..configuration.resolver import resolve_config
|
|
256
|
+
section = (resolve_config().extra or {}).get("checkpoints", {})
|
|
257
|
+
if isinstance(section, dict):
|
|
258
|
+
storage_dir = section.get("storage_dir")
|
|
259
|
+
except Exception:
|
|
260
|
+
storage_dir = None
|
|
261
|
+
|
|
262
|
+
handler = CheckpointsHandler(
|
|
263
|
+
workspace_dir=workspace, verbose=verbose, storage_dir=storage_dir
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
async def _run() -> bool:
|
|
267
|
+
resolved = await _resolve_checkpoint_id(handler, ref)
|
|
268
|
+
if resolved is None:
|
|
269
|
+
handler._print_error(f"No checkpoint found for: {ref}")
|
|
270
|
+
return False
|
|
271
|
+
# Preview what restoring will change before applying it.
|
|
272
|
+
await handler.diff(resolved, None)
|
|
273
|
+
return await handler.restore(resolved)
|
|
274
|
+
|
|
275
|
+
if not asyncio.run(_run()):
|
|
276
|
+
raise typer.Exit(1)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command management for custom command definitions.
|
|
3
|
+
|
|
4
|
+
Provides commands to list and inspect custom command definitions.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from ..output.console import get_output_controller
|
|
12
|
+
|
|
13
|
+
app = typer.Typer(help="Manage custom commands")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@app.command(name="list")
|
|
17
|
+
def list_commands(
|
|
18
|
+
verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed information"),
|
|
19
|
+
):
|
|
20
|
+
"""List all discovered custom commands."""
|
|
21
|
+
output = get_output_controller()
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
from praisonai.cli.features.custom_definitions import CustomDefinitionsDiscovery
|
|
25
|
+
|
|
26
|
+
discovery = CustomDefinitionsDiscovery()
|
|
27
|
+
discovery.discover()
|
|
28
|
+
|
|
29
|
+
commands = discovery.list_commands()
|
|
30
|
+
|
|
31
|
+
if not commands:
|
|
32
|
+
output.print_info("No custom commands found.")
|
|
33
|
+
output.print_info("Run 'praisonai init' to scaffold a starter .praisonai/ project,")
|
|
34
|
+
output.print_info("or create commands in .praisonai/commands/*.md or ~/.praisonai/commands/*.md")
|
|
35
|
+
return
|
|
36
|
+
|
|
37
|
+
from rich.table import Table
|
|
38
|
+
from rich.console import Console
|
|
39
|
+
|
|
40
|
+
console = Console()
|
|
41
|
+
table = Table(title="Custom Commands", show_header=True)
|
|
42
|
+
table.add_column("Name", style="cyan")
|
|
43
|
+
table.add_column("Source", style="yellow")
|
|
44
|
+
table.add_column("Description", style="green")
|
|
45
|
+
|
|
46
|
+
if verbose:
|
|
47
|
+
table.add_column("Path", style="dim")
|
|
48
|
+
|
|
49
|
+
for cmd in commands:
|
|
50
|
+
row = [
|
|
51
|
+
cmd.name,
|
|
52
|
+
cmd.source,
|
|
53
|
+
cmd.description or "No description",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
if verbose:
|
|
57
|
+
row.append(str(cmd.path))
|
|
58
|
+
|
|
59
|
+
table.add_row(*row)
|
|
60
|
+
|
|
61
|
+
console.print(table)
|
|
62
|
+
|
|
63
|
+
except Exception as e:
|
|
64
|
+
output.print_error(str(e))
|
|
65
|
+
raise typer.Exit(1)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@app.command()
|
|
69
|
+
def show(
|
|
70
|
+
name: str = typer.Argument(help="Command name to inspect"),
|
|
71
|
+
preview: bool = typer.Option(False, "--preview", "-p", help="Preview with sample arguments"),
|
|
72
|
+
):
|
|
73
|
+
"""Show details of a specific command."""
|
|
74
|
+
output = get_output_controller()
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
from praisonai.cli.features.custom_definitions import CustomDefinitionsDiscovery, TemplateInterpolator
|
|
78
|
+
|
|
79
|
+
discovery = CustomDefinitionsDiscovery()
|
|
80
|
+
cmd = discovery.get_command(name)
|
|
81
|
+
|
|
82
|
+
if not cmd:
|
|
83
|
+
output.print_error(f"Command '{name}' not found")
|
|
84
|
+
raise typer.Exit(1)
|
|
85
|
+
|
|
86
|
+
from rich.console import Console
|
|
87
|
+
from rich.panel import Panel
|
|
88
|
+
from rich.syntax import Syntax
|
|
89
|
+
|
|
90
|
+
console = Console()
|
|
91
|
+
|
|
92
|
+
# Build command info
|
|
93
|
+
info = f"""[bold cyan]Command: {cmd.name}[/bold cyan]
|
|
94
|
+
[yellow]Source:[/yellow] {cmd.source}
|
|
95
|
+
[yellow]Path:[/yellow] {cmd.path}
|
|
96
|
+
[yellow]Description:[/yellow] {cmd.description or 'No description'}"""
|
|
97
|
+
|
|
98
|
+
console.print(Panel(info, title="Command Details", border_style="cyan"))
|
|
99
|
+
|
|
100
|
+
# Show template
|
|
101
|
+
syntax = Syntax(cmd.template, "markdown", theme="monokai", line_numbers=False)
|
|
102
|
+
console.print(Panel(syntax, title="Template", border_style="green"))
|
|
103
|
+
|
|
104
|
+
# Show preview if requested
|
|
105
|
+
if preview:
|
|
106
|
+
interpolator = TemplateInterpolator()
|
|
107
|
+
sample_args = "<sample arguments>"
|
|
108
|
+
preview_text = interpolator.interpolate(cmd.template, sample_args)
|
|
109
|
+
syntax = Syntax(preview_text, "markdown", theme="monokai", line_numbers=False)
|
|
110
|
+
console.print(Panel(syntax, title=f"Preview with args: '{sample_args}'", border_style="yellow"))
|
|
111
|
+
|
|
112
|
+
except Exception as e:
|
|
113
|
+
output.print_error(str(e))
|
|
114
|
+
raise typer.Exit(1)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Commit command group for PraisonAI CLI.
|
|
3
|
+
|
|
4
|
+
Provides git commit commands with AI assistance.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="AI-assisted git commits")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.callback(invoke_without_command=True)
|
|
13
|
+
def commit_main(
|
|
14
|
+
ctx: typer.Context,
|
|
15
|
+
message: str = typer.Option(None, "--message", "-m", help="Commit message (auto-generated if not provided)"),
|
|
16
|
+
all_files: bool = typer.Option(False, "--all", "-a", help="Stage all changes"),
|
|
17
|
+
push: bool = typer.Option(False, "--push", "-p", help="Push after commit"),
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
Create AI-assisted git commits.
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
praisonai commit
|
|
24
|
+
praisonai commit -m "Fix bug"
|
|
25
|
+
praisonai commit --all --push
|
|
26
|
+
"""
|
|
27
|
+
from praisonai.cli.main import PraisonAI
|
|
28
|
+
import sys
|
|
29
|
+
|
|
30
|
+
argv = ['commit']
|
|
31
|
+
if message:
|
|
32
|
+
argv.extend(['--message', message])
|
|
33
|
+
if all_files:
|
|
34
|
+
argv.append('--all')
|
|
35
|
+
if push:
|
|
36
|
+
argv.append('--push')
|
|
37
|
+
|
|
38
|
+
original_argv = sys.argv
|
|
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
|