praisonai-code 0.0.51__tar.gz → 0.0.52__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.
Files changed (316) hide show
  1. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/PKG-INFO +1 -1
  2. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/__init__.py +1 -1
  3. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/events.py +64 -0
  4. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/frontends/rich_frontend.py +24 -13
  5. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/frontends/textual_frontend.py +28 -9
  6. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code.egg-info/PKG-INFO +1 -1
  7. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/pyproject.toml +1 -1
  8. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/README.md +0 -0
  9. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/__main__.py +0 -0
  10. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_bot_bridge.py +0 -0
  11. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_browser_bridge.py +0 -0
  12. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_framework_availability.py +0 -0
  13. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_logging.py +0 -0
  14. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_mcp_bridge.py +0 -0
  15. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_registry.py +0 -0
  16. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_safe_loader.py +0 -0
  17. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_train_bridge.py +0 -0
  18. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_version.py +0 -0
  19. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/_wrapper_bridge.py +0 -0
  20. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/__init__.py +0 -0
  21. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/_forward_shim.py +0 -0
  22. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/_paths.py +0 -0
  23. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/_warnings.py +0 -0
  24. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/_wrapper_reexport.py +0 -0
  25. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/app.py +0 -0
  26. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/approval_backend.py +0 -0
  27. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/branding.py +0 -0
  28. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/__init__.py +0 -0
  29. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/acp.py +0 -0
  30. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/agent.py +0 -0
  31. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/agents.py +0 -0
  32. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/attach.py +0 -0
  33. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/auth.py +0 -0
  34. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/benchmark.py +0 -0
  35. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/browser_tool.py +0 -0
  36. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/call.py +0 -0
  37. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/chat.py +0 -0
  38. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/checkpoint.py +0 -0
  39. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/code.py +0 -0
  40. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/command.py +0 -0
  41. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/commit.py +0 -0
  42. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/completion.py +0 -0
  43. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/config.py +0 -0
  44. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/daemon.py +0 -0
  45. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/debug.py +0 -0
  46. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/deploy.py +0 -0
  47. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/diag.py +0 -0
  48. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/doctor.py +0 -0
  49. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/endpoints.py +0 -0
  50. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/environment.py +0 -0
  51. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/eval.py +0 -0
  52. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/github.py +0 -0
  53. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/hooks.py +0 -0
  54. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/init.py +0 -0
  55. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/loop.py +0 -0
  56. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/lsp.py +0 -0
  57. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/memory.py +0 -0
  58. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/models.py +0 -0
  59. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/obs.py +0 -0
  60. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/package.py +0 -0
  61. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/paths.py +0 -0
  62. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/permissions.py +0 -0
  63. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/plugins.py +0 -0
  64. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/port.py +0 -0
  65. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/publish.py +0 -0
  66. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/registry.py +0 -0
  67. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/research.py +0 -0
  68. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/retrieval.py +0 -0
  69. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/rules.py +0 -0
  70. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/run.py +0 -0
  71. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/sandbox.py +0 -0
  72. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/serve.py +0 -0
  73. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/session.py +0 -0
  74. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/setup.py +0 -0
  75. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/skills.py +0 -0
  76. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/templates.py +0 -0
  77. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/test.py +0 -0
  78. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/todo.py +0 -0
  79. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/tools.py +0 -0
  80. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/traces.py +0 -0
  81. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/tracker.py +0 -0
  82. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/ui.py +0 -0
  83. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/uninstall.py +0 -0
  84. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/up.py +0 -0
  85. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/upgrade.py +0 -0
  86. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/version.py +0 -0
  87. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/commands/workflow.py +0 -0
  88. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/config_loader.py +0 -0
  89. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/configuration/__init__.py +0 -0
  90. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/configuration/config.schema.json +0 -0
  91. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/configuration/credentials.py +0 -0
  92. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/configuration/loader.py +0 -0
  93. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/configuration/model_resolver.py +0 -0
  94. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/configuration/oauth.py +0 -0
  95. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/configuration/paths.py +0 -0
  96. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/configuration/resolver.py +0 -0
  97. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/configuration/schema.py +0 -0
  98. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/execution/__init__.py +0 -0
  99. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/execution/core.py +0 -0
  100. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/execution/profiler.py +0 -0
  101. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/execution/request.py +0 -0
  102. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/execution/result.py +0 -0
  103. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/fallback_schema.py +0 -0
  104. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/__init__.py +0 -0
  105. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/_approval_bridge.py +0 -0
  106. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/_endpoint_registry.py +0 -0
  107. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/_search_registry.py +0 -0
  108. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/action_orchestrator.py +0 -0
  109. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/agents.py +0 -0
  110. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/at_mentions.py +0 -0
  111. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/audit_cli.py +0 -0
  112. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/auto_memory.py +0 -0
  113. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/auto_mode.py +0 -0
  114. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/autonomy_mode.py +0 -0
  115. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/base.py +0 -0
  116. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/benchmark.py +0 -0
  117. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/capabilities.py +0 -0
  118. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/checkpoints.py +0 -0
  119. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/cli_profiler.py +0 -0
  120. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/code_intelligence.py +0 -0
  121. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/compaction.py +0 -0
  122. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/compare.py +0 -0
  123. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/config_hierarchy.py +0 -0
  124. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/context_manager.py +0 -0
  125. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/cost_tracker.py +0 -0
  126. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/csv_test_runner.py +0 -0
  127. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/custom_definitions.py +0 -0
  128. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/debug.py +0 -0
  129. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/diag.py +0 -0
  130. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/display_jsonl.py +0 -0
  131. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/__init__.py +0 -0
  132. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/__init__.py +0 -0
  133. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/_wrapper_checks.py +0 -0
  134. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/acp_checks.py +0 -0
  135. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/bot_checks.py +0 -0
  136. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/config_checks.py +0 -0
  137. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/db_checks.py +0 -0
  138. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/env_checks.py +0 -0
  139. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/gateway_checks.py +0 -0
  140. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/lsp_checks.py +0 -0
  141. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/mcp_checks.py +0 -0
  142. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/memory_checks.py +0 -0
  143. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/network_checks.py +0 -0
  144. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/obs_checks.py +0 -0
  145. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/packaging_checks.py +0 -0
  146. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/performance_checks.py +0 -0
  147. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/permissions_checks.py +0 -0
  148. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/runtime_checks.py +0 -0
  149. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/runtime_migration_checks.py +0 -0
  150. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/selftest_checks.py +0 -0
  151. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/serve_checks.py +0 -0
  152. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/skills_checks.py +0 -0
  153. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/checks/tools_checks.py +0 -0
  154. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/engine.py +0 -0
  155. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/formatters.py +0 -0
  156. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/handler.py +0 -0
  157. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/models.py +0 -0
  158. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/doctor/registry.py +0 -0
  159. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/endpoints.py +0 -0
  160. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/examples.py +0 -0
  161. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/external_agents.py +0 -0
  162. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/fast_context.py +0 -0
  163. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/file_history.py +0 -0
  164. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/flow_display.py +0 -0
  165. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/git_attribution.py +0 -0
  166. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/git_integration.py +0 -0
  167. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/guardrail.py +0 -0
  168. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/handoff.py +0 -0
  169. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/hooks.py +0 -0
  170. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/hybrid_workflow.py +0 -0
  171. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/image.py +0 -0
  172. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/interactive_core_headless.py +0 -0
  173. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/interactive_runtime.py +0 -0
  174. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/interactive_test_harness.py +0 -0
  175. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/interactive_tools.py +0 -0
  176. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/interactive_tui.py +0 -0
  177. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/job_workflow.py +0 -0
  178. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/jobs.py +0 -0
  179. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/knowledge.py +0 -0
  180. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/knowledge_cli.py +0 -0
  181. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/lite.py +0 -0
  182. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/logs.py +0 -0
  183. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/lsp_cli.py +0 -0
  184. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/lsp_diagnostics.py +0 -0
  185. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/mcp.py +0 -0
  186. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/message_queue.py +0 -0
  187. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/metrics.py +0 -0
  188. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/migrate.py +0 -0
  189. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/migration_flow.py +0 -0
  190. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/migration_spec.py +0 -0
  191. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/n8n.py +0 -0
  192. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/observability.py +0 -0
  193. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/output_modes.py +0 -0
  194. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/output_style.py +0 -0
  195. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/package.py +0 -0
  196. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/performance.py +0 -0
  197. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/profiler/__init__.py +0 -0
  198. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/profiler/core.py +0 -0
  199. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/profiler/optimizations.py +0 -0
  200. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/profiler/suite.py +0 -0
  201. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/queue/__init__.py +0 -0
  202. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/queue/manager.py +0 -0
  203. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/queue/models.py +0 -0
  204. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/queue/persistence.py +0 -0
  205. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/queue/scheduler.py +0 -0
  206. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/queue/worker.py +0 -0
  207. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/recipe_creator.py +0 -0
  208. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/recipe_prompts.py +0 -0
  209. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/registry.py +0 -0
  210. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/repo_map.py +0 -0
  211. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/router.py +0 -0
  212. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/safe_shell.py +0 -0
  213. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/sandbox_executor.py +0 -0
  214. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/sdk_knowledge.py +0 -0
  215. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/self_manage.py +0 -0
  216. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/session.py +0 -0
  217. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/session_checkpoints.py +0 -0
  218. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/setup/__init__.py +0 -0
  219. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/setup/handler.py +0 -0
  220. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/setup/templates.py +0 -0
  221. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/skills.py +0 -0
  222. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/slash_commands.py +0 -0
  223. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/telemetry.py +0 -0
  224. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/thinking.py +0 -0
  225. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/todo.py +0 -0
  226. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tools.py +0 -0
  227. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/__init__.py +0 -0
  228. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/cli.py +0 -0
  229. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/config.py +0 -0
  230. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/debug.py +0 -0
  231. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/events.py +0 -0
  232. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/mock_provider.py +0 -0
  233. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/orchestrator.py +0 -0
  234. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/screens/__init__.py +0 -0
  235. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/screens/help.py +0 -0
  236. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/screens/main.py +0 -0
  237. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/screens/queue.py +0 -0
  238. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/screens/session.py +0 -0
  239. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/screens/settings.py +0 -0
  240. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/session_store.py +0 -0
  241. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/widgets/__init__.py +0 -0
  242. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/widgets/chat.py +0 -0
  243. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/widgets/command_popup.py +0 -0
  244. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/widgets/composer.py +0 -0
  245. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/widgets/file_popup.py +0 -0
  246. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/widgets/queue_panel.py +0 -0
  247. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/widgets/status.py +0 -0
  248. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/tui/widgets/tool_panel.py +0 -0
  249. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/wizard.py +0 -0
  250. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/workflow.py +0 -0
  251. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/features/yaml_utils.py +0 -0
  252. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/help_categories.py +0 -0
  253. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/__init__.py +0 -0
  254. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/async_tui.py +0 -0
  255. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/command_registry.py +0 -0
  256. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/config.py +0 -0
  257. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/core.py +0 -0
  258. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/frontends/__init__.py +0 -0
  259. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/praison_io.py +0 -0
  260. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/repl.py +0 -0
  261. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/split_tui.py +0 -0
  262. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/interactive/tui_app.py +0 -0
  263. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/legacy/__init__.py +0 -0
  264. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/legacy/env_security.py +0 -0
  265. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/legacy/praison_ai.py +0 -0
  266. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/legacy/prompt_dispatch.py +0 -0
  267. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/main.py +0 -0
  268. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/output/__init__.py +0 -0
  269. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/output/console.py +0 -0
  270. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/output/event_bridge.py +0 -0
  271. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/schedule_cli.py +0 -0
  272. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/schema_provider.py +0 -0
  273. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/session/__init__.py +0 -0
  274. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/session/resume.py +0 -0
  275. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/session/unified.py +0 -0
  276. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/state/__init__.py +0 -0
  277. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/state/identifiers.py +0 -0
  278. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/state/project_sessions.py +0 -0
  279. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/state/session_resolver.py +0 -0
  280. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/state/sessions.py +0 -0
  281. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/ui/__init__.py +0 -0
  282. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/ui/config.py +0 -0
  283. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/ui/events.py +0 -0
  284. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/ui/mg_backend.py +0 -0
  285. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/ui/plain.py +0 -0
  286. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/ui/rich_backend.py +0 -0
  287. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/unified_schema.py +0 -0
  288. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/utils/env_utils.py +0 -0
  289. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/utils/project.py +0 -0
  290. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli/utils/stdin.py +0 -0
  291. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli_backends/__init__.py +0 -0
  292. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli_backends/claude.py +0 -0
  293. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/cli_backends/registry.py +0 -0
  294. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/data/__init__.py +0 -0
  295. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/data/fixtures/interactive/multi_agent.csv +0 -0
  296. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/data/fixtures/interactive/refactor.csv +0 -0
  297. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/data/fixtures/interactive/smoke.csv +0 -0
  298. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/data/fixtures/interactive/tools.csv +0 -0
  299. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/llm/__init__.py +0 -0
  300. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/llm/catalogue.py +0 -0
  301. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/llm/config.py +0 -0
  302. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/llm/credentials.py +0 -0
  303. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/llm/env.py +0 -0
  304. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/runtime/__init__.py +0 -0
  305. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/runtime/__main__.py +0 -0
  306. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/runtime/client.py +0 -0
  307. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/runtime/descriptor.py +0 -0
  308. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/runtime/server.py +0 -0
  309. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/tool_registry.py +0 -0
  310. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code/tool_resolver.py +0 -0
  311. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code.egg-info/SOURCES.txt +0 -0
  312. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code.egg-info/dependency_links.txt +0 -0
  313. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code.egg-info/entry_points.txt +0 -0
  314. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code.egg-info/requires.txt +0 -0
  315. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/praisonai_code.egg-info/top_level.txt +0 -0
  316. {praisonai_code-0.0.51 → praisonai_code-0.0.52}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: praisonai-code
3
- Version: 0.0.51
3
+ Version: 0.0.52
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
@@ -12,6 +12,6 @@ the remaining terminal-agent modules, with PEP 562 shims left behind at the
12
12
  old ``praisonai.*`` paths for backward compatibility.
13
13
  """
14
14
 
15
- __version__ = "0.0.51"
15
+ __version__ = "0.0.52"
16
16
 
17
17
  __all__ = ["__version__"]
@@ -114,6 +114,70 @@ class ApprovalRequest:
114
114
  return fnmatch.fnmatch(str(path), path_pattern)
115
115
 
116
116
 
117
+ def derive_permission_pattern(request: "ApprovalRequest", scope: str = "command") -> str:
118
+ """Derive the persisted permission pattern for an approval request.
119
+
120
+ Mirrors the console backend's ``_create_pattern`` so interactive frontends
121
+ and the non-interactive console backend scope grants identically.
122
+
123
+ Args:
124
+ request: The approval request being persisted.
125
+ scope: ``"command"`` (default) derives the *narrowest reasonable*
126
+ pattern so approving a single command does not silently grant
127
+ unrestricted use of a tool. ``"tool"`` is the explicit, clearly
128
+ labelled "allow all uses of this tool" choice that emits the
129
+ blanket ``action_type:*`` pattern.
130
+
131
+ Returns:
132
+ A permission glob pattern. For ``scope="command"`` the result is
133
+ **never** the blanket ``action_type:*``: shell commands are generalised
134
+ to a reusable command-prefix (e.g. ``shell_command:git status *``) via
135
+ the shared core helper, and other tools scope to the concrete
136
+ path/argument, falling back to a literal (single-use) target so the
137
+ rule can only match the exact invocation the user approved.
138
+ """
139
+ action_type = request.action_type
140
+
141
+ # Explicit, clearly-labelled "always allow all uses of this tool" only.
142
+ if scope == "tool":
143
+ return f"{action_type}:*"
144
+
145
+ params = request.parameters or {}
146
+
147
+ # Shell tools: generalise to a reusable command-prefix via the shared core
148
+ # helper so interactive and declarative rules scope identically. Unknown or
149
+ # compound commands stay literal (fail-closed).
150
+ command = params.get("command")
151
+ if isinstance(command, str) and command.strip():
152
+ try:
153
+ from praisonaiagents.permissions import derive_pattern
154
+
155
+ # derive_pattern only generalises bash:/shell: targets, so map the
156
+ # action type onto a shell prefix for derivation, then restore it.
157
+ derived = derive_pattern(f"shell:{command}")
158
+ suffix = derived[len("shell:"):]
159
+ return f"{action_type}:{suffix}"
160
+ except ImportError:
161
+ pass
162
+ except Exception: # pragma: no cover - fail-closed on unexpected errors
163
+ import logging as _logging
164
+ _logging.getLogger(__name__).debug(
165
+ "derive_pattern failed for %r; falling back to literal command",
166
+ command,
167
+ exc_info=True,
168
+ )
169
+ return f"{action_type}:{command}"
170
+
171
+ # Non-shell tools: scope to the concrete path/target when available so the
172
+ # persisted rule matches only that resource, never the whole tool.
173
+ path = params.get("path")
174
+ if isinstance(path, str) and path:
175
+ return f"{action_type}:{path}"
176
+
177
+ # No usable target: match only the bare invocation, never the wildcard.
178
+ return f"{action_type}:"
179
+
180
+
117
181
  @dataclass
118
182
  class ApprovalResponse:
119
183
  """Response to an approval request."""
@@ -17,6 +17,7 @@ from ..events import (
17
17
  ApprovalRequest,
18
18
  ApprovalResponse,
19
19
  ApprovalDecision,
20
+ derive_permission_pattern,
20
21
  )
21
22
 
22
23
  logger = logging.getLogger(__name__)
@@ -163,6 +164,10 @@ class RichFrontend:
163
164
 
164
165
  def _prompt_approval(self, request: ApprovalRequest) -> ApprovalResponse:
165
166
  """Prompt user for approval decision."""
167
+ # Derive the narrowest reasonable pattern so "always allow" defaults to
168
+ # a command-scoped grant, not a blanket ``action_type:*`` whitelist.
169
+ narrow_pattern = derive_permission_pattern(request, scope="command")
170
+ blanket_pattern = derive_permission_pattern(request, scope="tool")
166
171
  try:
167
172
  from rich.console import Console
168
173
  from rich.panel import Panel
@@ -177,23 +182,25 @@ class RichFrontend:
177
182
  ))
178
183
 
179
184
  console.print("[1] Allow once")
180
- console.print("[2] Always allow this pattern")
181
- console.print("[3] Always allow for this session")
182
- console.print("[4] Reject")
185
+ console.print(f"[2] Always allow this command ({narrow_pattern})")
186
+ console.print(f"[3] Always allow this command for this session ({narrow_pattern})")
187
+ console.print(f"[4] Always allow ALL uses of {request.tool_name} ({blanket_pattern})")
188
+ console.print("[5] Reject")
183
189
 
184
190
  except ImportError:
185
- print(f"\n=== Approval Required ===")
191
+ print("\n=== Approval Required ===")
186
192
  print(f"Description: {request.description}")
187
193
  print(f"Tool: {request.tool_name}")
188
194
  print(f"Action: {request.action_type}")
189
195
  print("[1] Allow once")
190
- print("[2] Always allow this pattern")
191
- print("[3] Always allow for this session")
192
- print("[4] Reject")
196
+ print(f"[2] Always allow this command ({narrow_pattern})")
197
+ print(f"[3] Always allow this command for this session ({narrow_pattern})")
198
+ print(f"[4] Always allow ALL uses of {request.tool_name} ({blanket_pattern})")
199
+ print("[5] Reject")
193
200
 
194
201
  while True:
195
202
  try:
196
- choice = input("\nChoice [1-4]: ").strip()
203
+ choice = input("\nChoice [1-5]: ").strip()
197
204
 
198
205
  if choice == "1":
199
206
  return ApprovalResponse(
@@ -201,26 +208,30 @@ class RichFrontend:
201
208
  decision=ApprovalDecision.ONCE
202
209
  )
203
210
  elif choice == "2":
204
- pattern = f"{request.action_type}:*"
205
211
  return ApprovalResponse(
206
212
  request_id=request.request_id,
207
213
  decision=ApprovalDecision.ALWAYS,
208
- remember_pattern=pattern
214
+ remember_pattern=narrow_pattern
209
215
  )
210
216
  elif choice == "3":
211
- pattern = f"{request.action_type}:*"
212
217
  return ApprovalResponse(
213
218
  request_id=request.request_id,
214
219
  decision=ApprovalDecision.ALWAYS_SESSION,
215
- remember_pattern=pattern
220
+ remember_pattern=narrow_pattern
216
221
  )
217
222
  elif choice == "4":
223
+ return ApprovalResponse(
224
+ request_id=request.request_id,
225
+ decision=ApprovalDecision.ALWAYS,
226
+ remember_pattern=blanket_pattern
227
+ )
228
+ elif choice == "5":
218
229
  return ApprovalResponse(
219
230
  request_id=request.request_id,
220
231
  decision=ApprovalDecision.REJECT
221
232
  )
222
233
  else:
223
- print("Invalid choice. Please enter 1-4.")
234
+ print("Invalid choice. Please enter 1-5.")
224
235
  except (EOFError, KeyboardInterrupt):
225
236
  return ApprovalResponse(
226
237
  request_id=request.request_id,
@@ -15,6 +15,7 @@ from ..events import (
15
15
  ApprovalRequest,
16
16
  ApprovalResponse,
17
17
  ApprovalDecision,
18
+ derive_permission_pattern,
18
19
  )
19
20
 
20
21
  logger = logging.getLogger(__name__)
@@ -87,8 +88,9 @@ class ApprovalDialog:
87
88
 
88
89
  This provides the same approval options as the Rich frontend:
89
90
  - Allow once
90
- - Always allow this pattern
91
- - Always allow for this session
91
+ - Always allow this command (narrow, command-scoped pattern)
92
+ - Always allow this command for this session
93
+ - Always allow ALL uses of the tool (explicit blanket pattern)
92
94
  - Reject
93
95
  """
94
96
 
@@ -100,6 +102,10 @@ class ApprovalDialog:
100
102
  """
101
103
  self.request = request
102
104
  self.response: Optional[ApprovalResponse] = None
105
+ # Derive both patterns once so the label shown and the pattern stored
106
+ # for a given decision are guaranteed identical.
107
+ self._narrow_pattern = derive_permission_pattern(request, scope="command")
108
+ self._blanket_pattern = derive_permission_pattern(request, scope="tool")
103
109
 
104
110
  def compose(self):
105
111
  """Compose the dialog widgets (for Textual)."""
@@ -107,15 +113,19 @@ class ApprovalDialog:
107
113
  from textual.containers import Vertical, Horizontal
108
114
  from textual.widgets import Static, Button
109
115
 
116
+ narrow_pattern = self._narrow_pattern
117
+ blanket_pattern = self._blanket_pattern
118
+
110
119
  yield Vertical(
111
- Static(f"[bold]Approval Required[/bold]", id="title"),
120
+ Static("[bold]Approval Required[/bold]", id="title"),
112
121
  Static(f"\n{self.request.description}\n"),
113
122
  Static(f"Tool: {self.request.tool_name}"),
114
123
  Static(f"Action: {self.request.action_type}\n"),
115
124
  Horizontal(
116
125
  Button("Allow Once", id="once", variant="primary"),
117
- Button("Always Allow", id="always", variant="success"),
118
- Button("Session Only", id="session", variant="default"),
126
+ Button(f"Always Allow This Command ({narrow_pattern})", id="always", variant="success"),
127
+ Button(f"Session Only ({narrow_pattern})", id="session", variant="default"),
128
+ Button(f"Always Allow All ({blanket_pattern})", id="always_tool", variant="warning"),
119
129
  Button("Reject", id="reject", variant="error"),
120
130
  id="buttons"
121
131
  ),
@@ -133,8 +143,11 @@ class ApprovalDialog:
133
143
  Returns:
134
144
  ApprovalResponse based on the button pressed.
135
145
  """
136
- pattern = f"{self.request.action_type}:*"
137
-
146
+ # "Always allow" defaults to the narrowest reasonable command-scoped
147
+ # pattern; the blanket ``action_type:*`` grant is a separate, explicit
148
+ # choice so a single benign approval never whitelists an entire tool.
149
+ narrow_pattern = self._narrow_pattern
150
+
138
151
  if button_id == "once":
139
152
  return ApprovalResponse(
140
153
  request_id=self.request.request_id,
@@ -144,13 +157,19 @@ class ApprovalDialog:
144
157
  return ApprovalResponse(
145
158
  request_id=self.request.request_id,
146
159
  decision=ApprovalDecision.ALWAYS,
147
- remember_pattern=pattern
160
+ remember_pattern=narrow_pattern
148
161
  )
149
162
  elif button_id == "session":
150
163
  return ApprovalResponse(
151
164
  request_id=self.request.request_id,
152
165
  decision=ApprovalDecision.ALWAYS_SESSION,
153
- remember_pattern=pattern
166
+ remember_pattern=narrow_pattern
167
+ )
168
+ elif button_id == "always_tool":
169
+ return ApprovalResponse(
170
+ request_id=self.request.request_id,
171
+ decision=ApprovalDecision.ALWAYS,
172
+ remember_pattern=self._blanket_pattern
154
173
  )
155
174
  else: # reject
156
175
  return ApprovalResponse(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: praisonai-code
3
- Version: 0.0.51
3
+ Version: 0.0.52
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "praisonai-code"
3
- version = "0.0.51"
3
+ version = "0.0.52"
4
4
  description = "Agentic terminal CLI for PraisonAI — the terminal-native agent (run, chat, code, runtime, cli backends) extracted from the praisonai wrapper."
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}