agentwire-dev 1.23.0__tar.gz → 1.24.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.gitignore +3 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/CHANGELOG.md +20 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/PKG-INFO +4 -1
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/__init__.py +1 -1
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/__main__.py +241 -92
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/email.py +33 -6
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/config.py +30 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/agentwire-permission.sh +19 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +12 -3
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/mcp_server.py +6 -3
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/overnight.py +40 -27
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/project_config.py +4 -0
- agentwire_dev-1.24.0/agentwire/repl/__init__.py +12 -0
- agentwire_dev-1.24.0/agentwire/repl/app.py +185 -0
- agentwire_dev-1.24.0/agentwire/repl/commands.py +320 -0
- agentwire_dev-1.24.0/agentwire/repl/context.py +96 -0
- agentwire_dev-1.24.0/agentwire/repl/mentions.py +165 -0
- agentwire_dev-1.24.0/agentwire/repl/persistence.py +253 -0
- agentwire_dev-1.24.0/agentwire/repl/state.py +96 -0
- agentwire_dev-1.24.0/agentwire/repl/textual_app.py +1273 -0
- agentwire_dev-1.24.0/agentwire/repl/views/__init__.py +7 -0
- agentwire_dev-1.24.0/agentwire/repl/views/fanout.py +568 -0
- agentwire_dev-1.24.0/agentwire/sdk/__init__.py +42 -0
- agentwire_dev-1.24.0/agentwire/sdk/capabilities.py +129 -0
- agentwire_dev-1.24.0/agentwire/sdk/client.py +187 -0
- agentwire_dev-1.24.0/agentwire/sdk/damage_control.py +147 -0
- agentwire_dev-1.24.0/agentwire/sdk/errors.py +27 -0
- agentwire_dev-1.24.0/agentwire/sdk/events.py +214 -0
- agentwire_dev-1.24.0/agentwire/sdk/render.py +339 -0
- agentwire_dev-1.24.0/agentwire/sdk/sinks/__init__.py +11 -0
- agentwire_dev-1.24.0/agentwire/sdk/sinks/base.py +27 -0
- agentwire_dev-1.24.0/agentwire/sdk/sinks/textual.py +147 -0
- agentwire_dev-1.24.0/agentwire/sdk/state.py +169 -0
- agentwire_dev-1.24.0/agentwire/search.py +164 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/server.py +202 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/css/desktop.css +296 -2
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/desktop.js +48 -1
- agentwire_dev-1.24.0/agentwire/static/js/sidebar/sdk-sessions-section.js +77 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/sessions-section.js +4 -1
- agentwire_dev-1.24.0/agentwire/static/js/sidebar/workflows-section.js +114 -0
- agentwire_dev-1.24.0/agentwire/static/js/windows/sdk-watch-window.js +257 -0
- agentwire_dev-1.24.0/agentwire/static/js/windows/workflow-window.js +166 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/cli.py +60 -7
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/definitions.py +62 -6
- agentwire_dev-1.24.0/agentwire/workflows/node.py +166 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/pi_runner.py +6 -5
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/runner.py +19 -5
- agentwire_dev-1.24.0/agentwire/workflows/runners/__init__.py +67 -0
- agentwire_dev-1.24.0/agentwire/workflows/runners/anthropic.py +248 -0
- agentwire_dev-1.24.0/agentwire/workflows/runners/human_gate.py +133 -0
- agentwire_dev-1.24.0/agentwire/workflows/runners/pi.py +35 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/storage.py +13 -1
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/PORTAL.md +2 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/pi-zai.md +3 -3
- agentwire_dev-1.24.0/docs/repl-tui.md +286 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/scheduled-workloads.md +1 -1
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/workflows.md +135 -6
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/pyproject.toml +9 -0
- agentwire_dev-1.24.0/tests/integration/test_anthropic_runner_live.py +218 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_build_agent_command.py +36 -25
- agentwire_dev-1.24.0/tests/snapshot/__snapshots__/test_repl_snapshots/test_empty_boot_snapshot.raw +202 -0
- agentwire_dev-1.24.0/tests/snapshot/apps/repl_empty.py +59 -0
- agentwire_dev-1.24.0/tests/snapshot/test_repl_snapshots.py +44 -0
- agentwire_dev-1.24.0/tests/unit/test_anthropic_capabilities.py +149 -0
- agentwire_dev-1.24.0/tests/unit/test_anthropic_classify.py +36 -0
- agentwire_dev-1.24.0/tests/unit/test_anthropic_events.py +209 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_channels.py +37 -0
- agentwire_dev-1.24.0/tests/unit/test_human_gate_runner.py +151 -0
- agentwire_dev-1.24.0/tests/unit/test_overnight_resume_flags.py +72 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_commands.py +562 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_context.py +137 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_damage_control.py +188 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_dispatch.py +8 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_fanout.py +466 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_mentions.py +117 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_persistence.py +256 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_sdk.py +1106 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_sink_wrap.py +94 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_tail.py +98 -0
- agentwire_dev-1.24.0/tests/unit/test_repl_textual_app.py +1052 -0
- agentwire_dev-1.24.0/tests/unit/test_runner_on_event.py +86 -0
- agentwire_dev-1.24.0/tests/unit/test_runner_override.py +65 -0
- agentwire_dev-1.24.0/tests/unit/test_runners_registry.py +108 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_scheduler.py +12 -0
- agentwire_dev-1.24.0/tests/unit/test_sdk_session_types.py +95 -0
- agentwire_dev-1.24.0/tests/unit/test_search.py +196 -0
- agentwire_dev-1.24.0/tests/unit/test_server_sdk_watch.py +78 -0
- agentwire_dev-1.24.0/tests/unit/test_server_workflow_history.py +173 -0
- agentwire_dev-1.24.0/tests/unit/test_workflow_cli.py +172 -0
- agentwire_dev-1.24.0/tests/unit/test_workflow_storage.py +128 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_workflows.py +29 -9
- agentwire_dev-1.23.0/agentwire/workflows/node.py +0 -115
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/FUNDING.yml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/CLA.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/CODE_OF_CONDUCT.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/CONTRIBUTING.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/Dockerfile.local +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/Dockerfile.runpod +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/LICENSE +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/README.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/RELEASING.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/SECURITY.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/SPONSORS.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/agents/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/agents/base.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/agents/tmux.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/bridges/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/bridges/telegram.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/cached_status.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/_template.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/base.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/discord.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/quo.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/slack.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/sms.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/telegram.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/webhook.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/cli_safety.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/completion.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/errors.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/history.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/idle-handler.sh +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/init_agentwire.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/listen.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/locking.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/network.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/onboarding.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/pane_manager.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/projects.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/prompts/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/prompts/init.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/agentwire.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/channel-admin.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/chatbot.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/discord-dm.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/init.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/notifications.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/orchestrator.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/slack-dm.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/task-runner.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/voice.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/worker.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/scheduler.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-Echo--black.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-Echo--transparent.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-Echo.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-email-banner.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--transparent.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/favicon.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/android.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/automaton.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/bot.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/cyborg.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/droid.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/drone.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/guardian.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/mech.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/probe.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/robot.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/sentinel.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/unit.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/blob.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/cloud.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/crystal.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/cyclops.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/flame.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/horned.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/moon.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/slime.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/star.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/tentacle.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/winged.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/bear.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/cat.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/crown.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/deer.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/drone.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/eagle.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/fox.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/hawk.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/horse.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/lion.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/robot.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/tiger.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/wolf.jpeg +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/.gitkeep +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/artifact-window.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/components/icon-picker.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/components/list-card.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/components/type-tag.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/desktop-manager.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/icon-manager.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/notifications-panel.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/session-window.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/config-section.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/services-section.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/socials-section.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/tile-manager.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/utils/auto-refresh.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/windows/chat-window.js +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/base.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/server_backend.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/stt_server.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/whisperkit.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tasks.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/base.html +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/desktop.html +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/email_notification.html +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/tmux.conf +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templating.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/aws.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/docker.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/gcp.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/gh.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/git.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/gws.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/kubectl.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/npm.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/terraform.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/uv.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/base.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/chatterbox.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/kokoro.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/qwen_base.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/qwen_custom.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/qwen_design.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/zonos.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/registry.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/runpod_handler.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts_server.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tunnels.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/chunker.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/file_io.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/paths.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/subprocess.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/validation.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voiceclone.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/darren.wav +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/default.wav +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/jessica.wav +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/lisa.wav +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/may.wav +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/__init__.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/context.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/outputs.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/worktree.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/FEATURE-REQUESTS.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/FR-auto-mode-session-type.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/SHELL_ESCAPING.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/SPONSORS.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/TROUBLESHOOTING.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/README.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-agent-hot-swap.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-ambient-context-stream.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-ambient-listening-mode.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-audio-cues.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-checkpoint-commits.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-context-compression-protocol.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-context-window-gauge.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-contextual-bookmarks.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-conversation-archaeology.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-cost-tracking-dashboard.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-cross-session-events.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-delegation-replay.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-device-session-tethering.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-failure-memory.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-notification-escalation.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-periodic-voice-briefings.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-presence-aware-sessions.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-drift-detection.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-energy-model.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-handshake.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-momentum.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-replay.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-snapshots.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-templates.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-thermal-throttling.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-smart-session-routing.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-spatial-voice-mixing.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-speculative-execution.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-task-pipeline-chaining.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-task-pivot-protocol.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-task-time-budgets.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-activity-zones.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-breakpoints.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-code-review.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-command-undo.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-handoff.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-identity.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-interrupts-v2.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-interrupts.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-macros.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-transcript-logs.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-watchdog-mode.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-fencing.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-file-coordination.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-health-dashboard.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-heartbeat-watchdog.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-progress-streaming.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-proof-of-work.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-warmup.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-x-api-integration.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/channels.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/claude-code-auto-mode.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/critical-analysis.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/demo-script.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/gws-google-workspace-cli.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/hammerspoon.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/pending-code-changes.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/projects-dedup-ignores-machine.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/remote-tts-session-detection.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/tmux-config-onboarding.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/tmux-paste-freeze.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/tmux-recommended-config.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/logo.png +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/notification-hooks.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/progressive-loading-pattern.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/prompts/agentwire-website.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/releasing.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/remote-access.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/remote-machines.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/runpod-tts.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/security/damage-control-migration.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/security/damage-control.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/tmux-hooks.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/tts-self-hosted.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/youtube-channel.md +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/requirements-tts.txt +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/conftest.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/e2e/test_portal_ui.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/fixtures/sample_agentwire.yml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/fixtures/sample_config.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/fixtures/sample_scheduler.yaml +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_channels_cli.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_cli_commands.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_cli_output.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_mcp_tools.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_portal_api.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_scheduler_board.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_scheduler_workflow.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_cli_safety.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_config.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_file_io.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_history.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_locking.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_mcp_server.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_project_config.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_roles.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_server_async.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_server_pure.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_tasks.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_templating.py +0 -0
- {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_worktree.py +0 -0
|
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Anthropic workflow runner** — `runner: anthropic` alongside the existing pi runner (Phase 6, PRs 1–6)
|
|
13
|
+
- Pluggable runner registry (`agentwire/workflows/runners/`) with a shared `NodeRunner` Protocol; pi kept byte-for-byte identical behind a thin shim
|
|
14
|
+
- `AnthropicRunner` uses `claude-agent-sdk>=0.1.43` with subscription auth — no `ANTHROPIC_API_KEY` required, inherits `~/.claude/.credentials.json` (subscription-covered, no per-run billing)
|
|
15
|
+
- Tool execution is owned by Claude Code itself: `setting_sources=["user"]` loads `~/.claude/settings.json` so AgentWire's damage-control PreToolUse hooks fire on every Bash call (verified end-to-end by a live integration test that chmod 777's a sentinel file — hook blocks, file mode unchanged)
|
|
16
|
+
- Per-runner tool namespaces: pi stays lowercase (`read`, `bash`, `edit`, …), anthropic uses CamelCase (`Read`, `Bash`, `Edit`, …); parse-time validation rejects cross-namespace mixups
|
|
17
|
+
- Anthropic-only fields validated at parse time: `model` (required), `effort` (low|medium|high|max|xhigh — with Opus/Opus-4.7 gating), `thinking_config` (adaptive|enabled|disabled), `task_budget_tokens` (Opus 4.7 beta, min 20000), `max_thinking_tokens`, `max_budget_usd`
|
|
18
|
+
- Error classification: anthropic runner tags `NodeResult.error` with `transient:` / `permanent:` / `invalid:` / `error:` prefixes so rate-limited runs are distinguishable from genuine bugs
|
|
19
|
+
- **Live event streaming under `--verbose`** — `agentwire workflow run … -v` now streams per-event output for anthropic nodes: `[node] → tool_use Read …`, `← tool_result (ok/err)`, `▓ text`, `✓ turn 42+18 tok`, `■ agent_end 3.1s`
|
|
20
|
+
- **Runner recorded in metadata** — `metadata.json` bumped to `schema_version: 2` with run-level and per-node `runner` fields; `workflow show` renders a `Runner:` line + per-node tag + `Totals:` aggregation; `workflow history` gains a `runner` column
|
|
21
|
+
- **`--runner {pi,anthropic}` CLI override** — `agentwire workflow run` accepts `--runner` to flip every node's runner for one invocation; runner/field mismatches surface as normal validation errors
|
|
22
|
+
- **Canary live** — `daily-book-report` (daily 13:30) flipped to anthropic on 2026-04-17 (Sonnet 4.6 for fetch, Opus 4.7 for compose_and_send). Findings tracked in `docs/missions/anthropic-sdk-runner.md`
|
|
23
|
+
- **Damage-control honors session bypass modes** — `permission_mode: "bypassPermissions"` and `"auto"` now skip `ask:true` escalations for write-tier commands; hard blocks still fire. Fixes `--dangerously-skip-permissions` and autonomous-mode sessions being prompted per Bash call
|
|
24
|
+
|
|
25
|
+
### Documentation
|
|
26
|
+
|
|
27
|
+
- New "Runners" section in `docs/workflows.md` covering per-runner fields, `--runner` usage, and live-event output
|
|
28
|
+
- `agentwire-workflows` skill updated — no longer claims pi-only; links to full Runners reference
|
|
29
|
+
|
|
10
30
|
## [1.23.0] - 2026-04-16
|
|
11
31
|
|
|
12
32
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentwire-dev
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.24.0
|
|
4
4
|
Summary: Multi-session voice web interface for AI coding agents
|
|
5
5
|
Project-URL: Homepage, https://agentwire.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/dotdevdotdev/agentwire-dev
|
|
@@ -694,8 +694,11 @@ Requires-Dist: python-dotenv>=1.0.0
|
|
|
694
694
|
Requires-Dist: pyyaml>=6.0
|
|
695
695
|
Requires-Dist: requests>=2.28.0
|
|
696
696
|
Requires-Dist: resend>=2.0.0
|
|
697
|
+
Requires-Dist: rich>=13.0
|
|
698
|
+
Requires-Dist: textual>=0.80
|
|
697
699
|
Provides-Extra: dev
|
|
698
700
|
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
701
|
+
Requires-Dist: pytest-textual-snapshot>=1.0.0; extra == 'dev'
|
|
699
702
|
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
700
703
|
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
701
704
|
Provides-Extra: stt
|
|
@@ -84,11 +84,42 @@ class AgentCommand:
|
|
|
84
84
|
env: dict[str, str] = field(default_factory=dict) # Secrets to inject via tmux set-environment (keeps keys out of `ps`)
|
|
85
85
|
|
|
86
86
|
|
|
87
|
+
def _build_tmux_env_flags(env: dict[str, str]) -> list[str]:
|
|
88
|
+
"""Build `-e KEY=VAL` flag pairs for `tmux new-session`.
|
|
89
|
+
|
|
90
|
+
Prefer this over post-creation `inject_session_env` when creating a fresh
|
|
91
|
+
session with secrets: `tmux new-session -e K=V` places the var in the
|
|
92
|
+
session environment BEFORE the initial shell starts, so that shell sees
|
|
93
|
+
it. `tmux set-environment` on an existing session only affects shells
|
|
94
|
+
spawned AFTER the call, which leaves the initial pane's shell without
|
|
95
|
+
the var — and the agent command runs in that initial shell.
|
|
96
|
+
"""
|
|
97
|
+
flags: list[str] = []
|
|
98
|
+
for key, value in env.items():
|
|
99
|
+
flags.extend(["-e", f"{key}={value}"])
|
|
100
|
+
return flags
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _build_tmux_env_flags_shell(env: dict[str, str]) -> str:
|
|
104
|
+
"""Shell-safe `-e 'K=V' -e 'K2=V2' ` fragment for inlining in remote SSH chained commands.
|
|
105
|
+
|
|
106
|
+
Returns empty string when env is empty. Trailing space when non-empty so
|
|
107
|
+
the caller can concatenate directly into a `tmux new-session ... && ...`
|
|
108
|
+
string without extra glue.
|
|
109
|
+
"""
|
|
110
|
+
if not env:
|
|
111
|
+
return ""
|
|
112
|
+
parts = [f"-e {shlex.quote(f'{k}={v}')}" for k, v in env.items()]
|
|
113
|
+
return " ".join(parts) + " "
|
|
114
|
+
|
|
115
|
+
|
|
87
116
|
def inject_session_env(session: str, env: dict[str, str], remote_host: str | None = None) -> None:
|
|
88
|
-
"""Set env vars on
|
|
117
|
+
"""Set env vars on an existing tmux session for FUTURE shells in that session.
|
|
89
118
|
|
|
90
|
-
|
|
91
|
-
|
|
119
|
+
Does NOT update the initial pane's shell — that shell was already started
|
|
120
|
+
when the session was created and has a fixed env. Use
|
|
121
|
+
`_build_tmux_env_flags(env)` with `tmux new-session -e K=V` instead if
|
|
122
|
+
the agent command runs in the initial shell.
|
|
92
123
|
"""
|
|
93
124
|
if not env:
|
|
94
125
|
return
|
|
@@ -126,30 +157,13 @@ def parse_env_args(env_args: list[str] | None) -> dict[str, str]:
|
|
|
126
157
|
return result
|
|
127
158
|
|
|
128
159
|
|
|
129
|
-
def build_session_env_shell_fragment(session: str, env: dict[str, str]) -> str:
|
|
130
|
-
"""Build a shell fragment of `tmux set-environment` calls for chained remote commands.
|
|
131
|
-
|
|
132
|
-
Returns a trailing `&& ` string ready to splice into an ssh-executed compound
|
|
133
|
-
command. Empty string if no env.
|
|
134
|
-
"""
|
|
135
|
-
if not env:
|
|
136
|
-
return ""
|
|
137
|
-
parts = []
|
|
138
|
-
for key, value in env.items():
|
|
139
|
-
parts.append(
|
|
140
|
-
f"tmux set-environment -t {shlex.quote(session)} "
|
|
141
|
-
f"{shlex.quote(key)} {shlex.quote(value)}"
|
|
142
|
-
)
|
|
143
|
-
return " && ".join(parts) + " && "
|
|
144
|
-
|
|
145
|
-
|
|
146
160
|
def build_agent_command(session_type: str, roles: list[RoleConfig] | None = None, model: str | None = None) -> AgentCommand:
|
|
147
161
|
"""Build the agent command for a session.
|
|
148
162
|
|
|
149
163
|
Args:
|
|
150
164
|
session_type: Session type (e.g., "claude-bypass", "claude-auto", "pi-zai", "bare")
|
|
151
165
|
roles: Optional list of roles to apply
|
|
152
|
-
model: Optional model override (e.g., "haiku", "sonnet", "opus", "glm-5")
|
|
166
|
+
model: Optional model override (e.g., "haiku", "sonnet", "opus", "glm-5.1")
|
|
153
167
|
|
|
154
168
|
Returns:
|
|
155
169
|
AgentCommand with the command string and metadata
|
|
@@ -170,7 +184,7 @@ def build_agent_command(session_type: str, roles: list[RoleConfig] | None = None
|
|
|
170
184
|
# Pi reads ZAI_API_KEY from env. We inject it via `tmux set-environment`
|
|
171
185
|
# (see inject_session_env) so the key never appears in `ps auxwww`.
|
|
172
186
|
pi_binary = pi_config.get("binary", "pi")
|
|
173
|
-
default_model = pi_config.get("default_model", "glm-5")
|
|
187
|
+
default_model = pi_config.get("default_model", "glm-5.1")
|
|
174
188
|
|
|
175
189
|
parts = [pi_binary, "--provider", "zai"]
|
|
176
190
|
parts.extend(["--model", model or default_model])
|
|
@@ -204,6 +218,38 @@ def build_agent_command(session_type: str, roles: list[RoleConfig] | None = None
|
|
|
204
218
|
env={"ZAI_API_KEY": zai.get("api_key", "")},
|
|
205
219
|
)
|
|
206
220
|
|
|
221
|
+
# === Agentwire REPL (claude-agent-sdk) ===
|
|
222
|
+
# sdk-bypass / sdk-prompted / sdk-restricted — Python REPL running in a
|
|
223
|
+
# tmux pane, auth via Claude subscription. See docs/missions/agentwire-repl.md.
|
|
224
|
+
if session_type.startswith("sdk-"):
|
|
225
|
+
# Permission mode maps to SDK's permission_mode parameter
|
|
226
|
+
mode_map = {
|
|
227
|
+
"sdk-bypass": "bypass",
|
|
228
|
+
"sdk-prompted": "prompted",
|
|
229
|
+
"sdk-restricted": "restricted",
|
|
230
|
+
}
|
|
231
|
+
mode = mode_map.get(session_type, "bypass")
|
|
232
|
+
|
|
233
|
+
parts = ["agentwire", "repl", "--mode", mode]
|
|
234
|
+
if model:
|
|
235
|
+
parts.extend(["--model", model])
|
|
236
|
+
|
|
237
|
+
# Role-based system prompt (same temp-file pattern as claude-* / pi-zai
|
|
238
|
+
# to avoid shell escaping on multiline content; --append-system-prompt
|
|
239
|
+
# must be last).
|
|
240
|
+
temp_file = None
|
|
241
|
+
if merged and merged.instructions:
|
|
242
|
+
f = tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False)
|
|
243
|
+
f.write(merged.instructions)
|
|
244
|
+
f.close()
|
|
245
|
+
temp_file = f.name
|
|
246
|
+
parts.append(f'--append-system-prompt "$(<{temp_file})"')
|
|
247
|
+
|
|
248
|
+
return AgentCommand(
|
|
249
|
+
command=" ".join(parts),
|
|
250
|
+
temp_file=temp_file,
|
|
251
|
+
)
|
|
252
|
+
|
|
207
253
|
# === Claude Code ===
|
|
208
254
|
if session_type.startswith("claude"):
|
|
209
255
|
parts = ["claude"]
|
|
@@ -3381,6 +3427,31 @@ def cmd_list(args) -> int:
|
|
|
3381
3427
|
return 0
|
|
3382
3428
|
|
|
3383
3429
|
|
|
3430
|
+
def cmd_repl(args) -> int:
|
|
3431
|
+
"""Agentwire REPL — interactive harness built on claude-agent-sdk.
|
|
3432
|
+
|
|
3433
|
+
Invoked by build_agent_command when a session is spawned with --type sdk-*.
|
|
3434
|
+
Interactive mode auto-persists every turn under
|
|
3435
|
+
`~/.agentwire/sessions/repl/<session-name>/`; `--resume NAME` continues a
|
|
3436
|
+
prior session by reusing its sdk_session_id.
|
|
3437
|
+
"""
|
|
3438
|
+
from agentwire.repl.app import run_repl
|
|
3439
|
+
return run_repl(
|
|
3440
|
+
mode=args.mode,
|
|
3441
|
+
model=args.model,
|
|
3442
|
+
print_prompt=args.print,
|
|
3443
|
+
system_prompt=args.append_system_prompt,
|
|
3444
|
+
session_name=getattr(args, "session_name", None),
|
|
3445
|
+
resume=getattr(args, "resume", None),
|
|
3446
|
+
roles=getattr(args, "roles", None),
|
|
3447
|
+
view=getattr(args, "view", "chat"),
|
|
3448
|
+
cols=getattr(args, "cols", 3),
|
|
3449
|
+
col_models=getattr(args, "col_models", None),
|
|
3450
|
+
col_efforts=getattr(args, "col_efforts", None),
|
|
3451
|
+
col_roles=getattr(args, "col_roles", None),
|
|
3452
|
+
)
|
|
3453
|
+
|
|
3454
|
+
|
|
3384
3455
|
def cmd_new(args) -> int:
|
|
3385
3456
|
"""Create a new agent session.
|
|
3386
3457
|
|
|
@@ -3548,21 +3619,22 @@ def cmd_new(args) -> int:
|
|
|
3548
3619
|
except Exception as e:
|
|
3549
3620
|
print(f"Warning: Failed to write system prompt to remote: {e}", file=sys.stderr)
|
|
3550
3621
|
|
|
3551
|
-
|
|
3622
|
+
env_flags = _build_tmux_env_flags_shell(agent.env)
|
|
3552
3623
|
|
|
3553
|
-
# Create session - Agent starts immediately if not bare
|
|
3624
|
+
# Create session - Agent starts immediately if not bare.
|
|
3625
|
+
# `-e K=V` on new-session places env in the session environment BEFORE
|
|
3626
|
+
# the initial shell starts, so send-keys'd agent command sees it.
|
|
3554
3627
|
if agent_cmd:
|
|
3555
3628
|
create_cmd = (
|
|
3556
|
-
f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(remote_path)} && "
|
|
3629
|
+
f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(remote_path)} {env_flags}&& "
|
|
3557
3630
|
f"tmux send-keys -t {shlex.quote(session_name)} 'cd {shlex.quote(remote_path)}' Enter && "
|
|
3558
3631
|
f"sleep 0.1 && "
|
|
3559
|
-
f"{env_fragment}"
|
|
3560
3632
|
f"tmux send-keys -t {shlex.quote(session_name)} {shlex.quote(agent_cmd)} Enter"
|
|
3561
3633
|
)
|
|
3562
3634
|
else:
|
|
3563
3635
|
# Bare session - just create tmux
|
|
3564
3636
|
create_cmd = (
|
|
3565
|
-
f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(remote_path)} && "
|
|
3637
|
+
f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(remote_path)} {env_flags}&& "
|
|
3566
3638
|
f"tmux send-keys -t {shlex.quote(session_name)} 'cd {shlex.quote(remote_path)}' Enter"
|
|
3567
3639
|
)
|
|
3568
3640
|
|
|
@@ -3650,20 +3722,10 @@ def cmd_new(args) -> int:
|
|
|
3650
3722
|
else:
|
|
3651
3723
|
return _output_result(False, json_mode, f"Session '{session_name}' already exists. Use -f to replace.")
|
|
3652
3724
|
|
|
3653
|
-
#
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
)
|
|
3658
|
-
|
|
3659
|
-
# Ensure Claude starts in correct directory
|
|
3660
|
-
subprocess.run(
|
|
3661
|
-
["tmux", "send-keys", "-t", session_name, f"cd {shlex.quote(str(session_path))}", "Enter"],
|
|
3662
|
-
check=True
|
|
3663
|
-
)
|
|
3664
|
-
time.sleep(0.1)
|
|
3665
|
-
|
|
3666
|
-
# Determine agent type and normalize session type
|
|
3725
|
+
# Determine agent type and normalize session type BEFORE creating the
|
|
3726
|
+
# tmux session, so we can inject secrets via `tmux new-session -e K=V`
|
|
3727
|
+
# (the only way to make the initial pane's shell see them — post-hoc
|
|
3728
|
+
# `tmux set-environment` only affects shells spawned AFTER the call).
|
|
3667
3729
|
agent_type = detect_default_agent_type()
|
|
3668
3730
|
|
|
3669
3731
|
# Determine session type from CLI --type flag or existing config
|
|
@@ -3701,8 +3763,21 @@ def cmd_new(args) -> int:
|
|
|
3701
3763
|
|
|
3702
3764
|
agent_cmd = agent.command
|
|
3703
3765
|
|
|
3704
|
-
#
|
|
3705
|
-
|
|
3766
|
+
# Create new tmux session with env vars injected at creation time.
|
|
3767
|
+
# `-e K=V` places vars in the session environment before the initial
|
|
3768
|
+
# shell starts, so the agent command (run via send-keys below) sees them.
|
|
3769
|
+
subprocess.run(
|
|
3770
|
+
["tmux", "new-session", "-d", "-s", session_name, "-c", str(session_path),
|
|
3771
|
+
*_build_tmux_env_flags(agent.env)],
|
|
3772
|
+
check=True
|
|
3773
|
+
)
|
|
3774
|
+
|
|
3775
|
+
# Ensure Claude starts in correct directory
|
|
3776
|
+
subprocess.run(
|
|
3777
|
+
["tmux", "send-keys", "-t", session_name, f"cd {shlex.quote(str(session_path))}", "Enter"],
|
|
3778
|
+
check=True
|
|
3779
|
+
)
|
|
3780
|
+
time.sleep(0.1)
|
|
3706
3781
|
|
|
3707
3782
|
# Start agent command if not bare
|
|
3708
3783
|
if agent_cmd:
|
|
@@ -4590,13 +4665,12 @@ def cmd_recreate(args) -> int:
|
|
|
4590
4665
|
agent = build_agent_command(session_type_str)
|
|
4591
4666
|
agent.env.update(parse_env_args(getattr(args, 'env', None)))
|
|
4592
4667
|
agent_cmd = agent.command
|
|
4593
|
-
|
|
4668
|
+
env_flags = _build_tmux_env_flags_shell(agent.env)
|
|
4594
4669
|
|
|
4595
4670
|
create_cmd = (
|
|
4596
|
-
f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(session_path)} && "
|
|
4671
|
+
f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(session_path)} {env_flags}&& "
|
|
4597
4672
|
f"tmux send-keys -t {shlex.quote(session_name)} 'cd {shlex.quote(session_path)}' Enter && "
|
|
4598
4673
|
f"sleep 0.1 && "
|
|
4599
|
-
f"{env_fragment}"
|
|
4600
4674
|
f"tmux send-keys -t {shlex.quote(session_name)} {shlex.quote(agent_cmd)} Enter"
|
|
4601
4675
|
)
|
|
4602
4676
|
|
|
@@ -4697,9 +4771,12 @@ def cmd_recreate(args) -> int:
|
|
|
4697
4771
|
|
|
4698
4772
|
agent_cmd = agent.command
|
|
4699
4773
|
|
|
4700
|
-
# Step 5: Create new session
|
|
4774
|
+
# Step 5: Create new session with env vars injected at creation time so
|
|
4775
|
+
# the initial shell sees them (post-hoc set-environment doesn't reach the
|
|
4776
|
+
# already-running shell — see _build_tmux_env_flags docstring).
|
|
4701
4777
|
subprocess.run(
|
|
4702
|
-
["tmux", "new-session", "-d", "-s", session_name, "-c", str(session_path)
|
|
4778
|
+
["tmux", "new-session", "-d", "-s", session_name, "-c", str(session_path),
|
|
4779
|
+
*_build_tmux_env_flags(agent.env)],
|
|
4703
4780
|
check=True
|
|
4704
4781
|
)
|
|
4705
4782
|
|
|
@@ -4710,9 +4787,6 @@ def cmd_recreate(args) -> int:
|
|
|
4710
4787
|
)
|
|
4711
4788
|
time.sleep(0.1)
|
|
4712
4789
|
|
|
4713
|
-
# Inject secrets via tmux set-environment (keeps keys out of `ps`)
|
|
4714
|
-
inject_session_env(session_name, agent.env)
|
|
4715
|
-
|
|
4716
4790
|
# Start the agent with appropriate command
|
|
4717
4791
|
if agent_cmd:
|
|
4718
4792
|
subprocess.run(
|
|
@@ -4973,13 +5047,12 @@ def cmd_fork(args) -> int:
|
|
|
4973
5047
|
agent.env.update(parse_env_args(getattr(args, 'env', None)))
|
|
4974
5048
|
|
|
4975
5049
|
agent_cmd = agent.command
|
|
4976
|
-
|
|
5050
|
+
env_flags = _build_tmux_env_flags_shell(agent.env)
|
|
4977
5051
|
|
|
4978
5052
|
create_session_cmd = (
|
|
4979
|
-
f"tmux new-session -d -s {shlex.quote(target_session)} -c {shlex.quote(target_path)} && "
|
|
5053
|
+
f"tmux new-session -d -s {shlex.quote(target_session)} -c {shlex.quote(target_path)} {env_flags}&& "
|
|
4980
5054
|
f"tmux send-keys -t {shlex.quote(target_session)} 'cd {shlex.quote(target_path)}' Enter && "
|
|
4981
5055
|
f"sleep 0.1 && "
|
|
4982
|
-
f"{env_fragment}"
|
|
4983
5056
|
f"tmux send-keys -t {shlex.quote(target_session)} {shlex.quote(agent_cmd)} Enter"
|
|
4984
5057
|
)
|
|
4985
5058
|
|
|
@@ -5039,20 +5112,8 @@ def cmd_fork(args) -> int:
|
|
|
5039
5112
|
if check_target.returncode == 0:
|
|
5040
5113
|
return _output_result(False, json_mode, f"Target session '{target_session}' already exists")
|
|
5041
5114
|
|
|
5042
|
-
#
|
|
5043
|
-
|
|
5044
|
-
["tmux", "new-session", "-d", "-s", target_session, "-c", str(fork_path)],
|
|
5045
|
-
check=True
|
|
5046
|
-
)
|
|
5047
|
-
|
|
5048
|
-
# Ensure Claude starts in correct directory
|
|
5049
|
-
subprocess.run(
|
|
5050
|
-
["tmux", "send-keys", "-t", target_session, f"cd {shlex.quote(str(fork_path))}", "Enter"],
|
|
5051
|
-
check=True
|
|
5052
|
-
)
|
|
5053
|
-
time.sleep(0.1)
|
|
5054
|
-
|
|
5055
|
-
# Determine session type from --type flag or source config
|
|
5115
|
+
# Determine session type from --type flag or source config (before
|
|
5116
|
+
# session creation, so we can inject env via `tmux new-session -e K=V`).
|
|
5056
5117
|
agent_type = detect_default_agent_type()
|
|
5057
5118
|
type_arg = getattr(args, 'type', None)
|
|
5058
5119
|
source_project_config = load_project_config(fork_path)
|
|
@@ -5128,8 +5189,20 @@ def cmd_fork(args) -> int:
|
|
|
5128
5189
|
agent = build_agent_command(session_type_str, roles)
|
|
5129
5190
|
agent.env.update(parse_env_args(getattr(args, 'env', None)))
|
|
5130
5191
|
|
|
5131
|
-
#
|
|
5132
|
-
|
|
5192
|
+
# Create new tmux session with env injected at creation time so the
|
|
5193
|
+
# initial shell sees the vars (see _build_tmux_env_flags docstring).
|
|
5194
|
+
subprocess.run(
|
|
5195
|
+
["tmux", "new-session", "-d", "-s", target_session, "-c", str(fork_path),
|
|
5196
|
+
*_build_tmux_env_flags(agent.env)],
|
|
5197
|
+
check=True
|
|
5198
|
+
)
|
|
5199
|
+
|
|
5200
|
+
# Ensure Claude starts in correct directory
|
|
5201
|
+
subprocess.run(
|
|
5202
|
+
["tmux", "send-keys", "-t", target_session, f"cd {shlex.quote(str(fork_path))}", "Enter"],
|
|
5203
|
+
check=True
|
|
5204
|
+
)
|
|
5205
|
+
time.sleep(0.1)
|
|
5133
5206
|
|
|
5134
5207
|
agent_cmd = agent.command
|
|
5135
5208
|
if agent_cmd:
|
|
@@ -5205,20 +5278,8 @@ def cmd_fork(args) -> int:
|
|
|
5205
5278
|
if not success:
|
|
5206
5279
|
return _output_result(False, json_mode, f"Failed to create worktree for branch '{target_branch}'")
|
|
5207
5280
|
|
|
5208
|
-
#
|
|
5209
|
-
|
|
5210
|
-
["tmux", "new-session", "-d", "-s", target_session, "-c", str(target_path)],
|
|
5211
|
-
check=True
|
|
5212
|
-
)
|
|
5213
|
-
|
|
5214
|
-
# Ensure agent starts in correct directory
|
|
5215
|
-
subprocess.run(
|
|
5216
|
-
["tmux", "send-keys", "-t", target_session, f"cd {shlex.quote(str(target_path))}", "Enter"],
|
|
5217
|
-
check=True
|
|
5218
|
-
)
|
|
5219
|
-
time.sleep(0.1)
|
|
5220
|
-
|
|
5221
|
-
# Determine session type from --type flag or source config
|
|
5281
|
+
# Determine session type from --type flag or source config (before
|
|
5282
|
+
# session creation, so we can inject env via `tmux new-session -e K=V`).
|
|
5222
5283
|
agent_type = detect_default_agent_type()
|
|
5223
5284
|
type_arg = getattr(args, 'type', None)
|
|
5224
5285
|
config_path = source_path if source_path != project_path else project_path
|
|
@@ -5246,8 +5307,20 @@ def cmd_fork(args) -> int:
|
|
|
5246
5307
|
agent.env.update(parse_env_args(getattr(args, 'env', None)))
|
|
5247
5308
|
agent_cmd = agent.command
|
|
5248
5309
|
|
|
5249
|
-
#
|
|
5250
|
-
|
|
5310
|
+
# Create new session with env injected at creation time so the initial
|
|
5311
|
+
# shell sees the vars (see _build_tmux_env_flags docstring).
|
|
5312
|
+
subprocess.run(
|
|
5313
|
+
["tmux", "new-session", "-d", "-s", target_session, "-c", str(target_path),
|
|
5314
|
+
*_build_tmux_env_flags(agent.env)],
|
|
5315
|
+
check=True
|
|
5316
|
+
)
|
|
5317
|
+
|
|
5318
|
+
# Ensure agent starts in correct directory
|
|
5319
|
+
subprocess.run(
|
|
5320
|
+
["tmux", "send-keys", "-t", target_session, f"cd {shlex.quote(str(target_path))}", "Enter"],
|
|
5321
|
+
check=True
|
|
5322
|
+
)
|
|
5323
|
+
time.sleep(0.1)
|
|
5251
5324
|
|
|
5252
5325
|
if agent_cmd:
|
|
5253
5326
|
subprocess.run(
|
|
@@ -5840,15 +5913,14 @@ def cmd_dev(args) -> int:
|
|
|
5840
5913
|
|
|
5841
5914
|
agent_cmd = agent.command
|
|
5842
5915
|
|
|
5843
|
-
# Create session
|
|
5916
|
+
# Create session with env injected at creation time so the initial
|
|
5917
|
+
# shell sees the vars (see _build_tmux_env_flags docstring).
|
|
5844
5918
|
print(f"Creating dev session '{session_name}' in {project_dir}...")
|
|
5845
5919
|
subprocess.run([
|
|
5846
5920
|
"tmux", "new-session", "-d", "-s", session_name, "-c", str(project_dir),
|
|
5921
|
+
*_build_tmux_env_flags(agent.env),
|
|
5847
5922
|
])
|
|
5848
5923
|
|
|
5849
|
-
# Inject secrets via tmux set-environment (keeps keys out of `ps`)
|
|
5850
|
-
inject_session_env(session_name, agent.env)
|
|
5851
|
-
|
|
5852
5924
|
# Start agent with agentwire config
|
|
5853
5925
|
if agent_cmd:
|
|
5854
5926
|
wait_for_shell_prompt(session_name)
|
|
@@ -10025,7 +10097,10 @@ def main() -> int:
|
|
|
10025
10097
|
# === email command ===
|
|
10026
10098
|
from agentwire.channels.email import cmd_email
|
|
10027
10099
|
email_parser = subparsers.add_parser("email", help="Send branded email notification via Resend")
|
|
10028
|
-
email_parser.add_argument(
|
|
10100
|
+
email_parser.add_argument(
|
|
10101
|
+
"--to", action="append", default=None,
|
|
10102
|
+
help="Recipient email. Repeat or pass comma-separated for multiple recipients (default: from config).",
|
|
10103
|
+
)
|
|
10029
10104
|
email_parser.add_argument("--subject", "-s", type=str, help="Email subject")
|
|
10030
10105
|
email_parser.add_argument("--body", "-b", type=str, help="Email body - markdown supported (or pipe via stdin)")
|
|
10031
10106
|
email_parser.add_argument("--attach", "-a", type=str, action="append", help="Attach file (can use multiple times)")
|
|
@@ -10033,6 +10108,22 @@ def main() -> int:
|
|
|
10033
10108
|
email_parser.add_argument("-q", "--quiet", action="store_true", help="Suppress success output")
|
|
10034
10109
|
email_parser.set_defaults(func=cmd_email)
|
|
10035
10110
|
|
|
10111
|
+
# === brave command ===
|
|
10112
|
+
from agentwire.search import cmd_brave
|
|
10113
|
+
brave_parser = subparsers.add_parser(
|
|
10114
|
+
"brave",
|
|
10115
|
+
help="Brave Search helper — run a web search and print results optimized for LLM consumption.",
|
|
10116
|
+
)
|
|
10117
|
+
brave_parser.add_argument("query", nargs="+", help="Search query (all remaining args joined with spaces)")
|
|
10118
|
+
brave_parser.add_argument("--count", "-n", type=int, default=10, help="Max results (1-20, default 10)")
|
|
10119
|
+
brave_parser.add_argument(
|
|
10120
|
+
"--freshness", "-f", type=str, default="pd",
|
|
10121
|
+
choices=["pd", "pw", "pm", "py"],
|
|
10122
|
+
help="Time window: pd=past day (default), pw=past week, pm=past month, py=past year",
|
|
10123
|
+
)
|
|
10124
|
+
brave_parser.add_argument("--json", action="store_true", help="Output raw JSON instead of compact text")
|
|
10125
|
+
brave_parser.set_defaults(func=cmd_brave)
|
|
10126
|
+
|
|
10036
10127
|
# === notify command ===
|
|
10037
10128
|
notify_parser = subparsers.add_parser("notify", help="Notify portal of session/pane state changes")
|
|
10038
10129
|
notify_parser.add_argument(
|
|
@@ -10074,12 +10165,66 @@ def main() -> int:
|
|
|
10074
10165
|
list_parser.set_defaults(func=cmd_list)
|
|
10075
10166
|
|
|
10076
10167
|
# === new command (top-level) ===
|
|
10168
|
+
# === repl command (top-level, internal — invoked by build_agent_command) ===
|
|
10169
|
+
# Users spawn it via `agentwire new -s <name> --type sdk-bypass`; this is
|
|
10170
|
+
# the process that runs inside the tmux pane. See docs/missions/agentwire-repl.md.
|
|
10171
|
+
repl_parser = subparsers.add_parser(
|
|
10172
|
+
"repl",
|
|
10173
|
+
help="Agentwire REPL (internal — runs inside tmux pane for sdk-* session types)",
|
|
10174
|
+
)
|
|
10175
|
+
repl_parser.add_argument(
|
|
10176
|
+
"--mode", choices=["bypass", "prompted", "restricted"], default="bypass",
|
|
10177
|
+
help="Permission mode (bypass=run tools without asking, prompted=ask, restricted=read-only)",
|
|
10178
|
+
)
|
|
10179
|
+
repl_parser.add_argument("--model", default=None, help="Model override (default: claude-opus-4-7)")
|
|
10180
|
+
repl_parser.add_argument(
|
|
10181
|
+
"-p", "--print", dest="print", default=None, metavar="PROMPT",
|
|
10182
|
+
help="One-shot mode: run PROMPT, emit output, exit (no interactive loop)",
|
|
10183
|
+
)
|
|
10184
|
+
repl_parser.add_argument(
|
|
10185
|
+
"--append-system-prompt", dest="append_system_prompt", default=None, metavar="TEXT",
|
|
10186
|
+
help="Additional system prompt content (appended after base prompt)",
|
|
10187
|
+
)
|
|
10188
|
+
repl_parser.add_argument(
|
|
10189
|
+
"--session-name", dest="session_name", default=None, metavar="NAME",
|
|
10190
|
+
help="Transcript directory name under ~/.agentwire/sessions/repl/ (default: auto-generated timestamp+hash)",
|
|
10191
|
+
)
|
|
10192
|
+
repl_parser.add_argument(
|
|
10193
|
+
"--resume", dest="resume", default=None, metavar="NAME",
|
|
10194
|
+
help="Resume the saved session NAME (reuses its sdk_session_id to continue the prior conversation)",
|
|
10195
|
+
)
|
|
10196
|
+
repl_parser.add_argument(
|
|
10197
|
+
"--role", dest="roles", action="append", metavar="NAME",
|
|
10198
|
+
help="Role name to compose into the system prompt (repeatable). Overrides .agentwire.yml roles.",
|
|
10199
|
+
)
|
|
10200
|
+
repl_parser.add_argument(
|
|
10201
|
+
"--view", choices=["chat", "fanout"], default="chat",
|
|
10202
|
+
help="UI view: 'chat' (default, single conversation) or 'fanout' (N parallel columns).",
|
|
10203
|
+
)
|
|
10204
|
+
repl_parser.add_argument(
|
|
10205
|
+
"--cols", type=int, default=3, metavar="N",
|
|
10206
|
+
help="Column count for --view fanout (2-6, default 3).",
|
|
10207
|
+
)
|
|
10208
|
+
repl_parser.add_argument(
|
|
10209
|
+
"--col-model", dest="col_models", action="append", metavar="N=MODEL",
|
|
10210
|
+
help="Per-column model override for --view fanout (e.g. --col-model 0=claude-opus-4-7 --col-model 1=claude-sonnet-4-6). Repeatable.",
|
|
10211
|
+
)
|
|
10212
|
+
repl_parser.add_argument(
|
|
10213
|
+
"--col-effort", dest="col_efforts", action="append", metavar="N=EFFORT",
|
|
10214
|
+
help="Per-column effort override for --view fanout (e.g. --col-effort 0=max --col-effort 1=high). Repeatable.",
|
|
10215
|
+
)
|
|
10216
|
+
repl_parser.add_argument(
|
|
10217
|
+
"--col-role", dest="col_roles", action="append", metavar="N=ROLE[,ROLE...]",
|
|
10218
|
+
help="Per-column role override for --view fanout (e.g. --col-role 0=skeptic --col-role 1=optimist,explainer). Repeatable.",
|
|
10219
|
+
)
|
|
10220
|
+
repl_parser.set_defaults(func=cmd_repl)
|
|
10221
|
+
|
|
10077
10222
|
new_parser = subparsers.add_parser("new", help="Create new Claude Code session")
|
|
10078
10223
|
new_parser.add_argument("-s", "--session", required=True, help="Session name (project, project/branch, or project/branch@machine)")
|
|
10079
10224
|
new_parser.add_argument("-p", "--path", help="Working directory (default: ~/projects/<name>)")
|
|
10080
10225
|
new_parser.add_argument("-f", "--force", action="store_true", help="Replace existing session")
|
|
10081
10226
|
# Session type
|
|
10082
|
-
new_parser.add_argument("--type", help="Session type (bare, claude-bypass, claude-prompted, claude-restricted, pi-zai, pi-zai-restricted, pi-zai-readonly, standard, worker, voice)")
|
|
10227
|
+
new_parser.add_argument("--type", help="Session type (bare, claude-bypass, claude-prompted, claude-restricted, pi-zai, pi-zai-restricted, pi-zai-readonly, sdk-bypass, sdk-prompted, sdk-restricted, standard, worker, voice)")
|
|
10083
10228
|
# Roles
|
|
10084
10229
|
new_parser.add_argument("--roles", help="Comma-separated list of roles (preserves existing config, defaults to agentwire for new projects)")
|
|
10085
10230
|
new_parser.add_argument("--model", help="Model override (e.g., haiku, sonnet, opus)")
|
|
@@ -10222,6 +10367,10 @@ def main() -> int:
|
|
|
10222
10367
|
"--input-file", metavar="PATH",
|
|
10223
10368
|
help="JSON file with inputs (object mapping name → value)"
|
|
10224
10369
|
)
|
|
10370
|
+
wf_run.add_argument(
|
|
10371
|
+
"--runner", choices=["pi", "anthropic"], default=None,
|
|
10372
|
+
help="Override runner for every node in this run (YAML declarations ignored)."
|
|
10373
|
+
)
|
|
10225
10374
|
wf_run.add_argument("--dry-run", action="store_true", help="Print plan without running")
|
|
10226
10375
|
wf_run.add_argument("--verbose", "-v", action="store_true", help="Verbose output")
|
|
10227
10376
|
wf_run.add_argument("--json", action="store_true", help="Output as JSON")
|
|
@@ -166,8 +166,34 @@ def _get_email_config() -> EmailConfig:
|
|
|
166
166
|
return EmailConfig()
|
|
167
167
|
|
|
168
168
|
|
|
169
|
+
def _normalize_recipients(to: Optional[str | list[str]], default_to: str) -> list[str]:
|
|
170
|
+
"""Flatten `to` (str | list[str]) into a deduped list, splitting on commas.
|
|
171
|
+
|
|
172
|
+
Accepts: None, "a@x.com", "a@x.com,b@y.com", ["a@x.com"], ["a,b", "c"].
|
|
173
|
+
Falls back to `default_to` (also comma-split) when `to` is None/empty.
|
|
174
|
+
Preserves order, drops duplicates and empty entries.
|
|
175
|
+
"""
|
|
176
|
+
raw: list[str] = []
|
|
177
|
+
if not to:
|
|
178
|
+
raw = [default_to] if default_to else []
|
|
179
|
+
elif isinstance(to, str):
|
|
180
|
+
raw = [to]
|
|
181
|
+
else:
|
|
182
|
+
raw = list(to)
|
|
183
|
+
|
|
184
|
+
out: list[str] = []
|
|
185
|
+
seen: set[str] = set()
|
|
186
|
+
for entry in raw:
|
|
187
|
+
for part in str(entry).split(","):
|
|
188
|
+
addr = part.strip()
|
|
189
|
+
if addr and addr not in seen:
|
|
190
|
+
seen.add(addr)
|
|
191
|
+
out.append(addr)
|
|
192
|
+
return out
|
|
193
|
+
|
|
194
|
+
|
|
169
195
|
def send_email(
|
|
170
|
-
to: Optional[str] = None,
|
|
196
|
+
to: Optional[str | list[str]] = None,
|
|
171
197
|
subject: str = "",
|
|
172
198
|
body: str = "",
|
|
173
199
|
attachments: Optional[list[Path | str]] = None,
|
|
@@ -178,7 +204,8 @@ def send_email(
|
|
|
178
204
|
"""Send a branded email via Resend.
|
|
179
205
|
|
|
180
206
|
Args:
|
|
181
|
-
to: Recipient email
|
|
207
|
+
to: Recipient email(s). Accepts a single address, a comma-separated
|
|
208
|
+
string, or a list of either. Uses config default_to if not specified.
|
|
182
209
|
subject: Email subject line.
|
|
183
210
|
body: Email body (markdown supported, converted to HTML).
|
|
184
211
|
attachments: List of file paths to attach.
|
|
@@ -202,9 +229,9 @@ def send_email(
|
|
|
202
229
|
"or set channels.email.api_key in ~/.agentwire/config.yaml"
|
|
203
230
|
)
|
|
204
231
|
|
|
205
|
-
# Determine
|
|
206
|
-
|
|
207
|
-
if not
|
|
232
|
+
# Determine recipients (list form — Resend's `to` field accepts an array)
|
|
233
|
+
recipients = _normalize_recipients(to, email_config.default_to)
|
|
234
|
+
if not recipients:
|
|
208
235
|
raise EmailConfigError(
|
|
209
236
|
"No recipient specified and no default_to configured in "
|
|
210
237
|
"channels.email.default_to"
|
|
@@ -247,7 +274,7 @@ def send_email(
|
|
|
247
274
|
|
|
248
275
|
params: dict = {
|
|
249
276
|
"from": sender,
|
|
250
|
-
"to":
|
|
277
|
+
"to": recipients,
|
|
251
278
|
"subject": email_subject,
|
|
252
279
|
}
|
|
253
280
|
|