superqode 0.2.2__tar.gz → 0.2.4__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.2 → superqode-0.2.4}/CHANGELOG.md +18 -3
- {superqode-0.2.2/src/superqode.egg-info → superqode-0.2.4}/PKG-INFO +22 -3
- {superqode-0.2.2 → superqode-0.2.4}/README.md +21 -2
- {superqode-0.2.2 → superqode-0.2.4}/pyproject.toml +1 -1
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/__init__.py +1 -1
- superqode-0.2.4/src/superqode/acp/server.py +510 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/app_main.py +37 -6
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/serve.py +36 -1
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/pure_mode.py +1 -6
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/slash_complete.py +9 -3
- {superqode-0.2.2 → superqode-0.2.4/src/superqode.egg-info}/PKG-INFO +22 -3
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode.egg-info/SOURCES.txt +2 -0
- superqode-0.2.4/tests/test_acp_server.py +297 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_kernel.py +5 -3
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tui_smoke.py +55 -9
- {superqode-0.2.2 → superqode-0.2.4}/LICENSE +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/MANIFEST.in +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/README.md +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/byok-acp-team.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/coding.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/deepagents.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/ds4.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/gemma4.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/google-adk.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/local-recursive-dynamic.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/no-tool.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/omnigent-multi-agent.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/openai-agents.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/harnesses/pydanticai.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/local-models-team.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/omnigent-multi-agent.agent.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/examples/simple-team.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/setup.cfg +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/a2a/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/a2a/client.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/a2a/presets.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/a2a/registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/a2a/server.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/a2a/skills.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/a2a/tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/a2a/types.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/a2a/workflows.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/client.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/doctor.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/permission_screen.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/permission_store.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/render.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/session_store.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/slash.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/tool_call_context.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp/types.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/acp_discovery.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/auto_memory.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/command_safety.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/compaction.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/context_manager.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/edit_strategies.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/exec_policy.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/hooks.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/loop.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/loop_guard.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/network_policy.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/output_handler.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/parallel_compare.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/peer_agents.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/plan_mode.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/reminders.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/rubric.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/session_manager.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/structured_output.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/summarization.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/system_prompts.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/terminal_output_limits.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/text_tool_calls.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/tool_args.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/tool_tracking.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent/utility_model.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent_output.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agent_stream.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/acp_registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/client.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/agentpool.phil65.github.io.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/ampcode.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/augmentcode.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/autodev.github.io.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/blackbox.ai.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/bub.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/cagent.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/claude.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/cline.bot.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/codeassistant.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/codex.openai.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/copilot.github.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/crow-ai.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/cursor.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/factory.ai.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/fastagent.ai.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/fount.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/geminicli.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/goose.block.xyz.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/hermes-agent.nousresearch.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/junie.jetbrains.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/kimi.moonshot.cn.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/kiro.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/llmlingagent.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/minioncode.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/mistral-vibe.mistral.ai.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/openclaw.ai.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/opencode.ai.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/openhands.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/pi.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/poolside.ai.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/qoder.com.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/qwenlm.github.io.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/sigit.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/stakpak.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/stdiobus.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/data/vtcode.dev.toml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/discovery.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/free_models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/messaging.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/official_acp.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/persona.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/schema.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/agents/unified.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/app/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/app/constants.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/app/css.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/app/models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/app/suggester.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/app/theme_bridge.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/app/widgets.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/app_enhanced.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/approval.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/atomic.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/auth/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/benchmarks.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/channels/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/channels/config.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/channels/discord.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/channels/service.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/channels/slack.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/channels/telegram.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/claude.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/codex.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/a2a.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/acp.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/agents.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/auth.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/config.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/daemon.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/local.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/providers.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/runtime.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/commands/sessions.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/config/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/config/loader.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/config/schema.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/core/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/danger.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/data/eval_fixtures/ci-dynamic-root-cause.log +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/data/eval_fixtures/ci-root-cause.log +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/data/eval_packs/local_dynamic_workflow_smoke.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/data/eval_packs/local_recursive_smoke.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/data/superqode-template.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/design_system.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/dialogs/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/dialogs/base.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/dialogs/model.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/dialogs/provider.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/dialogs/runtime.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/diff_view.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/enterprise.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/evaluation/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/evaluation/adapters.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/evaluation/behaviors.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/evaluation/engine.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/evaluation/scenarios.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/execution/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/execution/linter.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/execution/modes.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/execution/resolver.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/execution/runner.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/file_explorer.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/file_viewer.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/flash.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/accelerator.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/agent_importer.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/approval_memory.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/backends/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/backends/base.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/backends/deepagents.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/backends/managed.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/backends/pydanticai.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/backends/registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/backends/runtime.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/compiler.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/context_handles.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/diagnostics.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/eval.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/events.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/explain.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/hooks.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/kernel.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/loader.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/mcp_bridge.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/model_policy.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/observability.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/omnigent_importer.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/optimize.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/output.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/permissions.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/sandbox.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/spec.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/store.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/templates.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/testing.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/wizard.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/workflow.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/harness/workflow_presets.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/headless.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/history.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/airplane.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/bench.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/build.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/code_index.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/data/model-packs/devstral.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/data/model-packs/ds4.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/data/model-packs/gemma4.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/data/model-packs/glm.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/data/model-packs/gpt-oss.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/data/model-packs/minimax.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/data/model-packs/qwen-coder.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/data/model-packs/qwen3.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/data/stack_matrix.yaml +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/doctor.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/engines.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/guardrails.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/hardware.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/inventory.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/labs.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/matrix.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/migrate.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/optimize.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/packs.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/repo.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/servers.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/setup.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/local/smoke.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/logging/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/logging/adapters.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/logging/formatter.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/logging/integration.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/logging/sinks.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/logging/unified_log.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/lsp/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/lsp/client.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/main.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/auth_storage.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/client.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/config.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/elicitation.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/harness_server.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/hf_auth.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/integration.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/oauth.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/oauth_callback.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/sampling.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/search.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/mcp/types.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/memory/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/memory/config.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/memory/providers.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/memory/types.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/notifications.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/permissions/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/permissions/rules.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/plan.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/plugins.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/project_trust.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/_builtin_profiles.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/acp_free_models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/acp_models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/acp_registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/apple_fm.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/catalog.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/connection_profiles.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/credentials.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/dynamic.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/env_introspect.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/free_inference.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/gateway/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/gateway/base.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/gateway/litellm_gateway.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/gateway/openresponses_gateway.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/gateway/synthetic.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/health.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/huggingface/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/huggingface/convert.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/huggingface/downloader.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/huggingface/endpoints.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/huggingface/fetch.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/huggingface/hub.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/huggingface/inference.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/huggingface/transformers_runner.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/live_models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/_mlx_worker.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/base.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/context_probe.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/discovery.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/ds4.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/lmstudio.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/mlx.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/mlx_engine.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/mlx_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/ollama.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/sglang.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/smoke.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/tgi.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/tool_support.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/local/vllm.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/manager.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/model_specs.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/models_dev.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/opencode_models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/converters/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/converters/messages.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/converters/tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/schema/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/schema/models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/streaming/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/streaming/parser.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/tools/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/tools/apply_patch.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/tools/code_interpreter.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/tools/file_search.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/openresponses/tools/mcp_adapter.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/profiles.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/recommendations.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/providers/usage.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/py.typed +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/rendering/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/rendering/html_export.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/rendering/markdown.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/rendering/transcript_export.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/adk.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/base.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/builtin.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/claude_agent_sdk.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/codex_sdk.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/errors.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/openai_agents.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/openai_sandbox.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/openai_session.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/pydanticai.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/tool_bridge.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/tool_bridge_openai.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/runtime/tool_bridge_pydanticai.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/safety/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/safety/sandbox.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/safety/warnings.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/sandbox/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/sandbox/backends.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/sandbox/execution.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/sandbox/local_sandbox.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/search_registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/server/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/server/api.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/server/web.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/session/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/session/factory.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/session/persistence.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/session/share_artifacts.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/session/sharing.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/session/switchboard.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/session.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/sidebar.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/skillopt.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/skills.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/stream_view.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/styles/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tool_call.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/agent_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/apply_patch.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/base.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/batch_tool.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/compact_tool.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/context_handle.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/context_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/diagnostics.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/diff_utils.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/display.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/dynamic_workflow.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/edit_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/enhanced_base.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/env_policy.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/file_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/file_tracking.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/harness_agent_session.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/image_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/lsp_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/mcp_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/monty_tool.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/network_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/output_spill.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/peer_agent_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/permissions.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/post_edit.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/question_tool.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/request_permissions_tool.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/search_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/semantic_search.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/shell_session.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/shell_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/skill_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/spawn_harness.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/todo_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/tool_search.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/validation.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tools/web_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tui_integration.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tui_widgets/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tui_widgets/widgets/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tui_widgets/widgets/progress.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/tui_widgets/widgets/tool_display.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/undo_manager.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/utils/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/utils/error_handling.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/utils/fuzzy.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/agent_store.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/agent_switcher.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/animation_manager.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/code_context.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/command_palette.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/connection_status.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/conversation_history.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/diff_indicator.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/enhanced_status_bar.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/enhanced_toast.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/file_browser.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/file_reference.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/leader_key.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/mode_switcher.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/model_picker.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/permission_preview.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/prompt.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/provider_connect.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/pty_shell.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/resizable_sidebar.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/response_changes.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/response_display.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/rewind_overlay.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/rich_tool_display.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/sidebar_panels.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/slash_commands.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/split_view.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/status_bar.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/superqode_display.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/theme_picker.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/thinking.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/thinking_display.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/throbber.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/toast.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/widgets/unified_output.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/__init__.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/artifacts.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/change_summary.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/coordinator.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/diff_tracker.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/git_guard.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/git_snapshot.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/manager.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/snapshot.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/watcher.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode/workspace/worktree.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode.egg-info/dependency_links.txt +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode.egg-info/entry_points.txt +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode.egg-info/requires.txt +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/src/superqode.egg-info/top_level.txt +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_acp_client.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_acp_free_models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_acp_parent_tool_linking.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_acp_permission_store.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_acp_registry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_acp_render.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_acp_session_store.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_acp_slash.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_adaptive_compaction.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_agent_importer.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_agent_loop_harness.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_agent_memory.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_agents_md_compat.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_apply_patch.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_auth.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_bash_spill.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_benchmarks.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_change_summary.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_channels.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_cli_commands.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_cli_connect.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_cli_reference_coverage.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_command_safety.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_commands_runtime.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_compaction.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_config_loader.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_config_runtime.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_connect_setup.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_connection_profiles.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_context_handles.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_context_probe.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_context_remaining.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_create_skill_tool.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_deferred_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_developer_workflow_docs.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_ds4_local_client.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_dynamic_workflow_tool.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_edit_line_number_strip.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_env_introspect.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_execution_resolver.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_final_parity_wave.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_free_models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_agent_session.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_backends.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_examples.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_explain.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_hooks.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_mcp_server.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_model_policy.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_observability.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_output.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_permissions.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_sandbox.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_seesaw_dimensions.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_spec.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_store.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_wizard.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_harness_workflow.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_headless.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_hf_fetch.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_hooks.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_linter_runner.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_litellm_gateway.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_live_models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_airplane.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_build.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_code_index.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_labs.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_migrate.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_model_optimizations.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_packs.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_sandbox.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_search.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_servers.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_setup.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_smoke.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_stack.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_local_tool_support.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_login_api.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_loop_guard.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_managed_harness_backend.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_markdown_render.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_mcp.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_mcp_integration.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_mcp_live.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_mcp_oauth_generalized.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_mcp_tools_runtime.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_mcp_two_way.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_memory_recall.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_mlx_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_model_profiles.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_model_specs.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_monty_tool.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_network_policy.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_ollama_client.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_omnigent_agent_session_smoke.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_omnigent_importer.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_openai_session.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_output_spill.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_parallel_compare.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_peer_agents.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_plugin_hook_wiring.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_plugins.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_policies_and_turndiff.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_post_edit_verify.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_project_trust.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_provider_catalog.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_provider_dynamic.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_provider_models.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_provider_recommendations.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_pure_mode_sessions.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_rate_limit_retry.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_read_tool_limits.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_reasoning_and_budget.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_recursive_eval_packs.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_adk.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_builtin.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_claude_agent_sdk.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_codex_sdk.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_dialog.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_openai_agents.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_openai_events.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_openai_hitl.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_openai_sandbox.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_protocol.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_runtime_pydanticai.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_sandbox_backends.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_sandbox_execution.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_search_roots.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_semantic_search.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_session_switchboard.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_shell_session.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_simple_login.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_simple_query_fastpath.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_skillopt.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_slash_runtime.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_spawn_harness_tool.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_steering_continue_reminders.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_synthetic_gateways.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_terminal_output_limits.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_theme_picker.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_todo_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tool_args_repair.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tool_batch_safety.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tool_bridge.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tool_bridge_openai.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tool_call_repair.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tool_output_pruning.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tool_tracking.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tools.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tui_change_summary.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tui_chat_mode.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tui_exit.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tui_llamacpp_connect.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tui_markdown_cleanup.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tui_mlx_connect.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tui_mounted.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_tui_tool_display.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_version.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_view_image.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_web_server_auth.py +0 -0
- {superqode-0.2.2 → superqode-0.2.4}/tests/test_workspace.py +0 -0
|
@@ -7,24 +7,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
## [0.2.
|
|
10
|
+
## [0.2.4] - 2026-07-04
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **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.
|
|
15
|
+
- **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`.
|
|
16
|
+
- **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.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **Release metadata** - Bumped the package version and runtime `__version__` to `0.2.4`.
|
|
21
|
+
|
|
22
|
+
## [0.2.3] - 2026-06-24
|
|
11
23
|
|
|
12
24
|
### Added
|
|
13
25
|
|
|
14
26
|
- **TUI harness wizard** - Added a step-by-step `:harness wizard` flow for creating starter HarnessSpec files from the TUI, plus `:harness init` / flag shortcuts using the same wizard builder as the CLI.
|
|
15
27
|
- **TUI CLI parity** - Exposed the remaining CLI command surface in the TUI command list and routed unsupported subcommands through the CLI runner so CLI-only workflows can be launched from the TUI.
|
|
28
|
+
- **First harness documentation** - Documented the TUI and CLI wizard path for creating, loading, checking, and running a first HarnessSpec in a few steps.
|
|
16
29
|
|
|
17
30
|
### Fixed
|
|
18
31
|
|
|
19
32
|
- **Smoke script source checkout support** - Made the Omnigent agent-session smoke script import SuperQode reliably when run directly from a checkout.
|
|
20
|
-
- **Harness model routing** - Made `model_policy.primary` override the active TUI connection for harness runs
|
|
33
|
+
- **Harness model routing** - Made `model_policy.primary` override the active TUI connection for harness runs while preserving valid Ollama model tags such as `*-mlx`.
|
|
21
34
|
- **Harness wizard defaults** - Made Enter-through defaults in the TUI wizard create a runnable Qwen local harness with an explicit `ollama/qwen3-coder` model policy.
|
|
35
|
+
- **Harness wizard final prompt** - Treated `yes`/`no` typed on the output-file step as the final load answer so the wizard no longer stores `yes` as a filename and loops back to the output prompt.
|
|
36
|
+
- **Harness wizard output paths** - Picked the next available default output path such as `harness-2.yaml` when `harness.yaml` already exists, preventing default runs from bouncing back to the output prompt.
|
|
22
37
|
- **Harness wizard loading** - Fixed the final “Load this harness now?” step so loaded harnesses remain visible after reconnect/disconnect state changes, and stale `SUPERQODE_HARNESS` paths no longer crash Pure Mode startup.
|
|
23
38
|
- **Harness streaming** - Forwarded builtin harness `model_delta` events through Pure Mode so TUI harness runs no longer report `chunks=0` when the model did stream content.
|
|
24
39
|
|
|
25
40
|
### Changed
|
|
26
41
|
|
|
27
|
-
- **Release metadata** - Bumped the package version and runtime `__version__` to `0.2.
|
|
42
|
+
- **Release metadata** - Bumped the package version and runtime `__version__` to `0.2.3`.
|
|
28
43
|
|
|
29
44
|
## [0.2.0] - 2026-06-23
|
|
30
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superqode
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
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>
|
|
@@ -230,7 +230,7 @@ Inside the TUI, the local-first MVP path is:
|
|
|
230
230
|
| File | Purpose | Created by |
|
|
231
231
|
| --- | --- | --- |
|
|
232
232
|
| `superqode.yaml` | Project configuration: providers, endpoints, MCP, memory, defaults | `superqode config init` or `:init` |
|
|
233
|
-
| `harness.yaml` | Portable agent run contract | `superqode harness init ...` |
|
|
233
|
+
| `harness.yaml` | Portable agent run contract | `:harness wizard`, `superqode harness wizard`, or `superqode harness init ...` |
|
|
234
234
|
| `superqode.local.yaml` | Local-first HarnessSpec generated for this machine | `:local init` or `superqode local init --repo .` |
|
|
235
235
|
| `superqode.airplane.yaml` | Strict no-network HarnessSpec for offline local work | `:local airplane prepare` or `superqode local airplane prepare` |
|
|
236
236
|
|
|
@@ -242,7 +242,26 @@ superqode --print "inspect this repository and suggest the smallest next step"
|
|
|
242
242
|
|
|
243
243
|
### Your First Harness Run
|
|
244
244
|
|
|
245
|
-
A harness is the repeatable contract for how an agent run behaves.
|
|
245
|
+
A harness is the repeatable contract for how an agent run behaves. In the TUI, create and load your first harness without writing YAML:
|
|
246
|
+
|
|
247
|
+
```text
|
|
248
|
+
:connect local
|
|
249
|
+
:harness wizard
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Press Enter through the defaults for a runnable local coding harness, choose an output file, and answer `yes` when asked whether to load it. If `harness.yaml` already exists, the wizard uses the next available path such as `harness-2.yaml`.
|
|
253
|
+
|
|
254
|
+
For the CLI path, start with the interactive wizard or the default coding template:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
cd your-project
|
|
258
|
+
superqode harness wizard
|
|
259
|
+
superqode harness explain --spec harness.yaml
|
|
260
|
+
superqode harness doctor --spec harness.yaml
|
|
261
|
+
superqode harness run --spec harness.yaml --prompt "summarize the architecture"
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Template shortcut:
|
|
246
265
|
|
|
247
266
|
```bash
|
|
248
267
|
cd your-project
|
|
@@ -102,7 +102,7 @@ Inside the TUI, the local-first MVP path is:
|
|
|
102
102
|
| File | Purpose | Created by |
|
|
103
103
|
| --- | --- | --- |
|
|
104
104
|
| `superqode.yaml` | Project configuration: providers, endpoints, MCP, memory, defaults | `superqode config init` or `:init` |
|
|
105
|
-
| `harness.yaml` | Portable agent run contract | `superqode harness init ...` |
|
|
105
|
+
| `harness.yaml` | Portable agent run contract | `:harness wizard`, `superqode harness wizard`, or `superqode harness init ...` |
|
|
106
106
|
| `superqode.local.yaml` | Local-first HarnessSpec generated for this machine | `:local init` or `superqode local init --repo .` |
|
|
107
107
|
| `superqode.airplane.yaml` | Strict no-network HarnessSpec for offline local work | `:local airplane prepare` or `superqode local airplane prepare` |
|
|
108
108
|
|
|
@@ -114,7 +114,26 @@ superqode --print "inspect this repository and suggest the smallest next step"
|
|
|
114
114
|
|
|
115
115
|
### Your First Harness Run
|
|
116
116
|
|
|
117
|
-
A harness is the repeatable contract for how an agent run behaves.
|
|
117
|
+
A harness is the repeatable contract for how an agent run behaves. In the TUI, create and load your first harness without writing YAML:
|
|
118
|
+
|
|
119
|
+
```text
|
|
120
|
+
:connect local
|
|
121
|
+
:harness wizard
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Press Enter through the defaults for a runnable local coding harness, choose an output file, and answer `yes` when asked whether to load it. If `harness.yaml` already exists, the wizard uses the next available path such as `harness-2.yaml`.
|
|
125
|
+
|
|
126
|
+
For the CLI path, start with the interactive wizard or the default coding template:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
cd your-project
|
|
130
|
+
superqode harness wizard
|
|
131
|
+
superqode harness explain --spec harness.yaml
|
|
132
|
+
superqode harness doctor --spec harness.yaml
|
|
133
|
+
superqode harness run --spec harness.yaml --prompt "summarize the architecture"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Template shortcut:
|
|
118
137
|
|
|
119
138
|
```bash
|
|
120
139
|
cd your-project
|
|
@@ -0,0 +1,510 @@
|
|
|
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
|
+
run_agent,
|
|
35
|
+
start_tool_call,
|
|
36
|
+
text_block,
|
|
37
|
+
tool_content,
|
|
38
|
+
update_agent_message_text,
|
|
39
|
+
update_agent_thought_text,
|
|
40
|
+
update_tool_call,
|
|
41
|
+
)
|
|
42
|
+
from acp.exceptions import RequestError
|
|
43
|
+
from acp.schema import (
|
|
44
|
+
AgentCapabilities,
|
|
45
|
+
Implementation,
|
|
46
|
+
PermissionOption,
|
|
47
|
+
PromptCapabilities,
|
|
48
|
+
TerminalAuthMethod,
|
|
49
|
+
ToolCallUpdate,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Conventional spec files looked up in the session working directory, in order.
|
|
53
|
+
SESSION_SPEC_FILENAMES = ("superqode.local.yaml", "harness.yaml")
|
|
54
|
+
|
|
55
|
+
# Cap tool output relayed to the client; full output stays in the harness store.
|
|
56
|
+
_TOOL_OUTPUT_LIMIT = 2000
|
|
57
|
+
|
|
58
|
+
_STREAM_DONE = object()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _tool_kind(name: str) -> str:
|
|
62
|
+
"""Map a SuperQode tool name onto an ACP ToolKind."""
|
|
63
|
+
lowered = (name or "").lower()
|
|
64
|
+
exact = {
|
|
65
|
+
"read_file": "read",
|
|
66
|
+
"ls": "read",
|
|
67
|
+
"list_dir": "read",
|
|
68
|
+
"get_context_remaining": "read",
|
|
69
|
+
"edit_file": "edit",
|
|
70
|
+
"write_file": "edit",
|
|
71
|
+
"patch": "edit",
|
|
72
|
+
"grep": "search",
|
|
73
|
+
"glob": "search",
|
|
74
|
+
"repo_search": "search",
|
|
75
|
+
"semantic_search": "search",
|
|
76
|
+
"bash": "execute",
|
|
77
|
+
"shell": "execute",
|
|
78
|
+
"web_fetch": "fetch",
|
|
79
|
+
}
|
|
80
|
+
if lowered in exact:
|
|
81
|
+
return exact[lowered]
|
|
82
|
+
for fragment, kind in (
|
|
83
|
+
("read", "read"),
|
|
84
|
+
("edit", "edit"),
|
|
85
|
+
("write", "edit"),
|
|
86
|
+
("patch", "edit"),
|
|
87
|
+
("grep", "search"),
|
|
88
|
+
("search", "search"),
|
|
89
|
+
("glob", "search"),
|
|
90
|
+
("find", "search"),
|
|
91
|
+
("bash", "execute"),
|
|
92
|
+
("shell", "execute"),
|
|
93
|
+
("command", "execute"),
|
|
94
|
+
("fetch", "fetch"),
|
|
95
|
+
):
|
|
96
|
+
if fragment in lowered:
|
|
97
|
+
return kind
|
|
98
|
+
return "other"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _prompt_to_text(blocks: list[Any] | None) -> str:
|
|
102
|
+
"""Flatten ACP prompt content blocks into one harness prompt string."""
|
|
103
|
+
parts: list[str] = []
|
|
104
|
+
for block in blocks or []:
|
|
105
|
+
block_type = getattr(block, "type", "")
|
|
106
|
+
if block_type == "text":
|
|
107
|
+
parts.append(getattr(block, "text", "") or "")
|
|
108
|
+
elif block_type == "resource":
|
|
109
|
+
resource = getattr(block, "resource", None)
|
|
110
|
+
text = getattr(resource, "text", None)
|
|
111
|
+
if text:
|
|
112
|
+
uri = getattr(resource, "uri", "") or ""
|
|
113
|
+
parts.append(f'<context uri="{uri}">\n{text}\n</context>')
|
|
114
|
+
elif block_type == "resource_link":
|
|
115
|
+
uri = getattr(block, "uri", "") or ""
|
|
116
|
+
name = getattr(block, "name", "") or ""
|
|
117
|
+
parts.append(f"[resource: {name or uri}]")
|
|
118
|
+
return "\n\n".join(part for part in parts if part).strip()
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _clip(text: Any, limit: int = _TOOL_OUTPUT_LIMIT) -> str:
|
|
122
|
+
rendered = str(text or "")
|
|
123
|
+
if len(rendered) <= limit:
|
|
124
|
+
return rendered
|
|
125
|
+
return rendered[:limit] + f"\n… (truncated, {len(rendered)} chars total)"
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class _ToolCallTracker:
|
|
129
|
+
"""Assign stable ACP tool_call ids to sequential harness tool events."""
|
|
130
|
+
|
|
131
|
+
def __init__(self) -> None:
|
|
132
|
+
self._counter = 0
|
|
133
|
+
self._open: dict[str, list[str]] = {}
|
|
134
|
+
|
|
135
|
+
def start(self, name: str) -> str:
|
|
136
|
+
self._counter += 1
|
|
137
|
+
call_id = f"tc-{self._counter}-{name or 'tool'}"
|
|
138
|
+
self._open.setdefault(name, []).append(call_id)
|
|
139
|
+
return call_id
|
|
140
|
+
|
|
141
|
+
def finish(self, name: str) -> str | None:
|
|
142
|
+
stack = self._open.get(name)
|
|
143
|
+
if stack:
|
|
144
|
+
return stack.pop(0)
|
|
145
|
+
return None
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def discover_session_spec(cwd: Path, harness_dir: Path | None = None) -> Path | None:
|
|
149
|
+
"""Find the HarnessSpec that should drive an ACP session rooted at ``cwd``."""
|
|
150
|
+
if harness_dir is not None:
|
|
151
|
+
directory = Path(harness_dir).expanduser()
|
|
152
|
+
if directory.is_dir():
|
|
153
|
+
for path in sorted([*directory.glob("*.yaml"), *directory.glob("*.yml")]):
|
|
154
|
+
return path
|
|
155
|
+
for name in SESSION_SPEC_FILENAMES:
|
|
156
|
+
candidate = cwd / name
|
|
157
|
+
if candidate.is_file():
|
|
158
|
+
return candidate
|
|
159
|
+
from superqode.mcp.harness_server import DEFAULT_HARNESS_DIRS
|
|
160
|
+
|
|
161
|
+
for dirname in DEFAULT_HARNESS_DIRS:
|
|
162
|
+
directory = cwd / dirname
|
|
163
|
+
if not directory.is_dir():
|
|
164
|
+
continue
|
|
165
|
+
for path in sorted([*directory.glob("*.yaml"), *directory.glob("*.yml")]):
|
|
166
|
+
return path
|
|
167
|
+
return None
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def resolve_provider_model(spec: Any, provider: str = "", model: str = "") -> tuple[str, str]:
|
|
171
|
+
"""Resolve provider/model: explicit args → ACP env vars → model_policy.primary."""
|
|
172
|
+
from superqode.providers.model_specs import (
|
|
173
|
+
normalize_model_for_provider,
|
|
174
|
+
normalize_provider_id,
|
|
175
|
+
split_provider_model_ref,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
provider = provider or os.environ.get("SUPERQODE_ACP_PROVIDER", "").strip()
|
|
179
|
+
model = model or os.environ.get("SUPERQODE_ACP_MODEL", "").strip()
|
|
180
|
+
provider = normalize_provider_id(provider)
|
|
181
|
+
if provider:
|
|
182
|
+
model = normalize_model_for_provider(provider, model)
|
|
183
|
+
elif model:
|
|
184
|
+
parsed_model = split_provider_model_ref(model)
|
|
185
|
+
if parsed_model.provider:
|
|
186
|
+
provider, model = parsed_model.provider, parsed_model.model
|
|
187
|
+
|
|
188
|
+
primary = getattr(getattr(spec, "model_policy", None), "primary", None)
|
|
189
|
+
if (not provider or not model) and primary:
|
|
190
|
+
parsed_primary = split_provider_model_ref(str(primary))
|
|
191
|
+
if parsed_primary.provider:
|
|
192
|
+
provider = provider or parsed_primary.provider
|
|
193
|
+
model = model or parsed_primary.model
|
|
194
|
+
else:
|
|
195
|
+
model = model or str(primary)
|
|
196
|
+
return provider, model
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@dataclass
|
|
200
|
+
class _AcpSessionState:
|
|
201
|
+
"""Live state for one ACP session backed by a HarnessSession."""
|
|
202
|
+
|
|
203
|
+
session: Any
|
|
204
|
+
spec: Any
|
|
205
|
+
provider: str
|
|
206
|
+
model: str
|
|
207
|
+
cwd: Path
|
|
208
|
+
cancel_event: asyncio.Event = field(default_factory=asyncio.Event)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class SuperQodeAcpAgent:
|
|
212
|
+
"""ACP agent implementation that runs prompts through a HarnessKernel."""
|
|
213
|
+
|
|
214
|
+
def __init__(
|
|
215
|
+
self,
|
|
216
|
+
*,
|
|
217
|
+
spec_path: Path | None = None,
|
|
218
|
+
harness_dir: Path | None = None,
|
|
219
|
+
provider: str = "",
|
|
220
|
+
model: str = "",
|
|
221
|
+
) -> None:
|
|
222
|
+
self._spec_path = spec_path
|
|
223
|
+
self._harness_dir = harness_dir
|
|
224
|
+
self._provider = provider
|
|
225
|
+
self._model = model
|
|
226
|
+
self._conn: Any | None = None
|
|
227
|
+
self._sessions: dict[str, _AcpSessionState] = {}
|
|
228
|
+
|
|
229
|
+
# -- connection lifecycle -------------------------------------------------
|
|
230
|
+
|
|
231
|
+
def on_connect(self, conn: Any) -> None:
|
|
232
|
+
self._conn = conn
|
|
233
|
+
|
|
234
|
+
async def initialize(
|
|
235
|
+
self,
|
|
236
|
+
protocol_version: int,
|
|
237
|
+
client_capabilities: Any = None,
|
|
238
|
+
client_info: Any = None,
|
|
239
|
+
**kwargs: Any,
|
|
240
|
+
) -> InitializeResponse:
|
|
241
|
+
from superqode import __version__
|
|
242
|
+
|
|
243
|
+
return InitializeResponse(
|
|
244
|
+
protocol_version=min(int(protocol_version), PROTOCOL_VERSION),
|
|
245
|
+
agent_capabilities=AgentCapabilities(
|
|
246
|
+
load_session=False,
|
|
247
|
+
prompt_capabilities=PromptCapabilities(
|
|
248
|
+
audio=False, image=False, embedded_context=True
|
|
249
|
+
),
|
|
250
|
+
),
|
|
251
|
+
agent_info=Implementation(name="superqode", title="SuperQode", version=__version__),
|
|
252
|
+
auth_methods=[
|
|
253
|
+
TerminalAuthMethod(
|
|
254
|
+
type="terminal",
|
|
255
|
+
id="superqode-setup",
|
|
256
|
+
name="Set up SuperQode",
|
|
257
|
+
description=(
|
|
258
|
+
"Detect local hardware, pick a local model, and generate a "
|
|
259
|
+
"starter harness for this project (superqode local init)."
|
|
260
|
+
),
|
|
261
|
+
args=["local", "init", "--repo", "."],
|
|
262
|
+
)
|
|
263
|
+
],
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
async def authenticate(self, method_id: str, **kwargs: Any) -> None:
|
|
267
|
+
# Terminal auth: the client runs `superqode local init --repo .` itself;
|
|
268
|
+
# nothing to complete on the agent side.
|
|
269
|
+
return None
|
|
270
|
+
|
|
271
|
+
# -- sessions ---------------------------------------------------------------
|
|
272
|
+
|
|
273
|
+
async def new_session(
|
|
274
|
+
self,
|
|
275
|
+
cwd: str,
|
|
276
|
+
additional_directories: list[str] | None = None,
|
|
277
|
+
mcp_servers: list[Any] | None = None,
|
|
278
|
+
**kwargs: Any,
|
|
279
|
+
) -> NewSessionResponse:
|
|
280
|
+
from superqode.harness import FileHarnessStore, init_harness
|
|
281
|
+
|
|
282
|
+
working_dir = Path(cwd).expanduser() if cwd else Path.cwd()
|
|
283
|
+
spec = self._load_spec(working_dir)
|
|
284
|
+
provider, model = resolve_provider_model(spec, self._provider, self._model)
|
|
285
|
+
if not provider or not model:
|
|
286
|
+
raise RequestError.invalid_params(
|
|
287
|
+
{
|
|
288
|
+
"reason": (
|
|
289
|
+
"No provider/model resolved for this session. Set "
|
|
290
|
+
"`model_policy.primary` in the harness spec, or set "
|
|
291
|
+
"SUPERQODE_ACP_PROVIDER / SUPERQODE_ACP_MODEL."
|
|
292
|
+
),
|
|
293
|
+
"spec": spec.name,
|
|
294
|
+
}
|
|
295
|
+
)
|
|
296
|
+
storage = Path(spec.context.session_storage)
|
|
297
|
+
if not storage.is_absolute():
|
|
298
|
+
storage = working_dir / storage
|
|
299
|
+
kernel = await init_harness(spec, store=FileHarnessStore(storage))
|
|
300
|
+
session = await kernel.session()
|
|
301
|
+
self._sessions[session.session_id] = _AcpSessionState(
|
|
302
|
+
session=session,
|
|
303
|
+
spec=spec,
|
|
304
|
+
provider=provider,
|
|
305
|
+
model=model,
|
|
306
|
+
cwd=working_dir,
|
|
307
|
+
)
|
|
308
|
+
return NewSessionResponse(session_id=session.session_id)
|
|
309
|
+
|
|
310
|
+
async def close_session(self, session_id: str, **kwargs: Any) -> None:
|
|
311
|
+
self._sessions.pop(session_id, None)
|
|
312
|
+
return None
|
|
313
|
+
|
|
314
|
+
async def cancel(self, session_id: str, **kwargs: Any) -> None:
|
|
315
|
+
state = self._sessions.get(session_id)
|
|
316
|
+
if state is not None:
|
|
317
|
+
state.cancel_event.set()
|
|
318
|
+
|
|
319
|
+
# -- prompting ---------------------------------------------------------------
|
|
320
|
+
|
|
321
|
+
async def prompt(
|
|
322
|
+
self,
|
|
323
|
+
prompt: list[Any],
|
|
324
|
+
session_id: str,
|
|
325
|
+
message_id: str | None = None,
|
|
326
|
+
**kwargs: Any,
|
|
327
|
+
) -> PromptResponse:
|
|
328
|
+
state = self._sessions.get(session_id)
|
|
329
|
+
if state is None:
|
|
330
|
+
raise RequestError.invalid_params({"reason": f"Unknown session: {session_id}"})
|
|
331
|
+
text = _prompt_to_text(prompt)
|
|
332
|
+
if not text:
|
|
333
|
+
return PromptResponse(stop_reason="end_turn")
|
|
334
|
+
state.cancel_event = asyncio.Event()
|
|
335
|
+
tracker = _ToolCallTracker()
|
|
336
|
+
try:
|
|
337
|
+
cancelled = await self._stream_turn(state, text, tracker)
|
|
338
|
+
if not cancelled:
|
|
339
|
+
cancelled = await self._resolve_approvals(state, tracker)
|
|
340
|
+
except asyncio.CancelledError:
|
|
341
|
+
raise
|
|
342
|
+
except Exception as exc:
|
|
343
|
+
await self._send_update(
|
|
344
|
+
session_id,
|
|
345
|
+
update_agent_message_text(f"SuperQode harness run failed: {exc}"),
|
|
346
|
+
)
|
|
347
|
+
return PromptResponse(stop_reason="end_turn")
|
|
348
|
+
return PromptResponse(stop_reason="cancelled" if cancelled else "end_turn")
|
|
349
|
+
|
|
350
|
+
async def _stream_turn(
|
|
351
|
+
self, state: _AcpSessionState, text: str, tracker: _ToolCallTracker
|
|
352
|
+
) -> bool:
|
|
353
|
+
"""Stream one harness turn to the client. Returns True when cancelled."""
|
|
354
|
+
stream = state.session.stream(
|
|
355
|
+
text,
|
|
356
|
+
provider=state.provider,
|
|
357
|
+
model=state.model,
|
|
358
|
+
working_directory=state.cwd,
|
|
359
|
+
sandbox_backend=state.spec.execution_policy.sandbox,
|
|
360
|
+
)
|
|
361
|
+
iterator = stream.__aiter__()
|
|
362
|
+
try:
|
|
363
|
+
while True:
|
|
364
|
+
next_task = asyncio.ensure_future(anext(iterator, _STREAM_DONE))
|
|
365
|
+
cancel_task = asyncio.ensure_future(state.cancel_event.wait())
|
|
366
|
+
done, _ = await asyncio.wait(
|
|
367
|
+
{next_task, cancel_task}, return_when=asyncio.FIRST_COMPLETED
|
|
368
|
+
)
|
|
369
|
+
if next_task not in done:
|
|
370
|
+
next_task.cancel()
|
|
371
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
372
|
+
await next_task
|
|
373
|
+
return True
|
|
374
|
+
cancel_task.cancel()
|
|
375
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
376
|
+
await cancel_task
|
|
377
|
+
event = next_task.result()
|
|
378
|
+
if event is _STREAM_DONE:
|
|
379
|
+
return False
|
|
380
|
+
await self._dispatch_event(state, event, tracker)
|
|
381
|
+
finally:
|
|
382
|
+
with contextlib.suppress(Exception):
|
|
383
|
+
await iterator.aclose()
|
|
384
|
+
|
|
385
|
+
async def _dispatch_event(
|
|
386
|
+
self, state: _AcpSessionState, event: Any, tracker: _ToolCallTracker
|
|
387
|
+
) -> None:
|
|
388
|
+
session_id = state.session.session_id
|
|
389
|
+
data = dict(getattr(event, "data", {}) or {})
|
|
390
|
+
event_type = getattr(event, "type", "")
|
|
391
|
+
if event_type in ("delta", "model_delta"):
|
|
392
|
+
text = data.get("text") or ""
|
|
393
|
+
if text:
|
|
394
|
+
await self._send_update(session_id, update_agent_message_text(text))
|
|
395
|
+
elif event_type == "thinking":
|
|
396
|
+
text = data.get("text") or ""
|
|
397
|
+
if text:
|
|
398
|
+
await self._send_update(session_id, update_agent_thought_text(text))
|
|
399
|
+
elif event_type == "tool_call":
|
|
400
|
+
name = str(data.get("tool_name") or "tool")
|
|
401
|
+
call_id = tracker.start(name)
|
|
402
|
+
await self._send_update(
|
|
403
|
+
session_id,
|
|
404
|
+
start_tool_call(
|
|
405
|
+
call_id,
|
|
406
|
+
name,
|
|
407
|
+
kind=_tool_kind(name),
|
|
408
|
+
status="in_progress",
|
|
409
|
+
raw_input=data.get("arguments"),
|
|
410
|
+
),
|
|
411
|
+
)
|
|
412
|
+
elif event_type == "tool_result":
|
|
413
|
+
name = str(data.get("tool_name") or "tool")
|
|
414
|
+
call_id = tracker.finish(name)
|
|
415
|
+
if call_id is None:
|
|
416
|
+
return
|
|
417
|
+
success = data.get("success", True)
|
|
418
|
+
output = data.get("output") if success else (data.get("error") or data.get("output"))
|
|
419
|
+
content = []
|
|
420
|
+
if output:
|
|
421
|
+
content.append(tool_content(text_block(_clip(output))))
|
|
422
|
+
await self._send_update(
|
|
423
|
+
session_id,
|
|
424
|
+
update_tool_call(
|
|
425
|
+
call_id,
|
|
426
|
+
status="completed" if success else "failed",
|
|
427
|
+
content=content or None,
|
|
428
|
+
raw_output=output,
|
|
429
|
+
),
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
async def _resolve_approvals(self, state: _AcpSessionState, tracker: _ToolCallTracker) -> bool:
|
|
433
|
+
"""Relay pending harness approvals as ACP permission requests."""
|
|
434
|
+
session = state.session
|
|
435
|
+
while True:
|
|
436
|
+
pending = session.pending_approvals()
|
|
437
|
+
if not pending:
|
|
438
|
+
return False
|
|
439
|
+
if state.cancel_event.is_set() or self._conn is None:
|
|
440
|
+
return True
|
|
441
|
+
item = dict(pending[0])
|
|
442
|
+
tool_name = str(item.get("tool_name") or "tool")
|
|
443
|
+
call_id = str(item.get("tool_call_id") or tracker.start(tool_name))
|
|
444
|
+
response = await self._conn.request_permission(
|
|
445
|
+
options=[
|
|
446
|
+
PermissionOption(option_id="allow_once", name="Allow once", kind="allow_once"),
|
|
447
|
+
PermissionOption(
|
|
448
|
+
option_id="allow_always", name="Always allow", kind="allow_always"
|
|
449
|
+
),
|
|
450
|
+
PermissionOption(option_id="reject_once", name="Reject", kind="reject_once"),
|
|
451
|
+
],
|
|
452
|
+
session_id=session.session_id,
|
|
453
|
+
tool_call=ToolCallUpdate(
|
|
454
|
+
tool_call_id=call_id,
|
|
455
|
+
title=tool_name,
|
|
456
|
+
kind=_tool_kind(tool_name),
|
|
457
|
+
status="pending",
|
|
458
|
+
raw_input=item.get("arguments"),
|
|
459
|
+
),
|
|
460
|
+
)
|
|
461
|
+
outcome = getattr(response, "outcome", None)
|
|
462
|
+
selected = getattr(outcome, "outcome", "") == "selected"
|
|
463
|
+
option_id = getattr(outcome, "option_id", "")
|
|
464
|
+
if selected and option_id in ("allow_once", "allow_always"):
|
|
465
|
+
result = await session.approve_pending(0, always=option_id == "allow_always")
|
|
466
|
+
elif selected:
|
|
467
|
+
result = await session.reject_pending(0)
|
|
468
|
+
else:
|
|
469
|
+
# Client cancelled the permission prompt: reject and stop the turn.
|
|
470
|
+
await session.reject_pending(0, message="Cancelled from the editor")
|
|
471
|
+
return True
|
|
472
|
+
content = getattr(result, "content", "") or ""
|
|
473
|
+
if content:
|
|
474
|
+
await self._send_update(session.session_id, update_agent_message_text(content))
|
|
475
|
+
|
|
476
|
+
# -- helpers ---------------------------------------------------------------
|
|
477
|
+
|
|
478
|
+
def _load_spec(self, cwd: Path) -> Any:
|
|
479
|
+
from superqode.harness import load_harness_spec
|
|
480
|
+
from superqode.harness.templates import coding_template
|
|
481
|
+
|
|
482
|
+
explicit = self._spec_path or os.environ.get("SUPERQODE_ACP_SPEC", "").strip()
|
|
483
|
+
if explicit:
|
|
484
|
+
return load_harness_spec(Path(explicit).expanduser())
|
|
485
|
+
found = discover_session_spec(cwd, self._harness_dir)
|
|
486
|
+
if found is not None:
|
|
487
|
+
return load_harness_spec(found)
|
|
488
|
+
return coding_template()
|
|
489
|
+
|
|
490
|
+
async def _send_update(self, session_id: str, update: Any) -> None:
|
|
491
|
+
if self._conn is None:
|
|
492
|
+
return
|
|
493
|
+
await self._conn.session_update(session_id=session_id, update=update)
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
async def run_acp_server(
|
|
497
|
+
*,
|
|
498
|
+
spec_path: Path | None = None,
|
|
499
|
+
harness_dir: Path | None = None,
|
|
500
|
+
provider: str = "",
|
|
501
|
+
model: str = "",
|
|
502
|
+
) -> None:
|
|
503
|
+
"""Serve SuperQode as an ACP agent on stdio until the client disconnects."""
|
|
504
|
+
agent = SuperQodeAcpAgent(
|
|
505
|
+
spec_path=spec_path,
|
|
506
|
+
harness_dir=harness_dir,
|
|
507
|
+
provider=provider,
|
|
508
|
+
model=model,
|
|
509
|
+
)
|
|
510
|
+
await run_agent(agent)
|