superqode 0.2.3__tar.gz → 0.2.5__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.
- {superqode-0.2.3 → superqode-0.2.5}/CHANGELOG.md +25 -0
- {superqode-0.2.3/src/superqode.egg-info → superqode-0.2.5}/PKG-INFO +1 -1
- {superqode-0.2.3 → superqode-0.2.5}/pyproject.toml +1 -1
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/__init__.py +1 -1
- superqode-0.2.5/src/superqode/acp/server.py +544 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/app_main.py +14 -2
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/serve.py +36 -1
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/templates.py +41 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/slash_complete.py +9 -3
- {superqode-0.2.3 → superqode-0.2.5/src/superqode.egg-info}/PKG-INFO +1 -1
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode.egg-info/SOURCES.txt +2 -0
- superqode-0.2.5/tests/test_acp_server.py +380 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tui_smoke.py +13 -9
- {superqode-0.2.3 → superqode-0.2.5}/LICENSE +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/MANIFEST.in +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/README.md +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/README.md +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/byok-acp-team.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/coding.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/deepagents.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/ds4.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/gemma4.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/google-adk.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/local-recursive-dynamic.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/no-tool.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/omnigent-multi-agent.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/openai-agents.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/harnesses/pydanticai.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/local-models-team.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/omnigent-multi-agent.agent.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/examples/simple-team.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/setup.cfg +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/a2a/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/a2a/client.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/a2a/presets.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/a2a/registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/a2a/server.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/a2a/skills.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/a2a/tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/a2a/types.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/a2a/workflows.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/client.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/doctor.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/permission_screen.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/permission_store.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/render.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/session_store.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/slash.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/tool_call_context.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp/types.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/acp_discovery.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/auto_memory.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/command_safety.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/compaction.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/context_manager.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/edit_strategies.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/exec_policy.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/hooks.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/loop.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/loop_guard.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/network_policy.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/output_handler.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/parallel_compare.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/peer_agents.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/plan_mode.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/reminders.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/rubric.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/session_manager.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/structured_output.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/summarization.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/system_prompts.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/terminal_output_limits.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/text_tool_calls.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/tool_args.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/tool_tracking.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent/utility_model.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent_output.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agent_stream.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/acp_registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/client.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/agentpool.phil65.github.io.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/ampcode.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/augmentcode.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/autodev.github.io.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/blackbox.ai.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/bub.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/cagent.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/claude.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/cline.bot.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/codeassistant.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/codex.openai.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/copilot.github.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/crow-ai.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/cursor.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/factory.ai.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/fastagent.ai.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/fount.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/geminicli.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/goose.block.xyz.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/hermes-agent.nousresearch.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/junie.jetbrains.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/kimi.moonshot.cn.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/kiro.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/llmlingagent.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/minioncode.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/mistral-vibe.mistral.ai.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/openclaw.ai.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/opencode.ai.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/openhands.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/pi.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/poolside.ai.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/qoder.com.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/qwenlm.github.io.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/sigit.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/stakpak.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/stdiobus.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/data/vtcode.dev.toml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/discovery.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/free_models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/messaging.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/official_acp.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/persona.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/schema.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/agents/unified.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/app/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/app/constants.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/app/css.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/app/models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/app/suggester.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/app/theme_bridge.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/app/widgets.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/app_enhanced.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/approval.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/atomic.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/auth/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/benchmarks.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/channels/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/channels/config.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/channels/discord.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/channels/service.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/channels/slack.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/channels/telegram.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/claude.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/codex.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/a2a.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/acp.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/agents.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/auth.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/config.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/daemon.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/local.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/providers.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/runtime.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/commands/sessions.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/config/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/config/loader.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/config/schema.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/core/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/danger.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/data/eval_fixtures/ci-dynamic-root-cause.log +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/data/eval_fixtures/ci-root-cause.log +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/data/eval_packs/local_dynamic_workflow_smoke.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/data/eval_packs/local_recursive_smoke.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/data/superqode-template.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/design_system.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/dialogs/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/dialogs/base.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/dialogs/model.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/dialogs/provider.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/dialogs/runtime.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/diff_view.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/enterprise.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/evaluation/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/evaluation/adapters.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/evaluation/behaviors.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/evaluation/engine.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/evaluation/scenarios.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/execution/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/execution/linter.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/execution/modes.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/execution/resolver.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/execution/runner.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/file_explorer.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/file_viewer.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/flash.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/accelerator.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/agent_importer.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/approval_memory.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/backends/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/backends/base.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/backends/deepagents.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/backends/managed.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/backends/pydanticai.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/backends/registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/backends/runtime.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/compiler.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/context_handles.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/diagnostics.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/eval.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/events.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/explain.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/hooks.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/kernel.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/loader.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/mcp_bridge.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/model_policy.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/observability.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/omnigent_importer.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/optimize.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/output.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/permissions.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/sandbox.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/spec.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/store.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/testing.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/wizard.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/workflow.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/harness/workflow_presets.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/headless.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/history.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/airplane.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/bench.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/build.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/code_index.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/data/model-packs/devstral.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/data/model-packs/ds4.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/data/model-packs/gemma4.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/data/model-packs/glm.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/data/model-packs/gpt-oss.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/data/model-packs/minimax.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/data/model-packs/qwen-coder.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/data/model-packs/qwen3.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/data/stack_matrix.yaml +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/doctor.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/engines.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/guardrails.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/hardware.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/inventory.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/labs.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/matrix.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/migrate.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/optimize.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/packs.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/repo.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/servers.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/setup.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/local/smoke.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/logging/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/logging/adapters.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/logging/formatter.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/logging/integration.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/logging/sinks.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/logging/unified_log.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/lsp/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/lsp/client.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/main.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/auth_storage.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/client.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/config.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/elicitation.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/harness_server.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/hf_auth.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/integration.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/oauth.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/oauth_callback.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/sampling.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/search.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/mcp/types.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/memory/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/memory/config.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/memory/providers.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/memory/types.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/notifications.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/permissions/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/permissions/rules.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/plan.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/plugins.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/project_trust.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/_builtin_profiles.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/acp_free_models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/acp_models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/acp_registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/apple_fm.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/catalog.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/connection_profiles.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/credentials.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/dynamic.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/env_introspect.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/free_inference.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/gateway/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/gateway/base.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/gateway/litellm_gateway.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/gateway/openresponses_gateway.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/gateway/synthetic.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/health.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/huggingface/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/huggingface/convert.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/huggingface/downloader.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/huggingface/endpoints.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/huggingface/fetch.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/huggingface/hub.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/huggingface/inference.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/huggingface/transformers_runner.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/live_models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/_mlx_worker.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/base.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/context_probe.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/discovery.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/ds4.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/lmstudio.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/mlx.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/mlx_engine.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/mlx_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/ollama.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/sglang.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/smoke.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/tgi.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/tool_support.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/local/vllm.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/manager.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/model_specs.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/models_dev.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/opencode_models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/converters/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/converters/messages.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/converters/tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/schema/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/schema/models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/streaming/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/streaming/parser.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/tools/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/tools/apply_patch.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/tools/code_interpreter.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/tools/file_search.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/openresponses/tools/mcp_adapter.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/profiles.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/recommendations.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/providers/usage.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/pure_mode.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/py.typed +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/rendering/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/rendering/html_export.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/rendering/markdown.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/rendering/transcript_export.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/adk.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/base.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/builtin.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/claude_agent_sdk.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/codex_sdk.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/errors.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/openai_agents.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/openai_sandbox.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/openai_session.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/pydanticai.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/tool_bridge.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/tool_bridge_openai.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/runtime/tool_bridge_pydanticai.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/safety/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/safety/sandbox.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/safety/warnings.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/sandbox/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/sandbox/backends.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/sandbox/execution.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/sandbox/local_sandbox.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/search_registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/server/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/server/api.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/server/web.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/session/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/session/factory.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/session/persistence.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/session/share_artifacts.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/session/sharing.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/session/switchboard.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/session.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/sidebar.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/skillopt.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/skills.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/stream_view.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/styles/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tool_call.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/agent_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/apply_patch.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/base.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/batch_tool.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/compact_tool.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/context_handle.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/context_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/diagnostics.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/diff_utils.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/display.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/dynamic_workflow.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/edit_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/enhanced_base.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/env_policy.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/file_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/file_tracking.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/harness_agent_session.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/image_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/lsp_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/mcp_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/monty_tool.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/network_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/output_spill.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/peer_agent_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/permissions.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/post_edit.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/question_tool.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/request_permissions_tool.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/search_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/semantic_search.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/shell_session.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/shell_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/skill_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/spawn_harness.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/todo_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/tool_search.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/validation.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tools/web_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tui_integration.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tui_widgets/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tui_widgets/widgets/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tui_widgets/widgets/progress.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/tui_widgets/widgets/tool_display.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/undo_manager.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/utils/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/utils/error_handling.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/utils/fuzzy.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/agent_store.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/agent_switcher.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/animation_manager.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/code_context.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/command_palette.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/connection_status.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/conversation_history.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/diff_indicator.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/enhanced_status_bar.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/enhanced_toast.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/file_browser.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/file_reference.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/leader_key.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/mode_switcher.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/model_picker.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/permission_preview.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/prompt.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/provider_connect.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/pty_shell.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/resizable_sidebar.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/response_changes.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/response_display.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/rewind_overlay.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/rich_tool_display.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/sidebar_panels.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/slash_commands.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/split_view.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/status_bar.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/superqode_display.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/theme_picker.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/thinking.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/thinking_display.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/throbber.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/toast.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/widgets/unified_output.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/__init__.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/artifacts.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/change_summary.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/coordinator.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/diff_tracker.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/git_guard.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/git_snapshot.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/manager.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/snapshot.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/watcher.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode/workspace/worktree.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode.egg-info/dependency_links.txt +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode.egg-info/entry_points.txt +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode.egg-info/requires.txt +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/src/superqode.egg-info/top_level.txt +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_acp_client.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_acp_free_models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_acp_parent_tool_linking.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_acp_permission_store.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_acp_registry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_acp_render.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_acp_session_store.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_acp_slash.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_adaptive_compaction.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_agent_importer.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_agent_loop_harness.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_agent_memory.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_agents_md_compat.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_apply_patch.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_auth.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_bash_spill.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_benchmarks.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_change_summary.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_channels.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_cli_commands.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_cli_connect.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_cli_reference_coverage.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_command_safety.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_commands_runtime.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_compaction.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_config_loader.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_config_runtime.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_connect_setup.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_connection_profiles.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_context_handles.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_context_probe.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_context_remaining.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_create_skill_tool.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_deferred_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_developer_workflow_docs.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_ds4_local_client.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_dynamic_workflow_tool.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_edit_line_number_strip.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_env_introspect.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_execution_resolver.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_final_parity_wave.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_free_models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_agent_session.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_backends.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_examples.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_explain.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_hooks.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_kernel.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_mcp_server.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_model_policy.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_observability.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_output.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_permissions.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_sandbox.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_seesaw_dimensions.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_spec.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_store.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_wizard.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_harness_workflow.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_headless.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_hf_fetch.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_hooks.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_linter_runner.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_litellm_gateway.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_live_models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_airplane.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_build.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_code_index.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_labs.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_migrate.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_model_optimizations.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_packs.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_sandbox.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_search.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_servers.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_setup.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_smoke.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_stack.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_local_tool_support.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_login_api.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_loop_guard.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_managed_harness_backend.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_markdown_render.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_mcp.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_mcp_integration.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_mcp_live.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_mcp_oauth_generalized.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_mcp_tools_runtime.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_mcp_two_way.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_memory_recall.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_mlx_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_model_profiles.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_model_specs.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_monty_tool.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_network_policy.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_ollama_client.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_omnigent_agent_session_smoke.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_omnigent_importer.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_openai_session.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_output_spill.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_parallel_compare.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_peer_agents.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_plugin_hook_wiring.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_plugins.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_policies_and_turndiff.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_post_edit_verify.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_project_trust.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_provider_catalog.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_provider_dynamic.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_provider_models.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_provider_recommendations.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_pure_mode_sessions.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_rate_limit_retry.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_read_tool_limits.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_reasoning_and_budget.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_recursive_eval_packs.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_adk.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_builtin.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_claude_agent_sdk.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_codex_sdk.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_dialog.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_openai_agents.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_openai_events.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_openai_hitl.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_openai_sandbox.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_protocol.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_runtime_pydanticai.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_sandbox_backends.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_sandbox_execution.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_search_roots.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_semantic_search.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_session_switchboard.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_shell_session.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_simple_login.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_simple_query_fastpath.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_skillopt.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_slash_runtime.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_spawn_harness_tool.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_steering_continue_reminders.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_synthetic_gateways.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_terminal_output_limits.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_theme_picker.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_todo_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tool_args_repair.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tool_batch_safety.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tool_bridge.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tool_bridge_openai.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tool_call_repair.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tool_output_pruning.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tool_tracking.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tools.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tui_change_summary.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tui_chat_mode.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tui_exit.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tui_llamacpp_connect.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tui_markdown_cleanup.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tui_mlx_connect.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tui_mounted.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_tui_tool_display.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_version.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_view_image.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_web_server_auth.py +0 -0
- {superqode-0.2.3 → superqode-0.2.5}/tests/test_workspace.py +0 -0
|
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.5] - 2026-07-04
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Harbor / Terminal-Bench compatibility for the ACP agent** - The ACP server now honors Harbor's `HARBOR_ACP_REQUESTED_MODEL` environment variable when resolving the session model and implements ACP `session/set_model`, so `harbor run --agent acp` can drive SuperQode on Terminal-Bench using the benchmark's `--model` flag with no wrapper code.
|
|
15
|
+
- **Harness template selection over ACP** - `SUPERQODE_ACP_SPEC` (and `serve acp --spec`) now accepts `template:<name>` to pin any built-in harness template for a session without a spec file, enabling harness-variant comparisons in benchmark containers.
|
|
16
|
+
- **`benchmark-coding` template** - An autonomous variant of the coding harness for unattended benchmark runs: yolo approvals, and a system stance that never asks the user questions, investigates recoverable state exhaustively (reflog, stashes, backups), always applies a concrete attempt, and verifies before finishing.
|
|
17
|
+
- **ACP Agent Server documentation** - Added the ACP Agent Server guide covering editor setup, harness and model resolution, template selection, and running SuperQode on Terminal-Bench with Harbor, plus `serve acp` CLI reference coverage.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **Release metadata** - Bumped the package version and runtime `__version__` to `0.2.5`.
|
|
22
|
+
|
|
23
|
+
## [0.2.4] - 2026-07-04
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **ACP agent server** - `superqode serve acp` runs SuperQode as an Agent Client Protocol agent over stdio, so ACP clients such as Zed, JetBrains IDEs, and Neovim can drive SuperQode as their coding agent. Each session resolves a HarnessSpec from `--spec`, the session directory's `superqode.local.yaml` / `harness.yaml`, the conventional harness directories, or the built-in coding template; provider/model resolve from flags, `SUPERQODE_ACP_PROVIDER` / `SUPERQODE_ACP_MODEL`, or the spec's `model_policy.primary`. Prompt turns stream harness model deltas, thinking, and tool calls as ACP session updates, harness tool approvals are relayed as ACP permission requests (allow once / always / reject), and `session/cancel` stops the running turn. The initialize response advertises a terminal auth method that runs `superqode local init --repo .` as the setup experience, as required for ACP registry listing.
|
|
28
|
+
- **ACP registry submission assets** - Added `install/acp-registry/superqode/` with the `agent.json` manifest (uvx distribution), monochrome 16×16 icon matching the SuperQode logo, and registry README, ready to copy into a fork of `agentclientprotocol/registry`.
|
|
29
|
+
- **Scalable brand logo** - Added `assets/superqode-logo.svg`, a compact vector version of the SuperQode logo with the brand gradient, for docs, README, and website use.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- **Release metadata** - Bumped the package version and runtime `__version__` to `0.2.4`.
|
|
34
|
+
|
|
10
35
|
## [0.2.3] - 2026-06-24
|
|
11
36
|
|
|
12
37
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superqode
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: SuperQode: harness engineering framework for coding agents, optimized for local and open models
|
|
5
5
|
Author-email: Shashi Jagtap <info@super-agentic.ai>
|
|
6
6
|
Maintainer-email: Shashi Jagtap <info@super-agentic.ai>
|
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Run SuperQode as an ACP agent (the agent side of the Agent Client Protocol).
|
|
3
|
+
|
|
4
|
+
Complements the client in ``acp/client.py``: any ACP client — Zed, JetBrains
|
|
5
|
+
IDEs, Neovim, Devin Desktop — can drive SuperQode as its coding agent over
|
|
6
|
+
stdio JSON-RPC. The agent loop is a HarnessSpec, resolved per session: an
|
|
7
|
+
explicit ``--spec``, the session directory's ``superqode.local.yaml`` or
|
|
8
|
+
``harness.yaml``, a spec discovered under the conventional harness dirs, or
|
|
9
|
+
the built-in coding template.
|
|
10
|
+
|
|
11
|
+
Run it::
|
|
12
|
+
|
|
13
|
+
superqode serve acp # stdio, auto-discovered spec
|
|
14
|
+
superqode serve acp --spec harness.yaml # pin one HarnessSpec
|
|
15
|
+
|
|
16
|
+
Provider/model resolution order: explicit flags → ``SUPERQODE_ACP_PROVIDER``
|
|
17
|
+
/ ``SUPERQODE_ACP_MODEL`` env → the spec's ``model_policy.primary``.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import asyncio
|
|
23
|
+
import contextlib
|
|
24
|
+
import os
|
|
25
|
+
from dataclasses import dataclass, field
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
from typing import Any
|
|
28
|
+
|
|
29
|
+
from acp import (
|
|
30
|
+
PROTOCOL_VERSION,
|
|
31
|
+
InitializeResponse,
|
|
32
|
+
NewSessionResponse,
|
|
33
|
+
PromptResponse,
|
|
34
|
+
SetSessionModelResponse,
|
|
35
|
+
run_agent,
|
|
36
|
+
start_tool_call,
|
|
37
|
+
text_block,
|
|
38
|
+
tool_content,
|
|
39
|
+
update_agent_message_text,
|
|
40
|
+
update_agent_thought_text,
|
|
41
|
+
update_tool_call,
|
|
42
|
+
)
|
|
43
|
+
from acp.exceptions import RequestError
|
|
44
|
+
from acp.schema import (
|
|
45
|
+
AgentCapabilities,
|
|
46
|
+
Implementation,
|
|
47
|
+
PermissionOption,
|
|
48
|
+
PromptCapabilities,
|
|
49
|
+
TerminalAuthMethod,
|
|
50
|
+
ToolCallUpdate,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# Conventional spec files looked up in the session working directory, in order.
|
|
54
|
+
SESSION_SPEC_FILENAMES = ("superqode.local.yaml", "harness.yaml")
|
|
55
|
+
|
|
56
|
+
# Cap tool output relayed to the client; full output stays in the harness store.
|
|
57
|
+
_TOOL_OUTPUT_LIMIT = 2000
|
|
58
|
+
|
|
59
|
+
_STREAM_DONE = object()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _tool_kind(name: str) -> str:
|
|
63
|
+
"""Map a SuperQode tool name onto an ACP ToolKind."""
|
|
64
|
+
lowered = (name or "").lower()
|
|
65
|
+
exact = {
|
|
66
|
+
"read_file": "read",
|
|
67
|
+
"ls": "read",
|
|
68
|
+
"list_dir": "read",
|
|
69
|
+
"get_context_remaining": "read",
|
|
70
|
+
"edit_file": "edit",
|
|
71
|
+
"write_file": "edit",
|
|
72
|
+
"patch": "edit",
|
|
73
|
+
"grep": "search",
|
|
74
|
+
"glob": "search",
|
|
75
|
+
"repo_search": "search",
|
|
76
|
+
"semantic_search": "search",
|
|
77
|
+
"bash": "execute",
|
|
78
|
+
"shell": "execute",
|
|
79
|
+
"web_fetch": "fetch",
|
|
80
|
+
}
|
|
81
|
+
if lowered in exact:
|
|
82
|
+
return exact[lowered]
|
|
83
|
+
for fragment, kind in (
|
|
84
|
+
("read", "read"),
|
|
85
|
+
("edit", "edit"),
|
|
86
|
+
("write", "edit"),
|
|
87
|
+
("patch", "edit"),
|
|
88
|
+
("grep", "search"),
|
|
89
|
+
("search", "search"),
|
|
90
|
+
("glob", "search"),
|
|
91
|
+
("find", "search"),
|
|
92
|
+
("bash", "execute"),
|
|
93
|
+
("shell", "execute"),
|
|
94
|
+
("command", "execute"),
|
|
95
|
+
("fetch", "fetch"),
|
|
96
|
+
):
|
|
97
|
+
if fragment in lowered:
|
|
98
|
+
return kind
|
|
99
|
+
return "other"
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _prompt_to_text(blocks: list[Any] | None) -> str:
|
|
103
|
+
"""Flatten ACP prompt content blocks into one harness prompt string."""
|
|
104
|
+
parts: list[str] = []
|
|
105
|
+
for block in blocks or []:
|
|
106
|
+
block_type = getattr(block, "type", "")
|
|
107
|
+
if block_type == "text":
|
|
108
|
+
parts.append(getattr(block, "text", "") or "")
|
|
109
|
+
elif block_type == "resource":
|
|
110
|
+
resource = getattr(block, "resource", None)
|
|
111
|
+
text = getattr(resource, "text", None)
|
|
112
|
+
if text:
|
|
113
|
+
uri = getattr(resource, "uri", "") or ""
|
|
114
|
+
parts.append(f'<context uri="{uri}">\n{text}\n</context>')
|
|
115
|
+
elif block_type == "resource_link":
|
|
116
|
+
uri = getattr(block, "uri", "") or ""
|
|
117
|
+
name = getattr(block, "name", "") or ""
|
|
118
|
+
parts.append(f"[resource: {name or uri}]")
|
|
119
|
+
return "\n\n".join(part for part in parts if part).strip()
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _clip(text: Any, limit: int = _TOOL_OUTPUT_LIMIT) -> str:
|
|
123
|
+
rendered = str(text or "")
|
|
124
|
+
if len(rendered) <= limit:
|
|
125
|
+
return rendered
|
|
126
|
+
return rendered[:limit] + f"\n… (truncated, {len(rendered)} chars total)"
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class _ToolCallTracker:
|
|
130
|
+
"""Assign stable ACP tool_call ids to sequential harness tool events."""
|
|
131
|
+
|
|
132
|
+
def __init__(self) -> None:
|
|
133
|
+
self._counter = 0
|
|
134
|
+
self._open: dict[str, list[str]] = {}
|
|
135
|
+
|
|
136
|
+
def start(self, name: str) -> str:
|
|
137
|
+
self._counter += 1
|
|
138
|
+
call_id = f"tc-{self._counter}-{name or 'tool'}"
|
|
139
|
+
self._open.setdefault(name, []).append(call_id)
|
|
140
|
+
return call_id
|
|
141
|
+
|
|
142
|
+
def finish(self, name: str) -> str | None:
|
|
143
|
+
stack = self._open.get(name)
|
|
144
|
+
if stack:
|
|
145
|
+
return stack.pop(0)
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def discover_session_spec(cwd: Path, harness_dir: Path | None = None) -> Path | None:
|
|
150
|
+
"""Find the HarnessSpec that should drive an ACP session rooted at ``cwd``."""
|
|
151
|
+
if harness_dir is not None:
|
|
152
|
+
directory = Path(harness_dir).expanduser()
|
|
153
|
+
if directory.is_dir():
|
|
154
|
+
for path in sorted([*directory.glob("*.yaml"), *directory.glob("*.yml")]):
|
|
155
|
+
return path
|
|
156
|
+
for name in SESSION_SPEC_FILENAMES:
|
|
157
|
+
candidate = cwd / name
|
|
158
|
+
if candidate.is_file():
|
|
159
|
+
return candidate
|
|
160
|
+
from superqode.mcp.harness_server import DEFAULT_HARNESS_DIRS
|
|
161
|
+
|
|
162
|
+
for dirname in DEFAULT_HARNESS_DIRS:
|
|
163
|
+
directory = cwd / dirname
|
|
164
|
+
if not directory.is_dir():
|
|
165
|
+
continue
|
|
166
|
+
for path in sorted([*directory.glob("*.yaml"), *directory.glob("*.yml")]):
|
|
167
|
+
return path
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def resolve_provider_model(spec: Any, provider: str = "", model: str = "") -> tuple[str, str]:
|
|
172
|
+
"""Resolve provider/model: explicit args → ACP env vars → Harbor requested model
|
|
173
|
+
→ model_policy.primary."""
|
|
174
|
+
from superqode.providers.model_specs import (
|
|
175
|
+
normalize_model_for_provider,
|
|
176
|
+
normalize_provider_id,
|
|
177
|
+
split_provider_model_ref,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
provider = provider or os.environ.get("SUPERQODE_ACP_PROVIDER", "").strip()
|
|
181
|
+
model = model or os.environ.get("SUPERQODE_ACP_MODEL", "").strip()
|
|
182
|
+
provider = normalize_provider_id(provider)
|
|
183
|
+
if provider:
|
|
184
|
+
model = normalize_model_for_provider(provider, model)
|
|
185
|
+
elif model:
|
|
186
|
+
parsed_model = split_provider_model_ref(model)
|
|
187
|
+
if parsed_model.provider:
|
|
188
|
+
provider, model = parsed_model.provider, parsed_model.model
|
|
189
|
+
|
|
190
|
+
# Harbor's ACP runner exports the benchmark's --model for the agent process;
|
|
191
|
+
# honoring it makes SuperQode work on Terminal-Bench without a wrapper.
|
|
192
|
+
harbor_requested = os.environ.get("HARBOR_ACP_REQUESTED_MODEL", "").strip()
|
|
193
|
+
if (not provider or not model) and harbor_requested:
|
|
194
|
+
parsed_requested = split_provider_model_ref(harbor_requested)
|
|
195
|
+
if parsed_requested.provider:
|
|
196
|
+
provider = provider or parsed_requested.provider
|
|
197
|
+
model = model or parsed_requested.model
|
|
198
|
+
else:
|
|
199
|
+
model = model or harbor_requested
|
|
200
|
+
|
|
201
|
+
primary = getattr(getattr(spec, "model_policy", None), "primary", None)
|
|
202
|
+
if (not provider or not model) and primary:
|
|
203
|
+
parsed_primary = split_provider_model_ref(str(primary))
|
|
204
|
+
if parsed_primary.provider:
|
|
205
|
+
provider = provider or parsed_primary.provider
|
|
206
|
+
model = model or parsed_primary.model
|
|
207
|
+
else:
|
|
208
|
+
model = model or str(primary)
|
|
209
|
+
return provider, model
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
@dataclass
|
|
213
|
+
class _AcpSessionState:
|
|
214
|
+
"""Live state for one ACP session backed by a HarnessSession."""
|
|
215
|
+
|
|
216
|
+
session: Any
|
|
217
|
+
spec: Any
|
|
218
|
+
provider: str
|
|
219
|
+
model: str
|
|
220
|
+
cwd: Path
|
|
221
|
+
cancel_event: asyncio.Event = field(default_factory=asyncio.Event)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class SuperQodeAcpAgent:
|
|
225
|
+
"""ACP agent implementation that runs prompts through a HarnessKernel."""
|
|
226
|
+
|
|
227
|
+
def __init__(
|
|
228
|
+
self,
|
|
229
|
+
*,
|
|
230
|
+
spec_path: Path | None = None,
|
|
231
|
+
harness_dir: Path | None = None,
|
|
232
|
+
provider: str = "",
|
|
233
|
+
model: str = "",
|
|
234
|
+
) -> None:
|
|
235
|
+
self._spec_path = spec_path
|
|
236
|
+
self._harness_dir = harness_dir
|
|
237
|
+
self._provider = provider
|
|
238
|
+
self._model = model
|
|
239
|
+
self._conn: Any | None = None
|
|
240
|
+
self._sessions: dict[str, _AcpSessionState] = {}
|
|
241
|
+
|
|
242
|
+
# -- connection lifecycle -------------------------------------------------
|
|
243
|
+
|
|
244
|
+
def on_connect(self, conn: Any) -> None:
|
|
245
|
+
self._conn = conn
|
|
246
|
+
|
|
247
|
+
async def initialize(
|
|
248
|
+
self,
|
|
249
|
+
protocol_version: int,
|
|
250
|
+
client_capabilities: Any = None,
|
|
251
|
+
client_info: Any = None,
|
|
252
|
+
**kwargs: Any,
|
|
253
|
+
) -> InitializeResponse:
|
|
254
|
+
from superqode import __version__
|
|
255
|
+
|
|
256
|
+
return InitializeResponse(
|
|
257
|
+
protocol_version=min(int(protocol_version), PROTOCOL_VERSION),
|
|
258
|
+
agent_capabilities=AgentCapabilities(
|
|
259
|
+
load_session=False,
|
|
260
|
+
prompt_capabilities=PromptCapabilities(
|
|
261
|
+
audio=False, image=False, embedded_context=True
|
|
262
|
+
),
|
|
263
|
+
),
|
|
264
|
+
agent_info=Implementation(name="superqode", title="SuperQode", version=__version__),
|
|
265
|
+
auth_methods=[
|
|
266
|
+
TerminalAuthMethod(
|
|
267
|
+
type="terminal",
|
|
268
|
+
id="superqode-setup",
|
|
269
|
+
name="Set up SuperQode",
|
|
270
|
+
description=(
|
|
271
|
+
"Detect local hardware, pick a local model, and generate a "
|
|
272
|
+
"starter harness for this project (superqode local init)."
|
|
273
|
+
),
|
|
274
|
+
args=["local", "init", "--repo", "."],
|
|
275
|
+
)
|
|
276
|
+
],
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
async def authenticate(self, method_id: str, **kwargs: Any) -> None:
|
|
280
|
+
# Terminal auth: the client runs `superqode local init --repo .` itself;
|
|
281
|
+
# nothing to complete on the agent side.
|
|
282
|
+
return None
|
|
283
|
+
|
|
284
|
+
# -- sessions ---------------------------------------------------------------
|
|
285
|
+
|
|
286
|
+
async def new_session(
|
|
287
|
+
self,
|
|
288
|
+
cwd: str,
|
|
289
|
+
additional_directories: list[str] | None = None,
|
|
290
|
+
mcp_servers: list[Any] | None = None,
|
|
291
|
+
**kwargs: Any,
|
|
292
|
+
) -> NewSessionResponse:
|
|
293
|
+
from superqode.harness import FileHarnessStore, init_harness
|
|
294
|
+
|
|
295
|
+
working_dir = Path(cwd).expanduser() if cwd else Path.cwd()
|
|
296
|
+
spec = self._load_spec(working_dir)
|
|
297
|
+
provider, model = resolve_provider_model(spec, self._provider, self._model)
|
|
298
|
+
if not provider or not model:
|
|
299
|
+
raise RequestError.invalid_params(
|
|
300
|
+
{
|
|
301
|
+
"reason": (
|
|
302
|
+
"No provider/model resolved for this session. Set "
|
|
303
|
+
"`model_policy.primary` in the harness spec, or set "
|
|
304
|
+
"SUPERQODE_ACP_PROVIDER / SUPERQODE_ACP_MODEL."
|
|
305
|
+
),
|
|
306
|
+
"spec": spec.name,
|
|
307
|
+
}
|
|
308
|
+
)
|
|
309
|
+
storage = Path(spec.context.session_storage)
|
|
310
|
+
if not storage.is_absolute():
|
|
311
|
+
storage = working_dir / storage
|
|
312
|
+
kernel = await init_harness(spec, store=FileHarnessStore(storage))
|
|
313
|
+
session = await kernel.session()
|
|
314
|
+
self._sessions[session.session_id] = _AcpSessionState(
|
|
315
|
+
session=session,
|
|
316
|
+
spec=spec,
|
|
317
|
+
provider=provider,
|
|
318
|
+
model=model,
|
|
319
|
+
cwd=working_dir,
|
|
320
|
+
)
|
|
321
|
+
return NewSessionResponse(session_id=session.session_id)
|
|
322
|
+
|
|
323
|
+
async def close_session(self, session_id: str, **kwargs: Any) -> None:
|
|
324
|
+
self._sessions.pop(session_id, None)
|
|
325
|
+
return None
|
|
326
|
+
|
|
327
|
+
async def set_session_model(
|
|
328
|
+
self, model_id: str, session_id: str, **kwargs: Any
|
|
329
|
+
) -> SetSessionModelResponse:
|
|
330
|
+
"""Switch the session's model; accepts `provider/model` or bare model ids."""
|
|
331
|
+
from superqode.providers.model_specs import split_provider_model_ref
|
|
332
|
+
|
|
333
|
+
state = self._sessions.get(session_id)
|
|
334
|
+
if state is None:
|
|
335
|
+
raise RequestError.invalid_params({"reason": f"Unknown session: {session_id}"})
|
|
336
|
+
parsed = split_provider_model_ref(str(model_id))
|
|
337
|
+
if parsed.provider:
|
|
338
|
+
state.provider = parsed.provider
|
|
339
|
+
state.model = parsed.model
|
|
340
|
+
else:
|
|
341
|
+
state.model = str(model_id)
|
|
342
|
+
return SetSessionModelResponse()
|
|
343
|
+
|
|
344
|
+
async def cancel(self, session_id: str, **kwargs: Any) -> None:
|
|
345
|
+
state = self._sessions.get(session_id)
|
|
346
|
+
if state is not None:
|
|
347
|
+
state.cancel_event.set()
|
|
348
|
+
|
|
349
|
+
# -- prompting ---------------------------------------------------------------
|
|
350
|
+
|
|
351
|
+
async def prompt(
|
|
352
|
+
self,
|
|
353
|
+
prompt: list[Any],
|
|
354
|
+
session_id: str,
|
|
355
|
+
message_id: str | None = None,
|
|
356
|
+
**kwargs: Any,
|
|
357
|
+
) -> PromptResponse:
|
|
358
|
+
state = self._sessions.get(session_id)
|
|
359
|
+
if state is None:
|
|
360
|
+
raise RequestError.invalid_params({"reason": f"Unknown session: {session_id}"})
|
|
361
|
+
text = _prompt_to_text(prompt)
|
|
362
|
+
if not text:
|
|
363
|
+
return PromptResponse(stop_reason="end_turn")
|
|
364
|
+
state.cancel_event = asyncio.Event()
|
|
365
|
+
tracker = _ToolCallTracker()
|
|
366
|
+
try:
|
|
367
|
+
cancelled = await self._stream_turn(state, text, tracker)
|
|
368
|
+
if not cancelled:
|
|
369
|
+
cancelled = await self._resolve_approvals(state, tracker)
|
|
370
|
+
except asyncio.CancelledError:
|
|
371
|
+
raise
|
|
372
|
+
except Exception as exc:
|
|
373
|
+
await self._send_update(
|
|
374
|
+
session_id,
|
|
375
|
+
update_agent_message_text(f"SuperQode harness run failed: {exc}"),
|
|
376
|
+
)
|
|
377
|
+
return PromptResponse(stop_reason="end_turn")
|
|
378
|
+
return PromptResponse(stop_reason="cancelled" if cancelled else "end_turn")
|
|
379
|
+
|
|
380
|
+
async def _stream_turn(
|
|
381
|
+
self, state: _AcpSessionState, text: str, tracker: _ToolCallTracker
|
|
382
|
+
) -> bool:
|
|
383
|
+
"""Stream one harness turn to the client. Returns True when cancelled."""
|
|
384
|
+
stream = state.session.stream(
|
|
385
|
+
text,
|
|
386
|
+
provider=state.provider,
|
|
387
|
+
model=state.model,
|
|
388
|
+
working_directory=state.cwd,
|
|
389
|
+
sandbox_backend=state.spec.execution_policy.sandbox,
|
|
390
|
+
)
|
|
391
|
+
iterator = stream.__aiter__()
|
|
392
|
+
try:
|
|
393
|
+
while True:
|
|
394
|
+
next_task = asyncio.ensure_future(anext(iterator, _STREAM_DONE))
|
|
395
|
+
cancel_task = asyncio.ensure_future(state.cancel_event.wait())
|
|
396
|
+
done, _ = await asyncio.wait(
|
|
397
|
+
{next_task, cancel_task}, return_when=asyncio.FIRST_COMPLETED
|
|
398
|
+
)
|
|
399
|
+
if next_task not in done:
|
|
400
|
+
next_task.cancel()
|
|
401
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
402
|
+
await next_task
|
|
403
|
+
return True
|
|
404
|
+
cancel_task.cancel()
|
|
405
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
406
|
+
await cancel_task
|
|
407
|
+
event = next_task.result()
|
|
408
|
+
if event is _STREAM_DONE:
|
|
409
|
+
return False
|
|
410
|
+
await self._dispatch_event(state, event, tracker)
|
|
411
|
+
finally:
|
|
412
|
+
with contextlib.suppress(Exception):
|
|
413
|
+
await iterator.aclose()
|
|
414
|
+
|
|
415
|
+
async def _dispatch_event(
|
|
416
|
+
self, state: _AcpSessionState, event: Any, tracker: _ToolCallTracker
|
|
417
|
+
) -> None:
|
|
418
|
+
session_id = state.session.session_id
|
|
419
|
+
data = dict(getattr(event, "data", {}) or {})
|
|
420
|
+
event_type = getattr(event, "type", "")
|
|
421
|
+
if event_type in ("delta", "model_delta"):
|
|
422
|
+
text = data.get("text") or ""
|
|
423
|
+
if text:
|
|
424
|
+
await self._send_update(session_id, update_agent_message_text(text))
|
|
425
|
+
elif event_type == "thinking":
|
|
426
|
+
text = data.get("text") or ""
|
|
427
|
+
if text:
|
|
428
|
+
await self._send_update(session_id, update_agent_thought_text(text))
|
|
429
|
+
elif event_type == "tool_call":
|
|
430
|
+
name = str(data.get("tool_name") or "tool")
|
|
431
|
+
call_id = tracker.start(name)
|
|
432
|
+
await self._send_update(
|
|
433
|
+
session_id,
|
|
434
|
+
start_tool_call(
|
|
435
|
+
call_id,
|
|
436
|
+
name,
|
|
437
|
+
kind=_tool_kind(name),
|
|
438
|
+
status="in_progress",
|
|
439
|
+
raw_input=data.get("arguments"),
|
|
440
|
+
),
|
|
441
|
+
)
|
|
442
|
+
elif event_type == "tool_result":
|
|
443
|
+
name = str(data.get("tool_name") or "tool")
|
|
444
|
+
call_id = tracker.finish(name)
|
|
445
|
+
if call_id is None:
|
|
446
|
+
return
|
|
447
|
+
success = data.get("success", True)
|
|
448
|
+
output = data.get("output") if success else (data.get("error") or data.get("output"))
|
|
449
|
+
content = []
|
|
450
|
+
if output:
|
|
451
|
+
content.append(tool_content(text_block(_clip(output))))
|
|
452
|
+
await self._send_update(
|
|
453
|
+
session_id,
|
|
454
|
+
update_tool_call(
|
|
455
|
+
call_id,
|
|
456
|
+
status="completed" if success else "failed",
|
|
457
|
+
content=content or None,
|
|
458
|
+
raw_output=output,
|
|
459
|
+
),
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
async def _resolve_approvals(self, state: _AcpSessionState, tracker: _ToolCallTracker) -> bool:
|
|
463
|
+
"""Relay pending harness approvals as ACP permission requests."""
|
|
464
|
+
session = state.session
|
|
465
|
+
while True:
|
|
466
|
+
pending = session.pending_approvals()
|
|
467
|
+
if not pending:
|
|
468
|
+
return False
|
|
469
|
+
if state.cancel_event.is_set() or self._conn is None:
|
|
470
|
+
return True
|
|
471
|
+
item = dict(pending[0])
|
|
472
|
+
tool_name = str(item.get("tool_name") or "tool")
|
|
473
|
+
call_id = str(item.get("tool_call_id") or tracker.start(tool_name))
|
|
474
|
+
response = await self._conn.request_permission(
|
|
475
|
+
options=[
|
|
476
|
+
PermissionOption(option_id="allow_once", name="Allow once", kind="allow_once"),
|
|
477
|
+
PermissionOption(
|
|
478
|
+
option_id="allow_always", name="Always allow", kind="allow_always"
|
|
479
|
+
),
|
|
480
|
+
PermissionOption(option_id="reject_once", name="Reject", kind="reject_once"),
|
|
481
|
+
],
|
|
482
|
+
session_id=session.session_id,
|
|
483
|
+
tool_call=ToolCallUpdate(
|
|
484
|
+
tool_call_id=call_id,
|
|
485
|
+
title=tool_name,
|
|
486
|
+
kind=_tool_kind(tool_name),
|
|
487
|
+
status="pending",
|
|
488
|
+
raw_input=item.get("arguments"),
|
|
489
|
+
),
|
|
490
|
+
)
|
|
491
|
+
outcome = getattr(response, "outcome", None)
|
|
492
|
+
selected = getattr(outcome, "outcome", "") == "selected"
|
|
493
|
+
option_id = getattr(outcome, "option_id", "")
|
|
494
|
+
if selected and option_id in ("allow_once", "allow_always"):
|
|
495
|
+
result = await session.approve_pending(0, always=option_id == "allow_always")
|
|
496
|
+
elif selected:
|
|
497
|
+
result = await session.reject_pending(0)
|
|
498
|
+
else:
|
|
499
|
+
# Client cancelled the permission prompt: reject and stop the turn.
|
|
500
|
+
await session.reject_pending(0, message="Cancelled from the editor")
|
|
501
|
+
return True
|
|
502
|
+
content = getattr(result, "content", "") or ""
|
|
503
|
+
if content:
|
|
504
|
+
await self._send_update(session.session_id, update_agent_message_text(content))
|
|
505
|
+
|
|
506
|
+
# -- helpers ---------------------------------------------------------------
|
|
507
|
+
|
|
508
|
+
def _load_spec(self, cwd: Path) -> Any:
|
|
509
|
+
from superqode.harness import load_harness_spec
|
|
510
|
+
from superqode.harness.templates import coding_template, get_harness_template
|
|
511
|
+
|
|
512
|
+
explicit = str(self._spec_path or os.environ.get("SUPERQODE_ACP_SPEC", "")).strip()
|
|
513
|
+
if explicit:
|
|
514
|
+
# `template:<name>` selects a built-in template — no spec file needed,
|
|
515
|
+
# which is how benchmark containers pin a harness variant per run.
|
|
516
|
+
if explicit.startswith("template:"):
|
|
517
|
+
return get_harness_template(explicit.removeprefix("template:"))
|
|
518
|
+
return load_harness_spec(Path(explicit).expanduser())
|
|
519
|
+
found = discover_session_spec(cwd, self._harness_dir)
|
|
520
|
+
if found is not None:
|
|
521
|
+
return load_harness_spec(found)
|
|
522
|
+
return coding_template()
|
|
523
|
+
|
|
524
|
+
async def _send_update(self, session_id: str, update: Any) -> None:
|
|
525
|
+
if self._conn is None:
|
|
526
|
+
return
|
|
527
|
+
await self._conn.session_update(session_id=session_id, update=update)
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
async def run_acp_server(
|
|
531
|
+
*,
|
|
532
|
+
spec_path: Path | None = None,
|
|
533
|
+
harness_dir: Path | None = None,
|
|
534
|
+
provider: str = "",
|
|
535
|
+
model: str = "",
|
|
536
|
+
) -> None:
|
|
537
|
+
"""Serve SuperQode as an ACP agent on stdio until the client disconnects."""
|
|
538
|
+
agent = SuperQodeAcpAgent(
|
|
539
|
+
spec_path=spec_path,
|
|
540
|
+
harness_dir=harness_dir,
|
|
541
|
+
provider=provider,
|
|
542
|
+
model=model,
|
|
543
|
+
)
|
|
544
|
+
await run_agent(agent)
|
|
@@ -12238,7 +12238,9 @@ class SuperQodeApp(App):
|
|
|
12238
12238
|
elif step == "provider":
|
|
12239
12239
|
t.append(" Step 3/9 Provider\n", style=f"bold {THEME['cyan']}")
|
|
12240
12240
|
t.append(" Leave blank to keep the template default.\n", style=THEME["muted"])
|
|
12241
|
-
t.append(
|
|
12241
|
+
t.append(
|
|
12242
|
+
" Examples: ollama, lmstudio, mlx, ds4, openai, anthropic\n", style=THEME["text"]
|
|
12243
|
+
)
|
|
12242
12244
|
elif step == "model":
|
|
12243
12245
|
t.append(" Step 4/9 Model\n", style=f"bold {THEME['cyan']}")
|
|
12244
12246
|
t.append(" Leave blank to keep the template model.\n", style=THEME["muted"])
|
|
@@ -25364,7 +25366,17 @@ class SuperQodeApp(App):
|
|
|
25364
25366
|
self._doctor_cmd(subargs, log)
|
|
25365
25367
|
return
|
|
25366
25368
|
|
|
25367
|
-
if sub in {
|
|
25369
|
+
if sub in {
|
|
25370
|
+
"list",
|
|
25371
|
+
"models",
|
|
25372
|
+
"guide",
|
|
25373
|
+
"recommend",
|
|
25374
|
+
"scan-free",
|
|
25375
|
+
"test",
|
|
25376
|
+
"monty",
|
|
25377
|
+
"ds4",
|
|
25378
|
+
"mlx",
|
|
25379
|
+
}:
|
|
25368
25380
|
self._run_cli_group("providers", args, log, "Providers command")
|
|
25369
25381
|
return
|
|
25370
25382
|
|
|
@@ -22,7 +22,7 @@ console = Console()
|
|
|
22
22
|
@click.pass_context
|
|
23
23
|
def serve(ctx: click.Context):
|
|
24
24
|
"""Server commands for IDE and web integration."""
|
|
25
|
-
if ctx.invoked_subcommand in {"api", "harness"}:
|
|
25
|
+
if ctx.invoked_subcommand in {"api", "harness", "acp"}:
|
|
26
26
|
return
|
|
27
27
|
if not require_enterprise("Server integrations"):
|
|
28
28
|
raise SystemExit(1)
|
|
@@ -110,6 +110,41 @@ def serve_harness(
|
|
|
110
110
|
run_server("http" if http else "stdio", host, port, str(harness_dir) if harness_dir else None)
|
|
111
111
|
|
|
112
112
|
|
|
113
|
+
@serve.command("acp")
|
|
114
|
+
@click.option("--spec", "spec_path", type=click.Path(exists=True, path_type=Path), default=None)
|
|
115
|
+
@click.option(
|
|
116
|
+
"--dir", "harness_dir", type=click.Path(file_okay=False, path_type=Path), default=None
|
|
117
|
+
)
|
|
118
|
+
@click.option("--provider", default="", envvar="SUPERQODE_ACP_PROVIDER")
|
|
119
|
+
@click.option("--model", default="", envvar="SUPERQODE_ACP_MODEL")
|
|
120
|
+
def serve_acp(spec_path: Optional[Path], harness_dir: Optional[Path], provider: str, model: str):
|
|
121
|
+
"""Run SuperQode as an ACP agent on stdio (Zed, JetBrains, Neovim, ...).
|
|
122
|
+
|
|
123
|
+
The agent loop is a HarnessSpec: --spec pins one file, otherwise each
|
|
124
|
+
session resolves superqode.local.yaml / harness.yaml in its working
|
|
125
|
+
directory, then the conventional harness dirs, then the coding template.
|
|
126
|
+
"""
|
|
127
|
+
import asyncio
|
|
128
|
+
|
|
129
|
+
from superqode.acp.server import run_acp_server
|
|
130
|
+
|
|
131
|
+
if spec_path and harness_dir:
|
|
132
|
+
raise click.ClickException("Pass either --spec or --dir, not both.")
|
|
133
|
+
# stdout carries JSON-RPC, so any human-facing output must go to stderr.
|
|
134
|
+
click.echo("SuperQode ACP agent listening on stdio", err=True)
|
|
135
|
+
try:
|
|
136
|
+
asyncio.run(
|
|
137
|
+
run_acp_server(
|
|
138
|
+
spec_path=spec_path,
|
|
139
|
+
harness_dir=harness_dir,
|
|
140
|
+
provider=provider,
|
|
141
|
+
model=model,
|
|
142
|
+
)
|
|
143
|
+
)
|
|
144
|
+
except KeyboardInterrupt:
|
|
145
|
+
pass
|
|
146
|
+
|
|
147
|
+
|
|
113
148
|
@serve.command("api")
|
|
114
149
|
@click.option("--host", default="127.0.0.1", show_default=True)
|
|
115
150
|
@click.option("--port", default=8766, show_default=True, type=int)
|