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.
Files changed (309) hide show
  1. praisonai_code/__init__.py +17 -0
  2. praisonai_code/cli/__init__.py +12 -0
  3. praisonai_code/cli/_forward_shim.py +10 -0
  4. praisonai_code/cli/_paths.py +88 -0
  5. praisonai_code/cli/_warnings.py +58 -0
  6. praisonai_code/cli/app.py +757 -0
  7. praisonai_code/cli/approval_backend.py +272 -0
  8. praisonai_code/cli/branding.py +94 -0
  9. praisonai_code/cli/commands/__init__.py +114 -0
  10. praisonai_code/cli/commands/acp.py +80 -0
  11. praisonai_code/cli/commands/agent.py +116 -0
  12. praisonai_code/cli/commands/agents.py +80 -0
  13. praisonai_code/cli/commands/app.py +139 -0
  14. praisonai_code/cli/commands/attach.py +95 -0
  15. praisonai_code/cli/commands/audit.py +102 -0
  16. praisonai_code/cli/commands/auth.py +508 -0
  17. praisonai_code/cli/commands/batch.py +848 -0
  18. praisonai_code/cli/commands/benchmark.py +286 -0
  19. praisonai_code/cli/commands/browser.py +299 -0
  20. praisonai_code/cli/commands/call.py +45 -0
  21. praisonai_code/cli/commands/chat.py +332 -0
  22. praisonai_code/cli/commands/checkpoint.py +170 -0
  23. praisonai_code/cli/commands/code.py +276 -0
  24. praisonai_code/cli/commands/command.py +114 -0
  25. praisonai_code/cli/commands/commit.py +47 -0
  26. praisonai_code/cli/commands/completion.py +333 -0
  27. praisonai_code/cli/commands/config.py +681 -0
  28. praisonai_code/cli/commands/context.py +414 -0
  29. praisonai_code/cli/commands/daemon.py +203 -0
  30. praisonai_code/cli/commands/debug.py +142 -0
  31. praisonai_code/cli/commands/deploy.py +71 -0
  32. praisonai_code/cli/commands/diag.py +55 -0
  33. praisonai_code/cli/commands/docs.py +1575 -0
  34. praisonai_code/cli/commands/doctor.py +332 -0
  35. praisonai_code/cli/commands/endpoints.py +51 -0
  36. praisonai_code/cli/commands/environment.py +179 -0
  37. praisonai_code/cli/commands/eval.py +131 -0
  38. praisonai_code/cli/commands/examples.py +953 -0
  39. praisonai_code/cli/commands/flow.py +436 -0
  40. praisonai_code/cli/commands/github.py +752 -0
  41. praisonai_code/cli/commands/hooks.py +74 -0
  42. praisonai_code/cli/commands/init.py +174 -0
  43. praisonai_code/cli/commands/knowledge.py +440 -0
  44. praisonai_code/cli/commands/langextract.py +120 -0
  45. praisonai_code/cli/commands/langfuse.py +984 -0
  46. praisonai_code/cli/commands/loop.py +211 -0
  47. praisonai_code/cli/commands/lsp.py +112 -0
  48. praisonai_code/cli/commands/managed.py +659 -0
  49. praisonai_code/cli/commands/mcp.py +763 -0
  50. praisonai_code/cli/commands/memory.py +298 -0
  51. praisonai_code/cli/commands/models.py +264 -0
  52. praisonai_code/cli/commands/n8n.py +326 -0
  53. praisonai_code/cli/commands/obs.py +19 -0
  54. praisonai_code/cli/commands/package.py +76 -0
  55. praisonai_code/cli/commands/paths.py +106 -0
  56. praisonai_code/cli/commands/permissions.py +272 -0
  57. praisonai_code/cli/commands/plugins.py +609 -0
  58. praisonai_code/cli/commands/port.py +530 -0
  59. praisonai_code/cli/commands/profile.py +466 -0
  60. praisonai_code/cli/commands/publish.py +193 -0
  61. praisonai_code/cli/commands/rag.py +913 -0
  62. praisonai_code/cli/commands/realtime.py +52 -0
  63. praisonai_code/cli/commands/recipe.py +684 -0
  64. praisonai_code/cli/commands/registry.py +59 -0
  65. praisonai_code/cli/commands/replay.py +830 -0
  66. praisonai_code/cli/commands/research.py +49 -0
  67. praisonai_code/cli/commands/retrieval.py +377 -0
  68. praisonai_code/cli/commands/rules.py +71 -0
  69. praisonai_code/cli/commands/run.py +1573 -0
  70. praisonai_code/cli/commands/sandbox.py +371 -0
  71. praisonai_code/cli/commands/schedule.py +529 -0
  72. praisonai_code/cli/commands/serve.py +690 -0
  73. praisonai_code/cli/commands/session.py +450 -0
  74. praisonai_code/cli/commands/setup.py +174 -0
  75. praisonai_code/cli/commands/skills.py +545 -0
  76. praisonai_code/cli/commands/standardise.py +711 -0
  77. praisonai_code/cli/commands/templates.py +54 -0
  78. praisonai_code/cli/commands/test.py +558 -0
  79. praisonai_code/cli/commands/todo.py +74 -0
  80. praisonai_code/cli/commands/tools.py +205 -0
  81. praisonai_code/cli/commands/traces.py +145 -0
  82. praisonai_code/cli/commands/tracker.py +852 -0
  83. praisonai_code/cli/commands/train.py +613 -0
  84. praisonai_code/cli/commands/ui.py +172 -0
  85. praisonai_code/cli/commands/up.py +354 -0
  86. praisonai_code/cli/commands/validate.py +291 -0
  87. praisonai_code/cli/commands/version.py +101 -0
  88. praisonai_code/cli/commands/workflow.py +97 -0
  89. praisonai_code/cli/config_loader.py +437 -0
  90. praisonai_code/cli/configuration/__init__.py +27 -0
  91. praisonai_code/cli/configuration/config.schema.json +57 -0
  92. praisonai_code/cli/configuration/credentials.py +446 -0
  93. praisonai_code/cli/configuration/loader.py +364 -0
  94. praisonai_code/cli/configuration/model_resolver.py +161 -0
  95. praisonai_code/cli/configuration/oauth.py +389 -0
  96. praisonai_code/cli/configuration/paths.py +224 -0
  97. praisonai_code/cli/configuration/resolver.py +687 -0
  98. praisonai_code/cli/configuration/schema.py +317 -0
  99. praisonai_code/cli/execution/__init__.py +99 -0
  100. praisonai_code/cli/execution/core.py +208 -0
  101. praisonai_code/cli/execution/profiler.py +898 -0
  102. praisonai_code/cli/execution/request.py +85 -0
  103. praisonai_code/cli/execution/result.py +74 -0
  104. praisonai_code/cli/fallback_schema.py +416 -0
  105. praisonai_code/cli/features/__init__.py +278 -0
  106. praisonai_code/cli/features/_endpoint_registry.py +64 -0
  107. praisonai_code/cli/features/_search_registry.py +43 -0
  108. praisonai_code/cli/features/acp.py +236 -0
  109. praisonai_code/cli/features/action_orchestrator.py +576 -0
  110. praisonai_code/cli/features/agent_scheduler.py +773 -0
  111. praisonai_code/cli/features/agent_tools.py +603 -0
  112. praisonai_code/cli/features/agents.py +397 -0
  113. praisonai_code/cli/features/at_mentions.py +471 -0
  114. praisonai_code/cli/features/audit_cli.py +270 -0
  115. praisonai_code/cli/features/auto_memory.py +182 -0
  116. praisonai_code/cli/features/auto_mode.py +552 -0
  117. praisonai_code/cli/features/autonomy_mode.py +546 -0
  118. praisonai_code/cli/features/background.py +356 -0
  119. praisonai_code/cli/features/base.py +168 -0
  120. praisonai_code/cli/features/benchmark.py +1462 -0
  121. praisonai_code/cli/features/capabilities.py +1326 -0
  122. praisonai_code/cli/features/checkpoints.py +345 -0
  123. praisonai_code/cli/features/cli_profiler.py +335 -0
  124. praisonai_code/cli/features/code_intelligence.py +666 -0
  125. praisonai_code/cli/features/compaction.py +294 -0
  126. praisonai_code/cli/features/compare.py +534 -0
  127. praisonai_code/cli/features/config_hierarchy.py +366 -0
  128. praisonai_code/cli/features/context_manager.py +597 -0
  129. praisonai_code/cli/features/cost_tracker.py +514 -0
  130. praisonai_code/cli/features/csv_test_runner.py +736 -0
  131. praisonai_code/cli/features/custom_definitions.py +790 -0
  132. praisonai_code/cli/features/debug.py +810 -0
  133. praisonai_code/cli/features/deploy.py +605 -0
  134. praisonai_code/cli/features/diag.py +289 -0
  135. praisonai_code/cli/features/display_jsonl.py +173 -0
  136. praisonai_code/cli/features/doctor/__init__.py +63 -0
  137. praisonai_code/cli/features/doctor/checks/__init__.py +29 -0
  138. praisonai_code/cli/features/doctor/checks/acp_checks.py +220 -0
  139. praisonai_code/cli/features/doctor/checks/bot_checks.py +340 -0
  140. praisonai_code/cli/features/doctor/checks/config_checks.py +373 -0
  141. praisonai_code/cli/features/doctor/checks/db_checks.py +366 -0
  142. praisonai_code/cli/features/doctor/checks/env_checks.py +637 -0
  143. praisonai_code/cli/features/doctor/checks/gateway_checks.py +387 -0
  144. praisonai_code/cli/features/doctor/checks/lsp_checks.py +231 -0
  145. praisonai_code/cli/features/doctor/checks/mcp_checks.py +367 -0
  146. praisonai_code/cli/features/doctor/checks/memory_checks.py +268 -0
  147. praisonai_code/cli/features/doctor/checks/network_checks.py +251 -0
  148. praisonai_code/cli/features/doctor/checks/obs_checks.py +328 -0
  149. praisonai_code/cli/features/doctor/checks/packaging_checks.py +422 -0
  150. praisonai_code/cli/features/doctor/checks/performance_checks.py +235 -0
  151. praisonai_code/cli/features/doctor/checks/permissions_checks.py +259 -0
  152. praisonai_code/cli/features/doctor/checks/runtime_checks.py +650 -0
  153. praisonai_code/cli/features/doctor/checks/runtime_migration_checks.py +220 -0
  154. praisonai_code/cli/features/doctor/checks/selftest_checks.py +322 -0
  155. praisonai_code/cli/features/doctor/checks/serve_checks.py +426 -0
  156. praisonai_code/cli/features/doctor/checks/skills_checks.py +327 -0
  157. praisonai_code/cli/features/doctor/checks/tools_checks.py +371 -0
  158. praisonai_code/cli/features/doctor/engine.py +266 -0
  159. praisonai_code/cli/features/doctor/formatters.py +377 -0
  160. praisonai_code/cli/features/doctor/handler.py +564 -0
  161. praisonai_code/cli/features/doctor/models.py +276 -0
  162. praisonai_code/cli/features/doctor/registry.py +239 -0
  163. praisonai_code/cli/features/endpoints.py +1016 -0
  164. praisonai_code/cli/features/eval.py +559 -0
  165. praisonai_code/cli/features/examples.py +707 -0
  166. praisonai_code/cli/features/external_agents.py +231 -0
  167. praisonai_code/cli/features/fast_context.py +410 -0
  168. praisonai_code/cli/features/file_history.py +320 -0
  169. praisonai_code/cli/features/flow_display.py +566 -0
  170. praisonai_code/cli/features/git_attribution.py +159 -0
  171. praisonai_code/cli/features/git_integration.py +651 -0
  172. praisonai_code/cli/features/guardrail.py +171 -0
  173. praisonai_code/cli/features/handoff.py +252 -0
  174. praisonai_code/cli/features/hooks.py +583 -0
  175. praisonai_code/cli/features/hybrid_workflow.py +391 -0
  176. praisonai_code/cli/features/image.py +384 -0
  177. praisonai_code/cli/features/interactive_core_headless.py +450 -0
  178. praisonai_code/cli/features/interactive_runtime.py +600 -0
  179. praisonai_code/cli/features/interactive_test_harness.py +537 -0
  180. praisonai_code/cli/features/interactive_tools.py +428 -0
  181. praisonai_code/cli/features/interactive_tui.py +603 -0
  182. praisonai_code/cli/features/job_workflow.py +906 -0
  183. praisonai_code/cli/features/jobs.py +632 -0
  184. praisonai_code/cli/features/knowledge.py +531 -0
  185. praisonai_code/cli/features/knowledge_cli.py +438 -0
  186. praisonai_code/cli/features/lite.py +244 -0
  187. praisonai_code/cli/features/logs.py +200 -0
  188. praisonai_code/cli/features/lsp_cli.py +225 -0
  189. praisonai_code/cli/features/lsp_diagnostics.py +185 -0
  190. praisonai_code/cli/features/mcp.py +344 -0
  191. praisonai_code/cli/features/message_queue.py +587 -0
  192. praisonai_code/cli/features/metrics.py +210 -0
  193. praisonai_code/cli/features/migrate.py +1329 -0
  194. praisonai_code/cli/features/migration_flow.py +463 -0
  195. praisonai_code/cli/features/migration_spec.py +276 -0
  196. praisonai_code/cli/features/n8n.py +703 -0
  197. praisonai_code/cli/features/observability.py +293 -0
  198. praisonai_code/cli/features/ollama.py +361 -0
  199. praisonai_code/cli/features/output_modes.py +155 -0
  200. praisonai_code/cli/features/output_style.py +273 -0
  201. praisonai_code/cli/features/package.py +631 -0
  202. praisonai_code/cli/features/performance.py +308 -0
  203. praisonai_code/cli/features/persistence.py +636 -0
  204. praisonai_code/cli/features/profiler/__init__.py +81 -0
  205. praisonai_code/cli/features/profiler/core.py +558 -0
  206. praisonai_code/cli/features/profiler/optimizations.py +652 -0
  207. praisonai_code/cli/features/profiler/suite.py +386 -0
  208. praisonai_code/cli/features/queue/__init__.py +73 -0
  209. praisonai_code/cli/features/queue/manager.py +435 -0
  210. praisonai_code/cli/features/queue/models.py +289 -0
  211. praisonai_code/cli/features/queue/persistence.py +564 -0
  212. praisonai_code/cli/features/queue/scheduler.py +529 -0
  213. praisonai_code/cli/features/queue/worker.py +400 -0
  214. praisonai_code/cli/features/recipe.py +2187 -0
  215. praisonai_code/cli/features/recipe_creator.py +996 -0
  216. praisonai_code/cli/features/recipe_optimizer.py +1364 -0
  217. praisonai_code/cli/features/recipe_prompts.py +226 -0
  218. praisonai_code/cli/features/registry.py +229 -0
  219. praisonai_code/cli/features/repo_map.py +860 -0
  220. praisonai_code/cli/features/router.py +466 -0
  221. praisonai_code/cli/features/safe_shell.py +427 -0
  222. praisonai_code/cli/features/sandbox_cli.py +283 -0
  223. praisonai_code/cli/features/sandbox_executor.py +536 -0
  224. praisonai_code/cli/features/sdk_knowledge.py +500 -0
  225. praisonai_code/cli/features/session.py +222 -0
  226. praisonai_code/cli/features/session_checkpoints.py +208 -0
  227. praisonai_code/cli/features/setup/__init__.py +9 -0
  228. praisonai_code/cli/features/setup/handler.py +355 -0
  229. praisonai_code/cli/features/setup/templates.py +62 -0
  230. praisonai_code/cli/features/skills.py +940 -0
  231. praisonai_code/cli/features/slash_commands.py +692 -0
  232. praisonai_code/cli/features/telemetry.py +179 -0
  233. praisonai_code/cli/features/templates.py +1390 -0
  234. praisonai_code/cli/features/thinking.py +343 -0
  235. praisonai_code/cli/features/todo.py +334 -0
  236. praisonai_code/cli/features/tools.py +680 -0
  237. praisonai_code/cli/features/tui/__init__.py +83 -0
  238. praisonai_code/cli/features/tui/app.py +871 -0
  239. praisonai_code/cli/features/tui/cli.py +580 -0
  240. praisonai_code/cli/features/tui/config.py +150 -0
  241. praisonai_code/cli/features/tui/debug.py +526 -0
  242. praisonai_code/cli/features/tui/events.py +99 -0
  243. praisonai_code/cli/features/tui/mock_provider.py +328 -0
  244. praisonai_code/cli/features/tui/orchestrator.py +652 -0
  245. praisonai_code/cli/features/tui/screens/__init__.py +50 -0
  246. praisonai_code/cli/features/tui/screens/help.py +157 -0
  247. praisonai_code/cli/features/tui/screens/main.py +568 -0
  248. praisonai_code/cli/features/tui/screens/queue.py +174 -0
  249. praisonai_code/cli/features/tui/screens/session.py +124 -0
  250. praisonai_code/cli/features/tui/screens/settings.py +148 -0
  251. praisonai_code/cli/features/tui/session_store.py +198 -0
  252. praisonai_code/cli/features/tui/widgets/__init__.py +56 -0
  253. praisonai_code/cli/features/tui/widgets/chat.py +263 -0
  254. praisonai_code/cli/features/tui/widgets/command_popup.py +258 -0
  255. praisonai_code/cli/features/tui/widgets/composer.py +292 -0
  256. praisonai_code/cli/features/tui/widgets/file_popup.py +207 -0
  257. praisonai_code/cli/features/tui/widgets/queue_panel.py +223 -0
  258. praisonai_code/cli/features/tui/widgets/status.py +181 -0
  259. praisonai_code/cli/features/tui/widgets/tool_panel.py +307 -0
  260. praisonai_code/cli/features/wizard.py +289 -0
  261. praisonai_code/cli/features/workflow.py +802 -0
  262. praisonai_code/cli/features/yaml_utils.py +321 -0
  263. praisonai_code/cli/interactive/__init__.py +48 -0
  264. praisonai_code/cli/interactive/async_tui.py +1218 -0
  265. praisonai_code/cli/interactive/config.py +139 -0
  266. praisonai_code/cli/interactive/core.py +618 -0
  267. praisonai_code/cli/interactive/events.py +131 -0
  268. praisonai_code/cli/interactive/frontends/__init__.py +31 -0
  269. praisonai_code/cli/interactive/frontends/rich_frontend.py +462 -0
  270. praisonai_code/cli/interactive/frontends/textual_frontend.py +157 -0
  271. praisonai_code/cli/interactive/praison_io.py +502 -0
  272. praisonai_code/cli/interactive/repl.py +297 -0
  273. praisonai_code/cli/interactive/split_tui.py +456 -0
  274. praisonai_code/cli/interactive/tui_app.py +457 -0
  275. praisonai_code/cli/langfuse_client.py +360 -0
  276. praisonai_code/cli/main.py +7421 -0
  277. praisonai_code/cli/output/__init__.py +25 -0
  278. praisonai_code/cli/output/console.py +456 -0
  279. praisonai_code/cli/output/event_bridge.py +191 -0
  280. praisonai_code/cli/schedule_cli.py +54 -0
  281. praisonai_code/cli/schema_provider.py +23 -0
  282. praisonai_code/cli/session/__init__.py +16 -0
  283. praisonai_code/cli/session/resume.py +148 -0
  284. praisonai_code/cli/session/unified.py +548 -0
  285. praisonai_code/cli/state/__init__.py +31 -0
  286. praisonai_code/cli/state/identifiers.py +161 -0
  287. praisonai_code/cli/state/project_sessions.py +383 -0
  288. praisonai_code/cli/state/sessions.py +390 -0
  289. praisonai_code/cli/ui/__init__.py +160 -0
  290. praisonai_code/cli/ui/config.py +46 -0
  291. praisonai_code/cli/ui/events.py +61 -0
  292. praisonai_code/cli/ui/mg_backend.py +342 -0
  293. praisonai_code/cli/ui/plain.py +133 -0
  294. praisonai_code/cli/ui/rich_backend.py +162 -0
  295. praisonai_code/cli/unified_schema.py +655 -0
  296. praisonai_code/cli/utils/env_utils.py +126 -0
  297. praisonai_code/cli/utils/project.py +131 -0
  298. praisonai_code/cli_backends/__init__.py +73 -0
  299. praisonai_code/cli_backends/claude.py +373 -0
  300. praisonai_code/cli_backends/registry.py +113 -0
  301. praisonai_code/runtime/__init__.py +36 -0
  302. praisonai_code/runtime/__main__.py +81 -0
  303. praisonai_code/runtime/client.py +131 -0
  304. praisonai_code/runtime/descriptor.py +209 -0
  305. praisonai_code/runtime/server.py +356 -0
  306. praisonai_code-0.0.1.dist-info/METADATA +80 -0
  307. praisonai_code-0.0.1.dist-info/RECORD +309 -0
  308. praisonai_code-0.0.1.dist-info/WHEEL +5 -0
  309. 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