agentwire-dev 1.32.0__tar.gz → 1.34.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.32.0 → agentwire_dev-1.34.0}/PKG-INFO +1 -1
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/__init__.py +1 -1
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/__main__.py +23 -9
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/mcp_server.py +5 -2
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/server.py +46 -33
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/announcements.json +17 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/css/desktop.css +19 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/desktop.js +11 -13
- agentwire_dev-1.34.0/agentwire/static/js/notification-prefs.js +56 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar/config-section.js +56 -2
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/INDEX.md +1 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/quickstart.md +5 -1
- agentwire_dev-1.34.0/docs/wiki/sessions/window-sizing.md +102 -0
- agentwire_dev-1.34.0/tests/unit/test_terminal_resize.py +71 -0
- agentwire_dev-1.34.0/tests/unit/test_tts_engine_resolution.py +54 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/.github/FUNDING.yml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/.gitignore +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/CHANGELOG.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/CLA.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/CODE_OF_CONDUCT.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/CONTRIBUTING.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/Dockerfile.local +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/Dockerfile.runpod +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/LICENSE +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/README.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/RELEASING.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/SECURITY.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/SPONSORS.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/agents/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/agents/base.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/agents/tmux.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/cached_status.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/channels/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/channels/base.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/channels/email.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/channels/quo.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/cli_safety.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/completion.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/config.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/council/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/council/cli.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/council/inbox.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/council/state.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/fetch.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/handoff/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/handoff/git_state.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/handoff/instructions.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/handoff/parser.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/handoff/renderer.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/handoff/schema.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/history.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/agentwire-permission.sh +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/idle-handler.sh +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/hooks/queue-processor.sh +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/listen.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/locking.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/cli.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/config.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/dispatcher.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/eligibility.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/feedback_router.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/gc.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/github.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/naming.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/missions/state.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/network.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/onboarding.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/overnight.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/pane_manager.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/project_config.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/projects.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/prompts/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/prompts/init.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/agentwire.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/chatbot.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/council-brain.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/council-conscience.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/council-critic.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/council-devils-advocate.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/council-gut.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/council-historian.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/council-member.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/council-orchestrator.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/init.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/notifications.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/orchestrator.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/soul.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/task-runner.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/voice.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/roles/worker.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/safety/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/safety/_core.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/scheduler.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/scratchpad.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/search.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/security.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/services.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/session_ready.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-Echo--black.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-Echo--transparent.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-Echo.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-email-banner.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--transparent.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/agentwire-splash-logo-layers.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/favicon.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/android.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/automaton.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/bot.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/cyborg.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/droid.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/drone.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/guardian.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/mech.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/probe.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/robot.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/sentinel.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/machines/unit.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/blob.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/cloud.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/crystal.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/cyclops.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/flame.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/horned.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/moon.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/slime.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/star.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/tentacle.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/projects/winged.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/bear.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/cat.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/crown.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/deer.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/drone.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/eagle.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/fox.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/hawk.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/horse.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/lion.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/robot.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/tiger.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/icons/sessions/wolf.jpeg +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/.gitkeep +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/announcement-modal.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/api.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/artifact-window.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/collage.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/command-palette.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/components/icon-picker.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/components/list-card.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/components/type-tag.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/dead-key-suppressor.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/desktop-manager.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/icon-manager.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/notifications-panel.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/safety-shared.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/safety-window.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/scratchpad.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/session-id.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/session-window.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar/missions-section.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar/services-section.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/sidebar.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/tile-manager.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/token-modal.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/utils/ansi.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/utils/auto-refresh.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/voice/browser-stt.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/voice/browser-tts.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/voice/jargon.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/voice/prompt.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/stt/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/stt/base.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/stt/server_backend.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/stt/stt_server.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tasks.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/templates/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/templates/base.html +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/templates/desktop.html +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/templates/email_notification.html +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/templates/tmux.conf +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/templating.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/aws.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/docker.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/gcp.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/gh.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/git.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/gws.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/kubectl.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/npm.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/terraform.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tooldefs/uv.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/base.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/engines/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/engines/chatterbox.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/engines/kokoro.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/engines/qwen_base.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/engines/qwen_custom.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/engines/qwen_design.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/engines/zonos.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts/registry.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tts_server.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/tunnels.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/utils/__init__.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/utils/chunker.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/utils/file_io.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/utils/paths.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/utils/speech.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/utils/subprocess.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/validation.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/voiceclone.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/voices/darren.wav +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/voices/default.wav +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/voices/jessica.wav +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/voices/lisa.wav +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/voices/may.wav +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/agentwire/worktree.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/decisions/obsidian-second-brain.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/logo.png +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/architecture.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/communication/channels.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/communication/hammerspoon.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/communication/handoff.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/concepts.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/council.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/deployment/remote-access.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/deployment/remote-machines.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/glossary.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/internals/damage-control.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/internals/portal.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/internals/shell-escaping.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/internals/troubleshooting.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/internals/window-collage.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/missions.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/services.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/sessions/pi.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/voice/shim-contract.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/pyproject.toml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/requirements-tts.txt +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/templates/launchd/dev.agentwire.mission-dispatcher.plist +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/templates/launchd/dev.agentwire.mission-feedback-router.plist +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/templates/launchd/dev.agentwire.mission-janitor.plist +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/conftest.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/e2e/test_portal_ui.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/fixtures/sample_agentwire.yml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/fixtures/sample_config.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/fixtures/sample_scheduler.yaml +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/integration/test_missions_concurrency.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/integration/test_missions_lifecycle.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/integration/test_scheduler_board.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/integration/test_server_websockets.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_announcements.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_build_agent_command.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_channels.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_cli_commands.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_cli_output.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_cli_safety.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_config.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_council_cli.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_council_inbox.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_council_state.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_damage_control_hooks.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_damage_control_sync.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_file_io.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_handoff_git_state.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_handoff_instructions.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_handoff_parser.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_handoff_renderer.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_history.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_hooks_install.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_idle_handler.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_locking.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_mcp_server.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_mcp_tools_args.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_missions_cli.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_missions_config.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_missions_dispatcher.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_missions_eligibility.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_missions_feedback_router.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_missions_gc.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_missions_github.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_missions_naming.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_missions_state.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_overnight_resume_flags.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_portal_api.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_project_config.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_roles.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_safety_disabled_rules.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_safety_escape_hatch.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_safety_kill_switch.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_safety_mission_worker.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_scheduler.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_scheduler_parsing.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_scratchpad.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_search.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_security.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_server_async.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_server_pure.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_services.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_session_ready.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_speech_tags.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_stt_backend.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_tasks.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_templating.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_tmux_template.py +0 -0
- {agentwire_dev-1.32.0 → agentwire_dev-1.34.0}/tests/unit/test_worktree.py +0 -0
|
@@ -1194,6 +1194,18 @@ def _get_venv_for_backend(backend: str) -> str:
|
|
|
1194
1194
|
return "qwen"
|
|
1195
1195
|
|
|
1196
1196
|
|
|
1197
|
+
def _get_tts_engine(args, tts_config: dict) -> str:
|
|
1198
|
+
"""Resolve the TTS engine to run: --backend flag, then tts.options.backend.
|
|
1199
|
+
|
|
1200
|
+
The top-level tts.backend is the tier (default|custom), never an engine.
|
|
1201
|
+
"""
|
|
1202
|
+
return (
|
|
1203
|
+
getattr(args, "backend", None)
|
|
1204
|
+
or (tts_config.get("options") or {}).get("backend")
|
|
1205
|
+
or "chatterbox"
|
|
1206
|
+
)
|
|
1207
|
+
|
|
1208
|
+
|
|
1197
1209
|
def _start_tts_local(args, venv_override: str | None = None, attach: bool = True) -> int:
|
|
1198
1210
|
"""Start TTS server locally in tmux.
|
|
1199
1211
|
|
|
@@ -1216,7 +1228,7 @@ def _start_tts_local(args, venv_override: str | None = None, attach: bool = True
|
|
|
1216
1228
|
tts_config = config.get("tts", {})
|
|
1217
1229
|
port = args.port or tts_config.get("port", 8100)
|
|
1218
1230
|
host = args.host or tts_config.get("host", "0.0.0.0")
|
|
1219
|
-
backend =
|
|
1231
|
+
backend = _get_tts_engine(args, tts_config)
|
|
1220
1232
|
|
|
1221
1233
|
# Determine venv family
|
|
1222
1234
|
venv = venv_override or _get_venv_for_backend(backend)
|
|
@@ -1284,7 +1296,7 @@ def _start_tts_remote(ssh_target: str, machine_id: str, args) -> int:
|
|
|
1284
1296
|
tts_config = config.get("tts", {})
|
|
1285
1297
|
port = args.port or tts_config.get("port", 8100)
|
|
1286
1298
|
host = args.host or tts_config.get("host", "0.0.0.0")
|
|
1287
|
-
backend =
|
|
1299
|
+
backend = _get_tts_engine(args, tts_config)
|
|
1288
1300
|
|
|
1289
1301
|
# Build backend flag
|
|
1290
1302
|
backend_flag = f" --backend {backend}" if backend != "chatterbox" else ""
|
|
@@ -1392,7 +1404,7 @@ def cmd_tts_serve(args) -> int:
|
|
|
1392
1404
|
tts_config = config.get("tts", {})
|
|
1393
1405
|
port = args.port or tts_config.get("port", 8100)
|
|
1394
1406
|
host = args.host or tts_config.get("host", "0.0.0.0")
|
|
1395
|
-
backend =
|
|
1407
|
+
backend = _get_tts_engine(args, tts_config)
|
|
1396
1408
|
|
|
1397
1409
|
# Determine venv family (explicit or auto-detect from backend)
|
|
1398
1410
|
venv = getattr(args, "venv", None)
|
|
@@ -1478,8 +1490,7 @@ def cmd_tts_restart(args) -> int:
|
|
|
1478
1490
|
|
|
1479
1491
|
# Determine backend and venv
|
|
1480
1492
|
if not backend:
|
|
1481
|
-
|
|
1482
|
-
backend = config.get("tts", {}).get("backend", "chatterbox")
|
|
1493
|
+
backend = _get_tts_engine(args, load_config().get("tts", {}))
|
|
1483
1494
|
|
|
1484
1495
|
venv = venv_override or _get_venv_for_backend(backend)
|
|
1485
1496
|
|
|
@@ -4154,7 +4165,7 @@ def cmd_jump(args) -> int:
|
|
|
4154
4165
|
|
|
4155
4166
|
|
|
4156
4167
|
def cmd_resize(args) -> int:
|
|
4157
|
-
"""
|
|
4168
|
+
"""Re-fit tmux window to its attached clients per the window-size policy."""
|
|
4158
4169
|
json_mode = getattr(args, 'json', False)
|
|
4159
4170
|
session = getattr(args, 'session', None)
|
|
4160
4171
|
|
|
@@ -4165,8 +4176,11 @@ def cmd_resize(args) -> int:
|
|
|
4165
4176
|
return _output_result(False, json_mode, "Not in a tmux session. Use -s to specify session.")
|
|
4166
4177
|
|
|
4167
4178
|
try:
|
|
4179
|
+
# Unset any window-level window-size override (e.g. manual mode left
|
|
4180
|
+
# by resize-window -x/-y) so the configured policy re-fits the window.
|
|
4181
|
+
# resize-window -A would resize once but leave manual mode set (#258).
|
|
4168
4182
|
result = subprocess.run(
|
|
4169
|
-
["tmux", "
|
|
4183
|
+
["tmux", "set-option", "-w", "-t", session, "-u", "window-size"],
|
|
4170
4184
|
capture_output=True,
|
|
4171
4185
|
text=True,
|
|
4172
4186
|
)
|
|
@@ -4177,7 +4191,7 @@ def cmd_resize(args) -> int:
|
|
|
4177
4191
|
if json_mode:
|
|
4178
4192
|
_output_json({"success": True, "session": session})
|
|
4179
4193
|
else:
|
|
4180
|
-
print(f"
|
|
4194
|
+
print(f"Re-fit {session} to attached clients per window-size policy")
|
|
4181
4195
|
|
|
4182
4196
|
return 0
|
|
4183
4197
|
|
|
@@ -10469,7 +10483,7 @@ def main() -> int:
|
|
|
10469
10483
|
jump_parser.set_defaults(func=cmd_jump)
|
|
10470
10484
|
|
|
10471
10485
|
# === resize command (top-level) ===
|
|
10472
|
-
resize_parser = subparsers.add_parser("resize", help="
|
|
10486
|
+
resize_parser = subparsers.add_parser("resize", help="Re-fit window to attached clients per window-size policy")
|
|
10473
10487
|
resize_parser.add_argument("-s", "--session", help="Target session (default: auto-detect)")
|
|
10474
10488
|
resize_parser.add_argument("--json", action="store_true", help="Output as JSON")
|
|
10475
10489
|
resize_parser.set_defaults(func=cmd_resize)
|
|
@@ -1266,7 +1266,10 @@ def pane_jump(session: str | None = None, pane: int = 0) -> str:
|
|
|
1266
1266
|
|
|
1267
1267
|
@mcp.tool()
|
|
1268
1268
|
def pane_resize(session: str | None = None) -> str:
|
|
1269
|
-
"""
|
|
1269
|
+
"""Re-fit tmux window to its attached clients per the window-size policy.
|
|
1270
|
+
|
|
1271
|
+
Clears any manual size pin so the configured policy (largest/latest/
|
|
1272
|
+
smallest) governs again.
|
|
1270
1273
|
|
|
1271
1274
|
Args:
|
|
1272
1275
|
session: Session name (defaults to current session if in tmux)
|
|
@@ -1280,7 +1283,7 @@ def pane_resize(session: str | None = None) -> str:
|
|
|
1280
1283
|
|
|
1281
1284
|
data = run_agentwire_cmd(args)
|
|
1282
1285
|
if data.get("success"):
|
|
1283
|
-
return "Window
|
|
1286
|
+
return "Window re-fit to attached clients per window-size policy."
|
|
1284
1287
|
return f"Failed to resize: {data.get('error', 'Unknown error')}"
|
|
1285
1288
|
|
|
1286
1289
|
|
|
@@ -57,6 +57,31 @@ PASTE_CHUNK_SIZE = 128 # bytes per write
|
|
|
57
57
|
PASTE_CHUNK_DELAY = 0.01 # seconds between chunks
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
async def unpin_tmux_window(session_name: str, ssh_target: str | None = None) -> None:
|
|
61
|
+
"""Clear tmux manual size mode so the window-size policy governs again.
|
|
62
|
+
|
|
63
|
+
Portal builds before v1.34 pinned windows to manual mode on every
|
|
64
|
+
browser resize (#258); this heals any window still stuck there.
|
|
65
|
+
Unsetting the window-level option restores the configured policy and
|
|
66
|
+
itself triggers a re-fit. (An explicit -A resize would not: it resizes
|
|
67
|
+
once but leaves manual mode set.)
|
|
68
|
+
"""
|
|
69
|
+
cmd = ["tmux", "set-option", "-w", "-t", session_name, "-u", "window-size"]
|
|
70
|
+
if ssh_target:
|
|
71
|
+
proc = await asyncio.create_subprocess_exec(
|
|
72
|
+
"ssh", ssh_target, shlex.join(cmd),
|
|
73
|
+
stdout=asyncio.subprocess.DEVNULL,
|
|
74
|
+
stderr=asyncio.subprocess.DEVNULL,
|
|
75
|
+
)
|
|
76
|
+
else:
|
|
77
|
+
proc = await asyncio.create_subprocess_exec(
|
|
78
|
+
*cmd,
|
|
79
|
+
stdout=asyncio.subprocess.DEVNULL,
|
|
80
|
+
stderr=asyncio.subprocess.DEVNULL,
|
|
81
|
+
)
|
|
82
|
+
await proc.wait()
|
|
83
|
+
|
|
84
|
+
|
|
60
85
|
def _is_allowed_in_restricted_mode(tool_name: str, tool_input: dict) -> bool:
|
|
61
86
|
"""Check if command is allowed in restricted mode.
|
|
62
87
|
|
|
@@ -1804,10 +1829,13 @@ class AgentWireServer:
|
|
|
1804
1829
|
os.close(slave_fd)
|
|
1805
1830
|
os.set_blocking(master_fd, False)
|
|
1806
1831
|
|
|
1807
|
-
#
|
|
1808
|
-
winsize = struct.pack("HHHH",
|
|
1832
|
+
# Set initial PTY size from browser's reported dimensions
|
|
1833
|
+
winsize = struct.pack("HHHH", init_rows, init_cols, 0, 0)
|
|
1809
1834
|
fcntl.ioctl(master_fd, termios.TIOCSWINSZ, winsize)
|
|
1810
|
-
logger.info(f"[Terminal] Set initial PTY size for SSH to
|
|
1835
|
+
logger.info(f"[Terminal] Set initial PTY size for SSH to {init_cols}x{init_rows} (fd={master_fd})")
|
|
1836
|
+
|
|
1837
|
+
# Heal windows pinned to manual size mode by pre-v1.34 portals
|
|
1838
|
+
await unpin_tmux_window(session_name, ssh_target)
|
|
1811
1839
|
else:
|
|
1812
1840
|
# Local session - use PTY
|
|
1813
1841
|
cmd = ["tmux", "attach", "-t", session_name]
|
|
@@ -1842,6 +1870,9 @@ class AgentWireServer:
|
|
|
1842
1870
|
fcntl.ioctl(master_fd, termios.TIOCSWINSZ, winsize)
|
|
1843
1871
|
logger.info(f"[Terminal] Set initial PTY size to {init_cols}x{init_rows} (fd={master_fd})")
|
|
1844
1872
|
|
|
1873
|
+
# Heal windows pinned to manual size mode by pre-v1.34 portals
|
|
1874
|
+
await unpin_tmux_window(session_name)
|
|
1875
|
+
|
|
1845
1876
|
# Task: Forward tmux stdout → WebSocket
|
|
1846
1877
|
async def forward_tmux_to_ws():
|
|
1847
1878
|
"""Read from tmux and send to WebSocket."""
|
|
@@ -1963,40 +1994,22 @@ class AgentWireServer:
|
|
|
1963
1994
|
await asyncio.sleep(PASTE_CHUNK_DELAY)
|
|
1964
1995
|
|
|
1965
1996
|
elif msg_type == "resize":
|
|
1966
|
-
# Terminal resize
|
|
1997
|
+
# Terminal resize: update the PTY and notify the
|
|
1998
|
+
# tmux/ssh client via SIGWINCH. The window itself
|
|
1999
|
+
# is sized by tmux per the window-size policy —
|
|
2000
|
+
# never force it with resize-window -x/-y, which
|
|
2001
|
+
# pins the window into manual mode (#258).
|
|
1967
2002
|
cols = payload.get("cols", 80)
|
|
1968
2003
|
rows = payload.get("rows", 24)
|
|
1969
2004
|
logger.info(f"[Terminal] Resize {session_name} to {cols}x{rows}")
|
|
1970
2005
|
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
os.kill(proc.pid, signal.SIGWINCH)
|
|
1979
|
-
except (OSError, ProcessLookupError):
|
|
1980
|
-
pass # Process may have exited
|
|
1981
|
-
# Explicitly resize the tmux window to match the browser.
|
|
1982
|
-
# Using -x/-y instead of -A avoids the race condition where
|
|
1983
|
-
# tmux hasn't yet processed SIGWINCH when resize-window runs.
|
|
1984
|
-
resize_proc = await asyncio.create_subprocess_exec(
|
|
1985
|
-
"tmux", "resize-window", "-t", session_name,
|
|
1986
|
-
"-x", str(cols), "-y", str(rows),
|
|
1987
|
-
stdout=asyncio.subprocess.DEVNULL,
|
|
1988
|
-
stderr=asyncio.subprocess.DEVNULL,
|
|
1989
|
-
)
|
|
1990
|
-
await resize_proc.wait()
|
|
1991
|
-
else:
|
|
1992
|
-
# Remote: send tmux resize-window command
|
|
1993
|
-
resize_cmd = f"tmux resize-window -t {session_name} -x {cols} -y {rows}\n"
|
|
1994
|
-
resize_proc = await asyncio.create_subprocess_exec(
|
|
1995
|
-
"ssh", ssh_target, "sh", "-c", resize_cmd,
|
|
1996
|
-
stdout=asyncio.subprocess.DEVNULL,
|
|
1997
|
-
stderr=asyncio.subprocess.DEVNULL,
|
|
1998
|
-
)
|
|
1999
|
-
await resize_proc.wait()
|
|
2006
|
+
winsize = struct.pack("HHHH", rows, cols, 0, 0)
|
|
2007
|
+
fcntl.ioctl(master_fd, termios.TIOCSWINSZ, winsize)
|
|
2008
|
+
if proc and proc.pid:
|
|
2009
|
+
try:
|
|
2010
|
+
os.kill(proc.pid, signal.SIGWINCH)
|
|
2011
|
+
except (OSError, ProcessLookupError):
|
|
2012
|
+
pass # Process may have exited
|
|
2000
2013
|
|
|
2001
2014
|
except json.JSONDecodeError:
|
|
2002
2015
|
logger.warning(f"[Terminal] Invalid JSON from WebSocket: {msg.data}")
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"announcements": [
|
|
3
|
+
{
|
|
4
|
+
"id": "2026-06-window-sizing-fix",
|
|
5
|
+
"placement": "modal",
|
|
6
|
+
"emoji": "🪟",
|
|
7
|
+
"title": "Terminal sizing now respects your tmux config",
|
|
8
|
+
"date": "2026-06-09",
|
|
9
|
+
"body": "Until now, resizing the portal terminal silently forced the whole tmux window to the browser's size — pinning it into manual mode and breaking your window-size setting (largest/smallest/latest) for every connected terminal. Fixed: the portal now behaves like any other tmux client, your policy decides, and previously stuck windows heal automatically when you open them in the portal. If you liked 'the browser always wins', set window-size latest in ~/.tmux.conf. Tip: window-size smallest keeps sessions fully visible even on a phone or tablet.",
|
|
10
|
+
"highlights": [
|
|
11
|
+
"Your window-size policy works again — for every client",
|
|
12
|
+
"Stuck windows self-heal on portal attach (agentwire resize works too)",
|
|
13
|
+
"On a tablet? Try: set -g window-size smallest"
|
|
14
|
+
],
|
|
15
|
+
"cta": {
|
|
16
|
+
"label": "How window sizing works now",
|
|
17
|
+
"url": "https://github.com/dotdevdotdev/agentwire-dev/blob/main/docs/wiki/sessions/window-sizing.md"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
3
20
|
{
|
|
4
21
|
"id": "evergreen-feedback-2026-06",
|
|
5
22
|
"placement": "banner",
|
|
@@ -770,6 +770,25 @@ body {
|
|
|
770
770
|
border-color: var(--accent);
|
|
771
771
|
}
|
|
772
772
|
|
|
773
|
+
.sidebar-notif-mute {
|
|
774
|
+
display: flex;
|
|
775
|
+
align-items: center;
|
|
776
|
+
gap: 6px;
|
|
777
|
+
color: var(--text-muted);
|
|
778
|
+
font-size: 13px;
|
|
779
|
+
cursor: pointer;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
.sidebar-notif-mute input[type="checkbox"] {
|
|
783
|
+
accent-color: var(--accent);
|
|
784
|
+
cursor: pointer;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
.sidebar-display-hint {
|
|
788
|
+
color: var(--text-muted);
|
|
789
|
+
font-size: 12px;
|
|
790
|
+
}
|
|
791
|
+
|
|
773
792
|
/* Voice Indicator States */
|
|
774
793
|
#sidebarVoiceIndicator {
|
|
775
794
|
display: flex;
|
|
@@ -15,6 +15,7 @@ import { SessionWindow } from './session-window.js';
|
|
|
15
15
|
import { ArtifactWindow } from './artifact-window.js';
|
|
16
16
|
import { sidebar } from './sidebar.js';
|
|
17
17
|
import { buildSessionId, normalizeMachine, isLocalMachine } from './session-id.js';
|
|
18
|
+
import { notificationsActive } from './notification-prefs.js';
|
|
18
19
|
import { configSection } from './sidebar/config-section.js';
|
|
19
20
|
import { safetySection } from './sidebar/safety-section.js';
|
|
20
21
|
import { artifactsSection } from './sidebar/artifacts-section.js';
|
|
@@ -315,19 +316,16 @@ function handleSessionRenamed({ old_name, new_name }) {
|
|
|
315
316
|
* Shows desktop notification for background session activity.
|
|
316
317
|
*/
|
|
317
318
|
function handleWindowActivity({ session }) {
|
|
318
|
-
// Only notify if session window
|
|
319
|
-
if (desktop.getActiveWindow()
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
Notification.requestPermission();
|
|
329
|
-
}
|
|
330
|
-
}
|
|
319
|
+
// Only notify if the session window isn't the one you're looking at.
|
|
320
|
+
if (desktop.getActiveWindow() === session) return;
|
|
321
|
+
// Respects browser permission + the Config sidebar mute toggle.
|
|
322
|
+
// Enabling is done explicitly from Config → Desktop notifications, not here.
|
|
323
|
+
if (!notificationsActive()) return;
|
|
324
|
+
new Notification(`Activity in ${session}`, {
|
|
325
|
+
body: 'Session has new output',
|
|
326
|
+
icon: '/static/img/icon-192.png',
|
|
327
|
+
tag: `activity-${session}`, // Prevent duplicate notifications
|
|
328
|
+
});
|
|
331
329
|
}
|
|
332
330
|
|
|
333
331
|
// Tab / Shift+Tab to cycle open windows
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desktop notification preferences — frontend-only, per-browser.
|
|
3
|
+
*
|
|
4
|
+
* Two independent layers:
|
|
5
|
+
* - Browser permission ('default' | 'granted' | 'denied') — owned by the
|
|
6
|
+
* browser, requested via enableNotifications(). The portal can ask but
|
|
7
|
+
* cannot grant it; that's a per-origin browser decision.
|
|
8
|
+
* - A local "muted" toggle — lets the user silence bubbles without revoking
|
|
9
|
+
* the OS permission. Persisted in localStorage.
|
|
10
|
+
*
|
|
11
|
+
* Changing either dispatches `notification-pref-change` on window so the
|
|
12
|
+
* Config sidebar (and anything else) can repaint.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const MUTE_KEY = 'notificationsMuted';
|
|
16
|
+
export const NOTIFICATION_PREF_EVENT = 'notification-pref-change';
|
|
17
|
+
|
|
18
|
+
export function notificationsSupported() {
|
|
19
|
+
return typeof window !== 'undefined' && 'Notification' in window;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** 'unsupported' | 'default' | 'granted' | 'denied' */
|
|
23
|
+
export function getPermission() {
|
|
24
|
+
return notificationsSupported() ? Notification.permission : 'unsupported';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function isMuted() {
|
|
28
|
+
return localStorage.getItem(MUTE_KEY) === '1';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function setMuted(muted) {
|
|
32
|
+
if (muted) localStorage.setItem(MUTE_KEY, '1');
|
|
33
|
+
else localStorage.removeItem(MUTE_KEY);
|
|
34
|
+
window.dispatchEvent(new CustomEvent(NOTIFICATION_PREF_EVENT));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** True only when a bubble should actually be shown right now. */
|
|
38
|
+
export function notificationsActive() {
|
|
39
|
+
return getPermission() === 'granted' && !isMuted();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Ask the browser for permission if it hasn't been decided yet.
|
|
44
|
+
* Returns the resulting permission string. No-op (returns current state) if
|
|
45
|
+
* already granted/denied or unsupported.
|
|
46
|
+
*/
|
|
47
|
+
export async function enableNotifications() {
|
|
48
|
+
if (!notificationsSupported()) return 'unsupported';
|
|
49
|
+
let perm = Notification.permission;
|
|
50
|
+
if (perm === 'default') {
|
|
51
|
+
try { perm = await Notification.requestPermission(); }
|
|
52
|
+
catch { perm = Notification.permission; }
|
|
53
|
+
}
|
|
54
|
+
window.dispatchEvent(new CustomEvent(NOTIFICATION_PREF_EVENT));
|
|
55
|
+
return perm;
|
|
56
|
+
}
|
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
setTerminalFontSize, clearTerminalFontSize,
|
|
5
5
|
FONT_SIZE_MIN, FONT_SIZE_MAX, FONT_SIZE_EVENT,
|
|
6
6
|
} from '../terminal-font-prefs.js';
|
|
7
|
+
import {
|
|
8
|
+
getPermission, isMuted, setMuted, enableNotifications,
|
|
9
|
+
} from '../notification-prefs.js';
|
|
7
10
|
|
|
8
11
|
function renderDisplayPrefs() {
|
|
9
12
|
const current = getTerminalFontSize();
|
|
@@ -20,6 +23,55 @@ function renderDisplayPrefs() {
|
|
|
20
23
|
</div>`;
|
|
21
24
|
}
|
|
22
25
|
|
|
26
|
+
function renderNotificationPrefs() {
|
|
27
|
+
const perm = getPermission();
|
|
28
|
+
const muted = isMuted();
|
|
29
|
+
|
|
30
|
+
let status, control = '';
|
|
31
|
+
if (perm === 'unsupported') {
|
|
32
|
+
status = '<em>not supported</em>';
|
|
33
|
+
} else if (perm === 'denied') {
|
|
34
|
+
status = '<em>blocked</em>';
|
|
35
|
+
control = '<span class="sidebar-display-hint">Allow in browser site settings</span>';
|
|
36
|
+
} else if (perm === 'default') {
|
|
37
|
+
status = '<em>off</em>';
|
|
38
|
+
control = '<button class="sidebar-display-reset" data-action="enable-notifs">Enable</button>';
|
|
39
|
+
} else { // granted
|
|
40
|
+
status = muted ? 'muted' : 'on';
|
|
41
|
+
control = `<label class="sidebar-notif-mute"><input type="checkbox" data-action="mute-notifs"${muted ? ' checked' : ''}/> Mute</label>`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return `<div class="sidebar-display-prefs" data-notif-block>
|
|
45
|
+
<div class="sidebar-display-row">
|
|
46
|
+
<label class="sidebar-config-key">Desktop notifications</label>
|
|
47
|
+
<span class="sidebar-display-value" data-notif="status">${status}</span>
|
|
48
|
+
</div>
|
|
49
|
+
${control ? `<div class="sidebar-display-row">${control}</div>` : ''}
|
|
50
|
+
</div>`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function bindNotificationPrefs(body) {
|
|
54
|
+
const repaint = () => {
|
|
55
|
+
const block = body.querySelector('[data-notif-block]');
|
|
56
|
+
if (!block) return;
|
|
57
|
+
const tmp = document.createElement('div');
|
|
58
|
+
tmp.innerHTML = renderNotificationPrefs();
|
|
59
|
+
block.replaceWith(tmp.firstElementChild);
|
|
60
|
+
wire();
|
|
61
|
+
};
|
|
62
|
+
function wire() {
|
|
63
|
+
body.querySelector('[data-action="enable-notifs"]')?.addEventListener('click', async () => {
|
|
64
|
+
await enableNotifications();
|
|
65
|
+
repaint();
|
|
66
|
+
});
|
|
67
|
+
body.querySelector('[data-action="mute-notifs"]')?.addEventListener('change', (e) => {
|
|
68
|
+
setMuted(e.target.checked);
|
|
69
|
+
repaint();
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
wire();
|
|
73
|
+
}
|
|
74
|
+
|
|
23
75
|
function bindDisplayPrefs(body) {
|
|
24
76
|
const slider = body.querySelector('#termFontSize');
|
|
25
77
|
const valueEl = body.querySelector('[data-display="size"]');
|
|
@@ -54,11 +106,13 @@ export const configSection = {
|
|
|
54
106
|
else if (typeof value === 'object') display = `<code>${JSON.stringify(value)}</code>`;
|
|
55
107
|
return `<div class="sidebar-config-item"><span class="sidebar-config-key">${key}</span><span class="sidebar-config-val">${display}</span></div>`;
|
|
56
108
|
}).join('');
|
|
57
|
-
body.innerHTML = renderDisplayPrefs() + itemHtml;
|
|
109
|
+
body.innerHTML = renderDisplayPrefs() + renderNotificationPrefs() + itemHtml;
|
|
58
110
|
bindDisplayPrefs(body);
|
|
111
|
+
bindNotificationPrefs(body);
|
|
59
112
|
} catch (e) {
|
|
60
|
-
body.innerHTML = renderDisplayPrefs() + '<div class="sidebar-empty">Failed to load config</div>';
|
|
113
|
+
body.innerHTML = renderDisplayPrefs() + renderNotificationPrefs() + '<div class="sidebar-empty">Failed to load config</div>';
|
|
61
114
|
bindDisplayPrefs(body);
|
|
115
|
+
bindNotificationPrefs(body);
|
|
62
116
|
}
|
|
63
117
|
},
|
|
64
118
|
};
|
|
@@ -22,6 +22,7 @@ How AgentWire runs AI agents — session types, REPLs, and permission models.
|
|
|
22
22
|
|
|
23
23
|
- **[claude-code-auto-mode](sessions/claude-code-auto-mode.md)** — Auto mode session type with classifier safety net
|
|
24
24
|
- **[pi](sessions/pi.md)** — Pi coding agent (multi-provider: zai, deepseek, openai, openrouter, …)
|
|
25
|
+
- **[Window sizing](sessions/window-sizing.md)** — how tmux `window-size` policies interact with the portal (v1.33+ behavior change, healing stuck windows, policy picker)
|
|
25
26
|
- **[Custom services](services.md)** — registered long-running sessions: autostart on portal launch, watchdog health checks + restart with backoff, `agentwire services` CLI
|
|
26
27
|
- **[Council](council.md)** — multi-soul orchestrator sitting: fan a prompt out to lens sessions (brain, conscience, gut, critic, …), collect via file inbox, synthesize with attribution
|
|
27
28
|
|
|
@@ -56,7 +56,11 @@ bind -T copy-mode-vi v send -X begin-selection
|
|
|
56
56
|
bind -T copy-mode-vi y send -X copy-selection-and-cancel
|
|
57
57
|
unbind -T copy-mode-vi MouseDragEnd1Pane
|
|
58
58
|
|
|
59
|
-
#
|
|
59
|
+
# Multi-client sizing — pick the policy that fits how you view sessions:
|
|
60
|
+
# largest = big clients win; small viewers see a cropped view
|
|
61
|
+
# smallest = fit the smallest viewer (e.g. portal on a tablet) so the
|
|
62
|
+
# window is always fully visible everywhere
|
|
63
|
+
# latest = whoever resized last wins (tmux default)
|
|
60
64
|
set -g window-size largest
|
|
61
65
|
```
|
|
62
66
|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Terminal Window Sizing
|
|
2
|
+
|
|
3
|
+
> How tmux window sizing works with the portal — what changed in v1.33+, why,
|
|
4
|
+
> and how to pick the right policy for your setup.
|
|
5
|
+
|
|
6
|
+
## TL;DR
|
|
7
|
+
|
|
8
|
+
The portal used to **force** every tmux window to the browser's exact size on
|
|
9
|
+
every resize. As of v1.33+ ([#258](https://github.com/dotdevdotdev/agentwire-dev/issues/258),
|
|
10
|
+
[PR #263](https://github.com/dotdevdotdev/agentwire-dev/pull/263)) it no longer
|
|
11
|
+
does — the portal is now a polite tmux client that reports its size and lets
|
|
12
|
+
**your configured `window-size` policy** decide. Previously-stuck windows heal
|
|
13
|
+
automatically the next time you open them in the portal. If you ever wrote
|
|
14
|
+
workaround hooks to fight stuck windows, you can delete them.
|
|
15
|
+
|
|
16
|
+
## What was happening before
|
|
17
|
+
|
|
18
|
+
Every time you resized the portal's terminal window, the portal ran
|
|
19
|
+
`tmux resize-window -x <cols> -y <rows>` behind the scenes. In tmux, an
|
|
20
|
+
explicit `-x/-y` resize flips the window into **manual size mode** — the
|
|
21
|
+
window gets nailed to those exact dimensions and tmux stops looking at
|
|
22
|
+
attached clients entirely. Your `window-size largest` (or `smallest`, or
|
|
23
|
+
`latest`) setting was silently ignored from then on, for *every* client:
|
|
24
|
+
|
|
25
|
+
- Attach a native terminal (iTerm, Alacritty, …) next to the portal and
|
|
26
|
+
resize it — nothing happens. The window stays at whatever the portal
|
|
27
|
+
last set.
|
|
28
|
+
- `window-size smallest` ("fit my tablet") never worked.
|
|
29
|
+
- The pin was sticky: it survived the portal disconnecting, and even
|
|
30
|
+
un-pinning by hand didn't last, because the next portal resize re-pinned it.
|
|
31
|
+
|
|
32
|
+
Manual mode is implemented as a window-level `window-size manual` option that
|
|
33
|
+
overrides your global/session policy. You can see it on a stuck window with:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
tmux show-options -w -t <session> window-size # "window-size manual" = stuck
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## What happens now
|
|
40
|
+
|
|
41
|
+
1. **Portal resizes are just client resizes.** The portal updates its own
|
|
42
|
+
PTY and notifies tmux (SIGWINCH) — exactly what your native terminal does
|
|
43
|
+
when you drag its corner. tmux then sizes the window per your policy.
|
|
44
|
+
2. **Stuck windows self-heal.** When the portal attaches to a session, it
|
|
45
|
+
unsets any window-level `window-size` override. Windows pinned by older
|
|
46
|
+
portal versions snap back to policy-governed sizing the moment you open
|
|
47
|
+
them in the portal.
|
|
48
|
+
3. **`agentwire resize` (and the `pane_resize` MCP tool) heal too.** They
|
|
49
|
+
now clear the manual pin and re-fit per policy. (The old implementation
|
|
50
|
+
used `resize-window -A`, which — counterintuitively — resizes once but
|
|
51
|
+
*leaves* manual mode set.)
|
|
52
|
+
|
|
53
|
+
## Picking your `window-size` policy
|
|
54
|
+
|
|
55
|
+
Set one of these in `~/.tmux.conf` (then `tmux source-file ~/.tmux.conf`):
|
|
56
|
+
|
|
57
|
+
| Policy | Behavior | Pick it when |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `largest` | Window sized to the **biggest** attached client; smaller viewers see a cropped view | Your desktop terminal is primary; portal/tablet viewers just peek |
|
|
60
|
+
| `smallest` | Window sized to the **smallest** attached client; always fully visible everywhere | You connect from a tablet/phone and want to see the whole window |
|
|
61
|
+
| `latest` (tmux default) | Whoever resized last wins | You use one viewer at a time and want it to always fit |
|
|
62
|
+
|
|
63
|
+
```tmux
|
|
64
|
+
set -g window-size smallest
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Per-session override (e.g. one session should behave differently):
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
tmux set -w -t <session> window-size largest
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## What you might notice after upgrading
|
|
74
|
+
|
|
75
|
+
- **The portal no longer "always wins."** Under `largest` with a bigger
|
|
76
|
+
native terminal attached, resizing the browser won't reflow the window —
|
|
77
|
+
you'll see tmux's standard smaller-client view (content with padding, or
|
|
78
|
+
cropped). That's your policy working. Want the old "browser drives the
|
|
79
|
+
window" feel? Use `latest`.
|
|
80
|
+
- **A window suddenly fits properly on your phone** — that's the heal
|
|
81
|
+
kicking in.
|
|
82
|
+
|
|
83
|
+
## Cleanup: workaround hooks
|
|
84
|
+
|
|
85
|
+
If you added hooks like these to fight stuck windows, they're obsolete —
|
|
86
|
+
delete them (they're harmless, but they hard-pin a policy at the window
|
|
87
|
+
level and will override your global setting):
|
|
88
|
+
|
|
89
|
+
```tmux
|
|
90
|
+
# DELETE these if you have them — pre-v1.33 workarounds
|
|
91
|
+
set-hook -g client-attached 'set-option -t "#{session_name}" window-size largest'
|
|
92
|
+
set-hook -g after-new-session 'set-option window-size largest'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Troubleshooting
|
|
96
|
+
|
|
97
|
+
| Symptom | Cause | Fix |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| Window ignores all client resizes | Still pinned (portal not attached since upgrade) | Open it in the portal once, or run `agentwire resize -s <session>` |
|
|
100
|
+
| Window smaller than my terminal | Another (smaller) client is attached under `smallest` | Detach the other client (`tmux detach-client`), or switch policy |
|
|
101
|
+
| Browser resize doesn't reflow the window | Bigger client attached under `largest` | Expected — see policy table; use `latest` for last-touch-wins |
|
|
102
|
+
| `show-options -w` still says `manual` | Something re-pinned it | Check `~/.tmux.conf` for old workaround hooks (above) |
|