aru-code 0.58.0__tar.gz → 0.59.0__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.
- {aru_code-0.58.0/aru_code.egg-info → aru_code-0.59.0}/PKG-INFO +10 -7
- {aru_code-0.58.0 → aru_code-0.59.0}/README.md +9 -6
- aru_code-0.59.0/aru/__init__.py +1 -0
- aru_code-0.59.0/aru/cli.py +307 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/display.py +0 -53
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/app.py +5 -5
- {aru_code-0.58.0 → aru_code-0.59.0/aru_code.egg-info}/PKG-INFO +10 -7
- {aru_code-0.58.0 → aru_code-0.59.0}/aru_code.egg-info/SOURCES.txt +0 -3
- {aru_code-0.58.0 → aru_code-0.59.0}/pyproject.toml +1 -1
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_cli.py +0 -190
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_cli_advanced.py +2 -127
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_cli_session.py +1 -32
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_main.py +0 -12
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_app_boot.py +4 -39
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_chat_adversarial.py +125 -73
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_permission_flow.py +6 -1
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_worktree_session_restore.py +1 -1
- aru_code-0.58.0/aru/__init__.py +0 -1
- aru_code-0.58.0/aru/cli.py +0 -1151
- aru_code-0.58.0/aru/completers.py +0 -383
- aru_code-0.58.0/tests/test_cli_completers.py +0 -690
- aru_code-0.58.0/tests/test_cli_run_cli.py +0 -1
- {aru_code-0.58.0 → aru_code-0.59.0}/LICENSE +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/_debug/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/_debug/analyze_trace.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/_debug/loop_tracer.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/agent_factory.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/agents/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/agents/base.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/agents/catalog.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/agents/planner.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/auth.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/cache_patch.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/checkpoints.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/commands.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/config.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/context.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/doom_loop.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/events.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/format/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/format/manager.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/format/runner.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/history_blocks.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/lsp/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/lsp/client.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/lsp/manager.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/lsp/protocol.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/memory/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/memory/extractor.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/memory/loader.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/memory/store.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/permissions.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/plugin_cache.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/plugins/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/plugins/custom_tools.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/plugins/hooks.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/plugins/manager.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/plugins/tool_api.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/providers.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/runner.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/runtime.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/select.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/session.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/sinks.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/streaming.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tool_policy.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/_diff.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/_shared.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/apply_patch.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/apply_patch_prompt.txt +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/ast_tools.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/codebase.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/delegate.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/delegate_prompt.txt +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/file_ops.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/gitignore.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/lsp.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/mcp_client.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/memory_tool.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/plan_mode.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/ranker.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/registry.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/search.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/shell.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/skill.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/tasklist.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/web.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tools/worktree.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/log_bridge.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/notifications.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/sanitize.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/screens/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/screens/choice.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/screens/confirm.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/screens/keymap.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/screens/search.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/screens/session_picker.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/screens/text_input.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/sinks.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/slash_bridge.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/themes.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/ui.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/__init__.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/chat.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/completer.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/context_pane.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/file_link.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/header.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/inline_choice.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/loaded_pane.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/prompt_area.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/prompt_queue.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/status.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/subagent_panel.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/tasklist_panel.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/thinking.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/tui/widgets/tools.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru/ui.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru_code.egg-info/dependency_links.txt +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru_code.egg-info/entry_points.txt +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru_code.egg-info/requires.txt +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/aru_code.egg-info/top_level.txt +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/setup.cfg +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_agents_base.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_agents_md_coverage.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_apply_patch.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_async_tool_permission.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_auth_store.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_cache_patch_metrics.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_cache_patch_stop_reason.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_catalog.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_chat_scrollable.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_checkpoints.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_cli_base.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_cli_new.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_cli_shell.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_codebase.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_confabulation_regression.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_config.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_connect_command.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_context.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_context_pane.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_cwd_awareness.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_delegate.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_doom_loop.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_events_backward_compat.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_events_schema.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_fork_ctx_concurrency.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_format.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_gitignore.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_guardrails_scenarios.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_invoke_skill.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_invoked_skills.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_loaded_pane_path.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_lsp.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_lsp_rename.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_markdown_to_text.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_mcp_client.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_mcp_health.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_memory.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_memory_tool.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_microcompact.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_permission_timeout_suspension.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_permissions.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_plan_mode_refactor.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_plugin_cache.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_plugin_errors.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_plugin_hooks_v2.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_plugins.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_providers.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_ranker.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_reasoning.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_runner_interrupt.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_runner_recovery.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_runtime.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_select.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_session_free_cost.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_skill_disallowed_tools.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_status_breakdown.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_status_cost.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_streaming_sink.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_subagent_tool_events.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tasklist.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_thread_tool_timeout.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tool_policy.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_truncation_marker.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_bindings.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_bus_flow.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_chat.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_completer.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_completer_dynamic.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_connect_wiring.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_copy.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_error_display.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_file_link.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_input_behaviour.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_layer12_recovery.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_layer13_recovery.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_mention_expand.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_modals.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_mode_cycle.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_native_selection.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_plan_task_render.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_prompt_queue.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_shell_bang.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_sidebar_toggle.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_slash_bridge.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_slash_model.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_snapshot_smoke.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_subagent_panel.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_theme.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_thinking_and_boot.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_tui_widgets_visual.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_ui_adapter.py +0 -0
- {aru_code-0.58.0 → aru_code-0.59.0}/tests/test_worktree.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aru-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.59.0
|
|
4
4
|
Summary: A Claude Code clone built with Agno agents
|
|
5
5
|
Author-email: Estevao <estevaofon@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -116,16 +116,19 @@ Key bindings (TUI):
|
|
|
116
116
|
Local slash commands inside the TUI: `/help`, `/clear`, `/quit`,
|
|
117
117
|
`/plan`. Any other input is sent to the agent.
|
|
118
118
|
|
|
119
|
-
###
|
|
119
|
+
### Non-interactive (one-shot)
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
For scripting and pipes, pass a prompt directly instead of launching the
|
|
122
|
+
TUI:
|
|
122
123
|
|
|
123
124
|
```bash
|
|
124
|
-
aru
|
|
125
|
+
aru "fix the failing test in auth" # one-shot, with tools
|
|
126
|
+
aru --print "explain this module" # text-only, no tools
|
|
127
|
+
echo "summarize TODOs" | aru # piped stdin
|
|
125
128
|
```
|
|
126
129
|
|
|
127
|
-
|
|
128
|
-
only presentation differs.
|
|
130
|
+
One-shot mode shares the same sessions, plugins, permissions, and tools
|
|
131
|
+
as the TUI — only presentation differs.
|
|
129
132
|
|
|
130
133
|
## Usage
|
|
131
134
|
|
|
@@ -706,7 +709,7 @@ Once a plan is stored, every following turn prepends a `<system-reminder>` listi
|
|
|
706
709
|
```
|
|
707
710
|
aru-code/
|
|
708
711
|
├── aru/
|
|
709
|
-
│ ├── cli.py #
|
|
712
|
+
│ ├── cli.py # Argument parsing, one-shot execution, and entry point
|
|
710
713
|
│ ├── agent_factory.py # Single factory — builds Agno Agents from catalog specs
|
|
711
714
|
│ ├── commands.py # Slash commands, help display, shell execution
|
|
712
715
|
│ ├── completers.py # Input completions, paste detection, @file mentions
|
|
@@ -68,16 +68,19 @@ Key bindings (TUI):
|
|
|
68
68
|
Local slash commands inside the TUI: `/help`, `/clear`, `/quit`,
|
|
69
69
|
`/plan`. Any other input is sent to the agent.
|
|
70
70
|
|
|
71
|
-
###
|
|
71
|
+
### Non-interactive (one-shot)
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
For scripting and pipes, pass a prompt directly instead of launching the
|
|
74
|
+
TUI:
|
|
74
75
|
|
|
75
76
|
```bash
|
|
76
|
-
aru
|
|
77
|
+
aru "fix the failing test in auth" # one-shot, with tools
|
|
78
|
+
aru --print "explain this module" # text-only, no tools
|
|
79
|
+
echo "summarize TODOs" | aru # piped stdin
|
|
77
80
|
```
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
only presentation differs.
|
|
82
|
+
One-shot mode shares the same sessions, plugins, permissions, and tools
|
|
83
|
+
as the TUI — only presentation differs.
|
|
81
84
|
|
|
82
85
|
## Usage
|
|
83
86
|
|
|
@@ -658,7 +661,7 @@ Once a plan is stored, every following turn prepends a `<system-reminder>` listi
|
|
|
658
661
|
```
|
|
659
662
|
aru-code/
|
|
660
663
|
├── aru/
|
|
661
|
-
│ ├── cli.py #
|
|
664
|
+
│ ├── cli.py # Argument parsing, one-shot execution, and entry point
|
|
662
665
|
│ ├── agent_factory.py # Single factory — builds Agno Agents from catalog specs
|
|
663
666
|
│ ├── commands.py # Slash commands, help display, shell execution
|
|
664
667
|
│ ├── completers.py # Input completions, paste detection, @file mentions
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.59.0"
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"""Non-interactive CLI for aru - a Claude Code clone.
|
|
2
|
+
|
|
3
|
+
This module is the slim orchestrator: arg parsing, one-shot execution, and the
|
|
4
|
+
entrypoint that launches the Textual TUI. All domain logic lives in dedicated
|
|
5
|
+
modules; public names are re-exported here for backward compatibility.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import io as _io
|
|
12
|
+
import logging as _logging
|
|
13
|
+
import os
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
# ── Re-exports for backward compatibility ─────────────────────────────
|
|
17
|
+
# Tests and external code import these from aru.cli; keep them accessible.
|
|
18
|
+
|
|
19
|
+
from aru.session import ( # noqa: F401
|
|
20
|
+
DEFAULT_MODEL,
|
|
21
|
+
PlanStep,
|
|
22
|
+
Session,
|
|
23
|
+
SessionStore,
|
|
24
|
+
SESSIONS_DIR,
|
|
25
|
+
_generate_session_id,
|
|
26
|
+
parse_plan_steps,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
from aru.display import ( # noqa: F401
|
|
30
|
+
StatusBar,
|
|
31
|
+
StreamingDisplay,
|
|
32
|
+
ToolTracker,
|
|
33
|
+
THINKING_PHRASES,
|
|
34
|
+
TOOL_DISPLAY_NAMES,
|
|
35
|
+
TOOL_PRIMARY_ARG,
|
|
36
|
+
_build_logo_with_shadow,
|
|
37
|
+
_format_tool_label,
|
|
38
|
+
aru_logo,
|
|
39
|
+
console,
|
|
40
|
+
format_duration,
|
|
41
|
+
neon_green,
|
|
42
|
+
shadow_green,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
from aru.commands import ( # noqa: F401
|
|
46
|
+
SLASH_COMMANDS,
|
|
47
|
+
_show_help,
|
|
48
|
+
ask_yes_no,
|
|
49
|
+
run_shell,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
from aru.runner import ( # noqa: F401
|
|
53
|
+
AgentRunResult,
|
|
54
|
+
_MUTATION_TOOLS,
|
|
55
|
+
build_env_context,
|
|
56
|
+
run_agent_capture,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
from aru.agent_factory import ( # noqa: F401
|
|
60
|
+
create_custom_agent_instance,
|
|
61
|
+
create_general_agent,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# ── Platform setup ─────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
if sys.platform == "win32" and not hasattr(sys, "_called_from_test"):
|
|
67
|
+
sys.stdout = _io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
|
68
|
+
sys.stderr = _io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")
|
|
69
|
+
|
|
70
|
+
_logging.getLogger("agno").setLevel(_logging.WARNING)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _restore_worktree_from_session(session) -> str:
|
|
74
|
+
"""Re-enter the worktree persisted on *session* (Tier 3 #2 R11).
|
|
75
|
+
|
|
76
|
+
Called at the top of ``run_tui`` right after the session is bound to
|
|
77
|
+
the runtime context. Three branches:
|
|
78
|
+
|
|
79
|
+
- ``worktree_path`` empty or missing → no-op, returns ``"none"``.
|
|
80
|
+
- ``worktree_path`` set AND directory exists on disk → ``enter_worktree``
|
|
81
|
+
is invoked so ``ctx.cwd`` matches the previous run. Returns
|
|
82
|
+
``"entered"``.
|
|
83
|
+
- ``worktree_path`` set but directory is gone → warn, null the
|
|
84
|
+
session fields, return ``"stale"``.
|
|
85
|
+
|
|
86
|
+
Returns a short outcome label (``"none"``/``"entered"``/``"stale"``/
|
|
87
|
+
``"error"``) so tests can pin the branch chosen without re-parsing
|
|
88
|
+
console output.
|
|
89
|
+
"""
|
|
90
|
+
saved_wt = getattr(session, "worktree_path", None)
|
|
91
|
+
saved_branch = getattr(session, "worktree_branch", None)
|
|
92
|
+
if not saved_wt:
|
|
93
|
+
return "none"
|
|
94
|
+
if os.path.isdir(saved_wt):
|
|
95
|
+
from aru.runtime import enter_worktree as _re_enter
|
|
96
|
+
try:
|
|
97
|
+
_re_enter(saved_wt, saved_branch)
|
|
98
|
+
console.print(
|
|
99
|
+
f"[dim]Resumed inside worktree: {saved_branch} ({saved_wt})[/dim]"
|
|
100
|
+
)
|
|
101
|
+
return "entered"
|
|
102
|
+
except Exception as exc:
|
|
103
|
+
console.print(
|
|
104
|
+
f"[yellow]Could not re-enter worktree {saved_wt}: {exc}[/yellow]"
|
|
105
|
+
)
|
|
106
|
+
return "error"
|
|
107
|
+
console.print(
|
|
108
|
+
f"[yellow]Saved worktree path no longer exists: {saved_wt} — "
|
|
109
|
+
f"using project root[/yellow]"
|
|
110
|
+
)
|
|
111
|
+
session.worktree_path = None
|
|
112
|
+
session.worktree_branch = None
|
|
113
|
+
return "stale"
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _configure_plugin_logger(verbose: bool = False) -> None:
|
|
117
|
+
"""Attach a stderr handler to the ``aru.plugins`` logger.
|
|
118
|
+
|
|
119
|
+
Without this, ``logger.error(...)`` inside ``PluginManager`` (e.g. when a
|
|
120
|
+
subscriber raises) has no handler and disappears silently. Idempotent —
|
|
121
|
+
a marker attribute on the logger prevents double-registration when
|
|
122
|
+
``run_oneshot`` is invoked multiple times in the same process (tests).
|
|
123
|
+
"""
|
|
124
|
+
lg = _logging.getLogger("aru.plugins")
|
|
125
|
+
if getattr(lg, "_aru_handler_attached", False):
|
|
126
|
+
return
|
|
127
|
+
handler = _logging.StreamHandler(sys.stderr)
|
|
128
|
+
handler.setFormatter(
|
|
129
|
+
_logging.Formatter("[aru.plugins] %(levelname)s: %(message)s")
|
|
130
|
+
)
|
|
131
|
+
lg.addHandler(handler)
|
|
132
|
+
lg.setLevel(_logging.DEBUG if verbose else _logging.WARNING)
|
|
133
|
+
lg._aru_handler_attached = True # type: ignore[attr-defined]
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
# ── CLI entrypoint ─────────────────────────────────────────────────────
|
|
137
|
+
|
|
138
|
+
def _list_sessions_and_exit():
|
|
139
|
+
"""Print saved sessions and exit."""
|
|
140
|
+
store = SessionStore()
|
|
141
|
+
sessions = store.list_sessions()
|
|
142
|
+
if not sessions:
|
|
143
|
+
console.print("[dim]No saved sessions.[/dim]")
|
|
144
|
+
return
|
|
145
|
+
console.print("[bold]Recent sessions:[/bold]\n")
|
|
146
|
+
for s in sessions:
|
|
147
|
+
sid = s["session_id"]
|
|
148
|
+
title = s["title"][:50]
|
|
149
|
+
msgs = s["messages"]
|
|
150
|
+
updated = s["updated_at"]
|
|
151
|
+
model = s["model"]
|
|
152
|
+
console.print(f" [bold cyan]{sid}[/bold cyan] {title} [dim]({msgs} msgs, {model}, {updated})[/dim]")
|
|
153
|
+
console.print(f"\n[dim]Resume with: aru --resume <id>[/dim]")
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
async def run_oneshot(prompt: str, print_only: bool = False, skip_permissions: bool = False):
|
|
157
|
+
"""Run a single prompt non-interactively and exit.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
prompt: The user prompt to execute.
|
|
161
|
+
print_only: If True, run without tools (text-only response).
|
|
162
|
+
skip_permissions: If True, skip all permission checks.
|
|
163
|
+
"""
|
|
164
|
+
from aru.runtime import init_ctx
|
|
165
|
+
from aru.config import load_config
|
|
166
|
+
from aru.cache_patch import apply_cache_patch
|
|
167
|
+
|
|
168
|
+
apply_cache_patch()
|
|
169
|
+
_configure_plugin_logger(verbose=bool(os.environ.get("ARU_VERBOSE")))
|
|
170
|
+
ctx = init_ctx(console=console, skip_permissions=skip_permissions)
|
|
171
|
+
|
|
172
|
+
# E6a: install REPL UI so migrated call sites work in one-shot mode.
|
|
173
|
+
from aru.ui import install_repl_ui_on_ctx
|
|
174
|
+
install_repl_ui_on_ctx(ctx)
|
|
175
|
+
|
|
176
|
+
config = load_config()
|
|
177
|
+
ctx.config = config
|
|
178
|
+
# Populate invoke_skill's dynamic docstring (same as interactive path)
|
|
179
|
+
from aru.tools.skill import _update_invoke_skill_docstring
|
|
180
|
+
_update_invoke_skill_docstring(config.skills)
|
|
181
|
+
session = Session()
|
|
182
|
+
if config.default_model:
|
|
183
|
+
session.model_ref = config.default_model
|
|
184
|
+
|
|
185
|
+
ctx.session = session
|
|
186
|
+
ctx.model_id = session.model_id
|
|
187
|
+
small_ref = config.model_aliases.get("small") if config else None
|
|
188
|
+
if not small_ref:
|
|
189
|
+
from aru.providers import resolve_model_ref
|
|
190
|
+
provider_key, _ = resolve_model_ref(session.model_ref)
|
|
191
|
+
_small_defaults = {
|
|
192
|
+
"anthropic": "anthropic/claude-haiku-4-5",
|
|
193
|
+
"openai": "openai/gpt-4o-mini",
|
|
194
|
+
"groq": "groq/llama-3.1-8b-instant",
|
|
195
|
+
"deepseek": "deepseek/deepseek-chat",
|
|
196
|
+
"ollama": "ollama/llama3.1",
|
|
197
|
+
}
|
|
198
|
+
small_ref = _small_defaults.get(provider_key, session.model_ref)
|
|
199
|
+
ctx.small_model_ref = small_ref
|
|
200
|
+
|
|
201
|
+
extra_instructions = config.get_extra_instructions()
|
|
202
|
+
|
|
203
|
+
if print_only:
|
|
204
|
+
# Text-only mode: no tools, just a direct LLM call
|
|
205
|
+
from agno.agent import Agent
|
|
206
|
+
from aru.providers import create_model
|
|
207
|
+
from aru.agents.base import build_instructions
|
|
208
|
+
|
|
209
|
+
agent = Agent(
|
|
210
|
+
name="Aru",
|
|
211
|
+
model=create_model(session.model_ref, reasoning_override=session.reasoning_override),
|
|
212
|
+
tools=[],
|
|
213
|
+
instructions=build_instructions("general", extra_instructions),
|
|
214
|
+
markdown=True,
|
|
215
|
+
)
|
|
216
|
+
response = await agent.arun(prompt)
|
|
217
|
+
if response and response.content:
|
|
218
|
+
# Print raw text to stdout for piping
|
|
219
|
+
print(response.content)
|
|
220
|
+
else:
|
|
221
|
+
# Full mode with tools
|
|
222
|
+
from aru.runner import build_env_context
|
|
223
|
+
env_ctx = build_env_context(session)
|
|
224
|
+
agent = await create_general_agent(session, config, env_context=env_ctx)
|
|
225
|
+
session.add_message("user", prompt)
|
|
226
|
+
await run_agent_capture(agent, prompt, session)
|
|
227
|
+
|
|
228
|
+
if session.token_summary:
|
|
229
|
+
console.print(f"[dim]{session.token_summary}[/dim]")
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def main():
|
|
233
|
+
"""Entry point for the aru CLI."""
|
|
234
|
+
from dotenv import load_dotenv
|
|
235
|
+
|
|
236
|
+
load_dotenv()
|
|
237
|
+
args = sys.argv[1:]
|
|
238
|
+
skip_permissions = "--dangerously-skip-permissions" in args
|
|
239
|
+
print_only = "--print" in args or "-p" in args
|
|
240
|
+
|
|
241
|
+
if "--list" in args:
|
|
242
|
+
_list_sessions_and_exit()
|
|
243
|
+
return
|
|
244
|
+
|
|
245
|
+
resume_id = None
|
|
246
|
+
if "--resume" in args:
|
|
247
|
+
idx = args.index("--resume")
|
|
248
|
+
if idx + 1 < len(args) and not args[idx + 1].startswith("--"):
|
|
249
|
+
resume_id = args[idx + 1]
|
|
250
|
+
else:
|
|
251
|
+
resume_id = "last"
|
|
252
|
+
|
|
253
|
+
# Collect positional arguments (non-flag, non-flag-value)
|
|
254
|
+
flags_with_value = {"--resume"}
|
|
255
|
+
positional = []
|
|
256
|
+
skip_next = False
|
|
257
|
+
for i, arg in enumerate(args):
|
|
258
|
+
if skip_next:
|
|
259
|
+
skip_next = False
|
|
260
|
+
continue
|
|
261
|
+
if arg.startswith("--") or arg.startswith("-"):
|
|
262
|
+
if arg in flags_with_value:
|
|
263
|
+
skip_next = True
|
|
264
|
+
continue
|
|
265
|
+
positional.append(arg)
|
|
266
|
+
|
|
267
|
+
# Piped stdin: echo "fix bug" | aru
|
|
268
|
+
if not sys.stdin.isatty() and not positional:
|
|
269
|
+
piped_input = sys.stdin.read().strip()
|
|
270
|
+
if piped_input:
|
|
271
|
+
positional = [piped_input]
|
|
272
|
+
|
|
273
|
+
# One-shot mode: aru "fix the bug" or aru --print "explain this"
|
|
274
|
+
if positional:
|
|
275
|
+
prompt = " ".join(positional)
|
|
276
|
+
try:
|
|
277
|
+
asyncio.run(run_oneshot(prompt, print_only=print_only, skip_permissions=skip_permissions))
|
|
278
|
+
except (KeyboardInterrupt, asyncio.CancelledError, SystemExit):
|
|
279
|
+
pass
|
|
280
|
+
except Exception as e:
|
|
281
|
+
from rich.markup import escape
|
|
282
|
+
console.print(f"\n[bold red]Fatal error: {escape(str(e))}[/bold red]")
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
# Interactive mode — the Textual TUI is the only interactive interface.
|
|
286
|
+
# `--repl` / `--tui` are still accepted as no-op flags for backwards compat.
|
|
287
|
+
from aru.tui import run_tui
|
|
288
|
+
try:
|
|
289
|
+
asyncio.run(run_tui(skip_permissions=skip_permissions, resume_id=resume_id))
|
|
290
|
+
except (KeyboardInterrupt, asyncio.CancelledError, SystemExit):
|
|
291
|
+
_graceful_exit()
|
|
292
|
+
except Exception as e:
|
|
293
|
+
from rich.markup import escape
|
|
294
|
+
console.print(f"\n[bold red]Fatal error: {escape(str(e))}[/bold red]")
|
|
295
|
+
_graceful_exit()
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def _graceful_exit():
|
|
299
|
+
"""Save session and show resume hint on exit."""
|
|
300
|
+
try:
|
|
301
|
+
store = SessionStore()
|
|
302
|
+
last = store.load_last()
|
|
303
|
+
if last:
|
|
304
|
+
console.print(f"\n[dim]Session saved: {last.session_id}[/dim]")
|
|
305
|
+
console.print(f"[dim]Resume with:[/dim] [bold cyan]aru --resume {last.session_id}[/bold cyan]")
|
|
306
|
+
except Exception:
|
|
307
|
+
pass
|
|
@@ -9,7 +9,6 @@ import time
|
|
|
9
9
|
from rich.console import Console, ConsoleOptions, RenderResult
|
|
10
10
|
from rich.markdown import Markdown
|
|
11
11
|
from rich.measure import Measurement
|
|
12
|
-
from rich.rule import Rule
|
|
13
12
|
from rich.spinner import Spinner
|
|
14
13
|
from rich.text import Text
|
|
15
14
|
|
|
@@ -88,58 +87,6 @@ def format_duration(seconds: float) -> str:
|
|
|
88
87
|
return f"{secs}s"
|
|
89
88
|
|
|
90
89
|
|
|
91
|
-
def _sanitize_input(text: str) -> str:
|
|
92
|
-
"""Remove lone UTF-16 surrogates that Windows clipboard can introduce."""
|
|
93
|
-
return text.encode("utf-8", errors="replace").decode("utf-8")
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def _render_input_separator() -> None:
|
|
97
|
-
"""Print a green separator line above the input prompt."""
|
|
98
|
-
console.print(Rule(style=f"dim {neon_green}"))
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def _render_home(session, skip_permissions: bool) -> None:
|
|
102
|
-
"""Render a clean home screen inspired by Claude Code."""
|
|
103
|
-
import os
|
|
104
|
-
|
|
105
|
-
from rich.table import Table
|
|
106
|
-
|
|
107
|
-
from aru import __version__
|
|
108
|
-
|
|
109
|
-
logo = _build_logo_with_shadow(aru_logo)
|
|
110
|
-
console.print(logo)
|
|
111
|
-
console.print(
|
|
112
|
-
Text.from_markup(f" [dim]A coding agent powered by OpenSource[/dim] [bold {neon_green}]v{__version__}[/bold {neon_green}]"),
|
|
113
|
-
)
|
|
114
|
-
console.print()
|
|
115
|
-
|
|
116
|
-
cmds = Table(show_header=False, box=None, padding=(0, 2), expand=False)
|
|
117
|
-
cmds.add_column(style="bold cyan", min_width=12)
|
|
118
|
-
cmds.add_column(style="dim")
|
|
119
|
-
cmds.add_row("/help", "Show all commands")
|
|
120
|
-
console.print(cmds)
|
|
121
|
-
console.print()
|
|
122
|
-
|
|
123
|
-
mode_label = "[bold red]🔥 YOLO mode — permissions bypassed[/bold red]" if skip_permissions else "[green]safe mode[/green]"
|
|
124
|
-
console.print(
|
|
125
|
-
Text.from_markup(
|
|
126
|
-
f" [dim]model:[/dim] [bold]{session.model_display}[/bold] [dim]({session.model_id})[/dim]"
|
|
127
|
-
f" [dim]|[/dim] {mode_label}"
|
|
128
|
-
)
|
|
129
|
-
)
|
|
130
|
-
# Prefer ctx.cwd so the "cwd:" line reflects the active worktree (Tier 3 #2).
|
|
131
|
-
# Falls back to os.getcwd() when no ctx is installed (pre-init, tests).
|
|
132
|
-
try:
|
|
133
|
-
from aru.runtime import get_cwd as _get_cwd
|
|
134
|
-
_cwd_display = _get_cwd()
|
|
135
|
-
except Exception:
|
|
136
|
-
_cwd_display = os.getcwd()
|
|
137
|
-
console.print(
|
|
138
|
-
Text.from_markup(f" [dim]cwd:[/dim] {_cwd_display}")
|
|
139
|
-
)
|
|
140
|
-
console.print()
|
|
141
|
-
|
|
142
|
-
|
|
143
90
|
THINKING_PHRASES = [
|
|
144
91
|
"Thinking...",
|
|
145
92
|
"Cooking...",
|
|
@@ -2572,9 +2572,9 @@ async def run_tui(
|
|
|
2572
2572
|
) -> None:
|
|
2573
2573
|
"""Bootstrap Aru in TUI mode and run the Textual App.
|
|
2574
2574
|
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2575
|
+
Performs the full Aru bootstrap: config resolution, custom
|
|
2576
|
+
tools/agents/plugins/MCP loading, formatter wiring, LSP, and
|
|
2577
|
+
session/worktree restoration.
|
|
2578
2578
|
"""
|
|
2579
2579
|
import atexit
|
|
2580
2580
|
import logging as _logging
|
|
@@ -2643,8 +2643,8 @@ async def run_tui(
|
|
|
2643
2643
|
session.model_ref = config.default_model
|
|
2644
2644
|
ctx.session = session
|
|
2645
2645
|
|
|
2646
|
-
#
|
|
2647
|
-
#
|
|
2646
|
+
# Update RuntimeContext with the session's model and resolve the
|
|
2647
|
+
# small-model reference.
|
|
2648
2648
|
try:
|
|
2649
2649
|
from aru.providers import resolve_model_ref
|
|
2650
2650
|
ctx.model_id = session.model_id
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aru-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.59.0
|
|
4
4
|
Summary: A Claude Code clone built with Agno agents
|
|
5
5
|
Author-email: Estevao <estevaofon@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -116,16 +116,19 @@ Key bindings (TUI):
|
|
|
116
116
|
Local slash commands inside the TUI: `/help`, `/clear`, `/quit`,
|
|
117
117
|
`/plan`. Any other input is sent to the agent.
|
|
118
118
|
|
|
119
|
-
###
|
|
119
|
+
### Non-interactive (one-shot)
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
For scripting and pipes, pass a prompt directly instead of launching the
|
|
122
|
+
TUI:
|
|
122
123
|
|
|
123
124
|
```bash
|
|
124
|
-
aru
|
|
125
|
+
aru "fix the failing test in auth" # one-shot, with tools
|
|
126
|
+
aru --print "explain this module" # text-only, no tools
|
|
127
|
+
echo "summarize TODOs" | aru # piped stdin
|
|
125
128
|
```
|
|
126
129
|
|
|
127
|
-
|
|
128
|
-
only presentation differs.
|
|
130
|
+
One-shot mode shares the same sessions, plugins, permissions, and tools
|
|
131
|
+
as the TUI — only presentation differs.
|
|
129
132
|
|
|
130
133
|
## Usage
|
|
131
134
|
|
|
@@ -706,7 +709,7 @@ Once a plan is stored, every following turn prepends a `<system-reminder>` listi
|
|
|
706
709
|
```
|
|
707
710
|
aru-code/
|
|
708
711
|
├── aru/
|
|
709
|
-
│ ├── cli.py #
|
|
712
|
+
│ ├── cli.py # Argument parsing, one-shot execution, and entry point
|
|
710
713
|
│ ├── agent_factory.py # Single factory — builds Agno Agents from catalog specs
|
|
711
714
|
│ ├── commands.py # Slash commands, help display, shell execution
|
|
712
715
|
│ ├── completers.py # Input completions, paste detection, @file mentions
|
|
@@ -8,7 +8,6 @@ aru/cache_patch.py
|
|
|
8
8
|
aru/checkpoints.py
|
|
9
9
|
aru/cli.py
|
|
10
10
|
aru/commands.py
|
|
11
|
-
aru/completers.py
|
|
12
11
|
aru/config.py
|
|
13
12
|
aru/context.py
|
|
14
13
|
aru/display.py
|
|
@@ -122,9 +121,7 @@ tests/test_checkpoints.py
|
|
|
122
121
|
tests/test_cli.py
|
|
123
122
|
tests/test_cli_advanced.py
|
|
124
123
|
tests/test_cli_base.py
|
|
125
|
-
tests/test_cli_completers.py
|
|
126
124
|
tests/test_cli_new.py
|
|
127
|
-
tests/test_cli_run_cli.py
|
|
128
125
|
tests/test_cli_session.py
|
|
129
126
|
tests/test_cli_shell.py
|
|
130
127
|
tests/test_codebase.py
|