agentwire-dev 1.40.0__tar.gz → 1.41.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.40.0 → agentwire_dev-1.41.0}/PKG-INFO +1 -1
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/__init__.py +1 -1
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/council/state.py +55 -1
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/council/view.py +22 -3
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/council-member.md +17 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/server.py +53 -10
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/css/desktop.css +40 -1
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/css/mobile.css +3 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/command-palette.js +91 -4
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/council-window.js +45 -3
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/desktop.js +91 -21
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/mobile.js +32 -2
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/service-classification.js +9 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/session-window.js +18 -3
- agentwire_dev-1.41.0/agentwire/static/js/sidebar/council-section.js +114 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/sidebar/sessions-section.js +3 -2
- agentwire_dev-1.41.0/agentwire/static/js/utils/swipe.js +68 -0
- agentwire_dev-1.40.0/agentwire/static/js/sidebar/council-section.js +0 -89
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/.github/FUNDING.yml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/.github/workflows/pytest.yml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/.github/workflows/tts-smoke.yml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/.gitignore +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/CLA.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/CODE_OF_CONDUCT.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/CONTRIBUTING.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/Dockerfile.local +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/Dockerfile.runpod +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/LICENSE +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/README.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/RELEASING.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/SECURITY.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/SPONSORS.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/__main__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/agents/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/agents/base.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/agents/tmux.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/cached_status.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/channels/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/channels/base.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/channels/email.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/channels/quo.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/cli_safety.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/completion.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/config.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/council/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/council/cli.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/council/inbox.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/fetch.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/handoff/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/handoff/git_state.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/handoff/instructions.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/handoff/parser.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/handoff/renderer.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/handoff/schema.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/history.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/agentwire-permission.sh +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/idle-handler.sh +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/hooks/queue-processor.sh +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/inbox.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/limits_cli.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/listen.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/locking.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/mcp_server.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/msg_cli.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/network.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/onboarding.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/pane_manager.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/project_config.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/projects.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/prompt_router.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/prompts/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/prompts/init.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/prompts_cli.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/agentwire.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/chatbot.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/council-brain.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/council-conscience.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/council-critic.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/council-devils-advocate.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/council-gut.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/council-historian.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/council-orchestrator.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/init.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/notifications.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/orchestrator.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/soul.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/task-runner.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/voice.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/worker.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/roles/worktree-session.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/safety/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/safety/_core.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/scheduler.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/scratchpad.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/security.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/services.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/session_ready.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/ssh.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-Echo--black.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-Echo--transparent.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-Echo.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-email-banner.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--transparent.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/agentwire-splash-logo-layers.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/announcements.json +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/favicon.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/android.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/automaton.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/bot.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/cyborg.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/droid.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/drone.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/guardian.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/mech.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/probe.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/robot.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/sentinel.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/machines/unit.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/blob.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/cloud.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/crystal.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/cyclops.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/flame.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/horned.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/moon.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/slime.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/star.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/tentacle.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/projects/winged.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/bear.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/cat.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/crown.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/deer.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/drone.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/eagle.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/fox.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/hawk.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/horse.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/lion.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/robot.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/tiger.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/icons/sessions/wolf.jpeg +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/.gitkeep +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/announcement-modal.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/api.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/artifact-window.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/collage.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/components/icon-picker.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/components/list-card.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/components/type-tag.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/dead-key-suppressor.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/desktop-manager.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/icon-manager.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/notification-prefs.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/notifications-panel.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/safety-shared.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/safety-window.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/scratchpad.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/session-id.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/sidebar/config-section.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/sidebar/services-section.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/sidebar.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/tile-manager.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/toast.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/token-modal.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/utils/ansi.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/utils/auto-refresh.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/voice/browser-stt.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/voice/browser-tts.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/voice/jargon.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/voice/prompt.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/stt/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/stt/base.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/stt/cloud.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/stt/engine.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/stt/local.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/stt/server_backend.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/stt/stt_server.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tasks.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/templates/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/templates/base.html +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/templates/desktop.html +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/templates/email_notification.html +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/templates/mobile.html +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/templates/tmux.conf +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/templating.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/aws.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/docker.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/gcp.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/gh.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/git.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/gws.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/kubectl.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/npm.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/terraform.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tooldefs/uv.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/audio.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/base.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/engines/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/engines/chatterbox.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/engines/kokoro.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/engines/qwen_base.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/engines/qwen_custom.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/engines/qwen_design.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/engines/zonos.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/local.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts/registry.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tts_server.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/tunnels.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/usage_limit.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/utils/__init__.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/utils/chunker.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/utils/file_io.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/utils/paths.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/utils/speech.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/utils/subprocess.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/validation.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/voiceclone.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/voices/darren.wav +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/voices/default.wav +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/voices/jessica.wav +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/voices/lisa.wav +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/voices/may.wav +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/worktree.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/agentwire/worktree_registry.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/decisions/obsidian-second-brain.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/logo.png +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/INDEX.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/architecture.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/communication/channels.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/communication/hammerspoon.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/communication/handoff.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/concepts.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/council.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/deployment/remote-access.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/deployment/remote-machines.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/glossary.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/internals/damage-control.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/internals/portal.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/internals/shell-escaping.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/internals/troubleshooting.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/internals/window-collage.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/quickstart.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/security/secrets.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/services.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/sessions/messaging.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/sessions/pi.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/sessions/prompt-routing.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/sessions/window-sizing.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/sessions/worktree-sessions.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/usage-limit-recovery.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/voice/shim-contract.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/voice/stt-cloud.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/pyproject.toml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/requirements-tts.txt +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/conftest.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/e2e/test_portal_ui.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/fixtures/sample_agentwire.yml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/fixtures/sample_config.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/fixtures/sample_scheduler.yaml +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/integration/test_council_portal.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/integration/test_scheduler_board.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/integration/test_server_websockets.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/integration/test_worktree_cmd.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_announcements.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_build_agent_command.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_channels.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_cli_commands.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_cli_output.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_cli_safety.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_config.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_council_cli.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_council_inbox.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_council_state.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_council_view.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_damage_control_hooks.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_damage_control_sync.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_file_io.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_handoff_git_state.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_handoff_instructions.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_handoff_parser.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_handoff_renderer.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_history.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_hooks_install.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_idle_handler.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_inbox.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_locking.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_mcp_server.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_mcp_tools_args.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_msg_cli.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_portal_api.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_project_config.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_prompt_router.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_roles.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_safety_disabled_rules.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_safety_escape_hatch.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_safety_kill_switch.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_scheduler.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_scheduler_parsing.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_scratchpad.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_security.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_server_async.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_server_pure.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_services.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_session_ready.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_speech_tags.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_ssh.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_stt_backend.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_stt_cloud.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_stt_engine.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_task_cli.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_tasks.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_templating.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_terminal_resize.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_tmux_template.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_tts_engine_resolution.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_tts_local.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_usage_limit.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_validation.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_worktree.py +0 -0
- {agentwire_dev-1.40.0 → agentwire_dev-1.41.0}/tests/unit/test_worktree_registry.py +0 -0
|
@@ -69,6 +69,11 @@ def sitting_path(name: str) -> Path:
|
|
|
69
69
|
return council_dir(name) / "sitting.json"
|
|
70
70
|
|
|
71
71
|
|
|
72
|
+
def archive_path(name: str) -> Path:
|
|
73
|
+
"""Preserved record of a dismissed sitting (kept so threads stay browsable)."""
|
|
74
|
+
return council_dir(name) / "archive.json"
|
|
75
|
+
|
|
76
|
+
|
|
72
77
|
def workspace_dir(name: str) -> Path:
|
|
73
78
|
return council_dir(name) / "workspace"
|
|
74
79
|
|
|
@@ -195,13 +200,62 @@ def write_sitting(name: str, sitting: Sitting) -> None:
|
|
|
195
200
|
|
|
196
201
|
|
|
197
202
|
def clear_sitting(name: str) -> None:
|
|
198
|
-
"""End the sitting.
|
|
203
|
+
"""End the sitting. A thread that deliberated something is preserved to
|
|
204
|
+
``archive.json`` (so it stays browsable/re-askable from the UI), and the
|
|
205
|
+
``prompts/`` history is kept; only the live ``sitting.json`` is removed."""
|
|
206
|
+
sitting = read_sitting(name)
|
|
207
|
+
if sitting is not None and prompts_dir(name).is_dir():
|
|
208
|
+
data = sitting.to_dict()
|
|
209
|
+
data["dismissed_at"] = now_iso()
|
|
210
|
+
try:
|
|
211
|
+
_atomic_write(archive_path(name), data)
|
|
212
|
+
except OSError:
|
|
213
|
+
pass
|
|
199
214
|
try:
|
|
200
215
|
sitting_path(name).unlink()
|
|
201
216
|
except FileNotFoundError:
|
|
202
217
|
pass
|
|
203
218
|
|
|
204
219
|
|
|
220
|
+
def read_archive_dict(name: str) -> dict | None:
|
|
221
|
+
"""Raw archive record (incl. ``dismissed_at``), or None if not archived."""
|
|
222
|
+
path = archive_path(name)
|
|
223
|
+
if not path.exists():
|
|
224
|
+
return None
|
|
225
|
+
try:
|
|
226
|
+
with open(path) as f:
|
|
227
|
+
data = json.load(f)
|
|
228
|
+
except (json.JSONDecodeError, OSError):
|
|
229
|
+
return None
|
|
230
|
+
return data if isinstance(data, dict) else None
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def read_archived(name: str) -> Sitting | None:
|
|
234
|
+
"""The preserved record of a dismissed sitting as a ``Sitting``, or None."""
|
|
235
|
+
data = read_archive_dict(name)
|
|
236
|
+
return Sitting.from_dict(data) if data is not None else None
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def _has_rounds(name: str) -> bool:
|
|
240
|
+
pdir = prompts_dir(name)
|
|
241
|
+
if not pdir.is_dir():
|
|
242
|
+
return False
|
|
243
|
+
return any(p.is_dir() and p.name.isdigit() for p in pdir.iterdir())
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def list_archive() -> list[str]:
|
|
247
|
+
"""Dismissed threads: have prompt history but no live ``sitting.json``."""
|
|
248
|
+
if not COUNCIL_ROOT.is_dir():
|
|
249
|
+
return []
|
|
250
|
+
out = []
|
|
251
|
+
for child in COUNCIL_ROOT.iterdir():
|
|
252
|
+
if not child.is_dir() or (child / "sitting.json").exists():
|
|
253
|
+
continue # absent or still live
|
|
254
|
+
if _has_rounds(child.name):
|
|
255
|
+
out.append(child.name)
|
|
256
|
+
return out
|
|
257
|
+
|
|
258
|
+
|
|
205
259
|
def allocate_prompt_id(name: str) -> int:
|
|
206
260
|
"""Bump and persist the sitting's prompt counter; return the new id.
|
|
207
261
|
|
|
@@ -143,13 +143,31 @@ def snapshot(
|
|
|
143
143
|
the sitting ``name``; the per-prompt ``meta.json.roster`` (falling back to
|
|
144
144
|
the sitting roster) fixes both soul order and grid size — nothing is
|
|
145
145
|
hardcoded to a roster of six.
|
|
146
|
+
|
|
147
|
+
The thread artifact outlives the compute: a dismissed sitting (no live
|
|
148
|
+
``sitting.json``) is still a fully readable thread, derived from the
|
|
149
|
+
preserved ``archive.json`` or, failing that, reconstructed from the
|
|
150
|
+
``prompts/`` tree. ``archived`` flags which case the caller is looking at.
|
|
146
151
|
"""
|
|
147
152
|
sitting = state.read_sitting(name)
|
|
153
|
+
archived = sitting is None
|
|
148
154
|
if sitting is None:
|
|
149
|
-
|
|
150
|
-
|
|
155
|
+
sitting = state.read_archived(name)
|
|
156
|
+
if sitting is None:
|
|
157
|
+
if not available_prompt_ids(name):
|
|
158
|
+
return None
|
|
159
|
+
sitting = state.Sitting(
|
|
160
|
+
orchestrator=state.orchestrator_for(name),
|
|
161
|
+
roster=[],
|
|
162
|
+
sessions={},
|
|
163
|
+
started_at="",
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
# available_prompt_ids (disk-derived) works for live and archived alike —
|
|
167
|
+
# the sitting.json prompt counter is gone once dismissed.
|
|
151
168
|
if prompt_id is None:
|
|
152
|
-
|
|
169
|
+
ids = available_prompt_ids(name)
|
|
170
|
+
prompt_id = ids[-1] if ids else None
|
|
153
171
|
|
|
154
172
|
dead_souls = dead_souls or set()
|
|
155
173
|
|
|
@@ -178,6 +196,7 @@ def snapshot(
|
|
|
178
196
|
"tiles": tiles,
|
|
179
197
|
"total": len(tiles),
|
|
180
198
|
"final": final,
|
|
199
|
+
"archived": archived,
|
|
181
200
|
}
|
|
182
201
|
|
|
183
202
|
|
|
@@ -32,6 +32,23 @@ The full prompt text is also on disk — the `[COUNCIL PROMPT #N]` message gives
|
|
|
32
32
|
the exact path (under `~/.agentwire/council/<council>/prompts/<NNNN>/prompt.md`)
|
|
33
33
|
if the message was truncated.
|
|
34
34
|
|
|
35
|
+
## Memory — consult past deliberations
|
|
36
|
+
|
|
37
|
+
Earlier rounds and earlier sittings are on disk; a take grounded in what this
|
|
38
|
+
council already concluded beats one argued from scratch. Before answering a
|
|
39
|
+
question that echoes past work, read the history:
|
|
40
|
+
|
|
41
|
+
- **This sitting's earlier rounds** — `~/.agentwire/council/<council>/prompts/`
|
|
42
|
+
holds every round (`NNNN/prompt.md` + `replies/<soul>.*.md`). Skim them so you
|
|
43
|
+
don't re-litigate a settled point or contradict your own prior take.
|
|
44
|
+
- **Other councils' threads (incl. archived/dismissed)** — sibling directories
|
|
45
|
+
under `~/.agentwire/council/<other>/prompts/` are durable thread artifacts that
|
|
46
|
+
outlive their sessions. When a decision was made elsewhere, cite it.
|
|
47
|
+
|
|
48
|
+
Keep it cheap: a quick `ls`/read of the relevant `prompts/` dir, not an
|
|
49
|
+
exhaustive trawl. When a past round changes your answer, say so in your take
|
|
50
|
+
(e.g. "consistent with round 2's call to …") so the orchestrator can attribute it.
|
|
51
|
+
|
|
35
52
|
## Rules
|
|
36
53
|
|
|
37
54
|
- **Passing is expected and free.** If your lens has nothing real to add, pass.
|
|
@@ -308,6 +308,7 @@ class AgentWireServer:
|
|
|
308
308
|
self.app.router.add_get("/api/scheduler/output", self.api_scheduler_session_output)
|
|
309
309
|
# Council seating board: live sittings + per-prompt snapshot
|
|
310
310
|
self.app.router.add_get("/api/council/sittings", self.api_council_sittings)
|
|
311
|
+
self.app.router.add_get("/api/council/archive", self.api_council_archive)
|
|
311
312
|
self.app.router.add_get("/api/council/live", self.api_council_live)
|
|
312
313
|
self.app.router.add_get("/api/council/status", self.api_council_status)
|
|
313
314
|
self.app.router.add_post("/api/council/start", self.api_council_start)
|
|
@@ -5007,6 +5008,48 @@ projects:
|
|
|
5007
5008
|
except Exception as e:
|
|
5008
5009
|
return web.json_response({"error": str(e)}, status=500)
|
|
5009
5010
|
|
|
5011
|
+
async def api_council_archive(self, request: web.Request) -> web.Response:
|
|
5012
|
+
"""GET /api/council/archive - Dismissed threads, newest first.
|
|
5013
|
+
|
|
5014
|
+
Each entry: ``{name, rounds, last_prompt_text, dismissed_at, cwd}`` —
|
|
5015
|
+
enough for the sidebar to list past deliberations; the board reads the
|
|
5016
|
+
full thread via ``/api/council/live?sitting=<name>``.
|
|
5017
|
+
"""
|
|
5018
|
+
try:
|
|
5019
|
+
from .council import state as council_state
|
|
5020
|
+
from .council import inbox as council_inbox
|
|
5021
|
+
from .council import view as council_view
|
|
5022
|
+
|
|
5023
|
+
out = []
|
|
5024
|
+
for name in council_state.list_archive():
|
|
5025
|
+
ids = council_view.available_prompt_ids(name)
|
|
5026
|
+
last_text = ""
|
|
5027
|
+
if ids:
|
|
5028
|
+
last_text = self._read_text_safe(
|
|
5029
|
+
council_inbox.prompt_dir(name, ids[-1]) / "prompt.md"
|
|
5030
|
+
)
|
|
5031
|
+
rec = council_state.read_archive_dict(name) or {}
|
|
5032
|
+
out.append(
|
|
5033
|
+
{
|
|
5034
|
+
"name": name,
|
|
5035
|
+
"rounds": len(ids),
|
|
5036
|
+
"last_prompt_text": last_text,
|
|
5037
|
+
"dismissed_at": rec.get("dismissed_at", ""),
|
|
5038
|
+
"cwd": rec.get("cwd", ""),
|
|
5039
|
+
}
|
|
5040
|
+
)
|
|
5041
|
+
out.sort(key=lambda e: e.get("dismissed_at", ""), reverse=True)
|
|
5042
|
+
return web.json_response({"archive": out})
|
|
5043
|
+
except Exception as e:
|
|
5044
|
+
return web.json_response({"error": str(e)}, status=500)
|
|
5045
|
+
|
|
5046
|
+
@staticmethod
|
|
5047
|
+
def _read_text_safe(path) -> str:
|
|
5048
|
+
try:
|
|
5049
|
+
return path.read_text()
|
|
5050
|
+
except OSError:
|
|
5051
|
+
return ""
|
|
5052
|
+
|
|
5010
5053
|
async def api_council_live(self, request: web.Request) -> web.Response:
|
|
5011
5054
|
"""GET /api/council/live - Board snapshot for a sitting (mirrors
|
|
5012
5055
|
/api/scheduler/live).
|
|
@@ -5033,20 +5076,20 @@ projects:
|
|
|
5033
5076
|
{"running": False, "sittings": live}, status=409
|
|
5034
5077
|
)
|
|
5035
5078
|
|
|
5036
|
-
sitting
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
status=404,
|
|
5041
|
-
)
|
|
5042
|
-
|
|
5079
|
+
# A dismissed thread has no live sitting.json but is still a fully
|
|
5080
|
+
# readable artifact (archive.json + prompts/). Only 404 when there
|
|
5081
|
+
# is genuinely nothing on disk.
|
|
5082
|
+
live = council_state.read_sitting(name)
|
|
5043
5083
|
prompt_id_raw = request.query.get("prompt_id")
|
|
5044
5084
|
prompt_id = int(prompt_id_raw) if prompt_id_raw else None
|
|
5045
|
-
dead = await self._council_dead_souls(
|
|
5085
|
+
dead = await self._council_dead_souls(live) if live else set()
|
|
5046
5086
|
snap = council_view.snapshot(name, prompt_id, dead_souls=dead)
|
|
5047
5087
|
if snap is None:
|
|
5048
|
-
return web.json_response(
|
|
5049
|
-
|
|
5088
|
+
return web.json_response(
|
|
5089
|
+
{"running": False, "sittings": council_state.list_sittings()},
|
|
5090
|
+
status=404,
|
|
5091
|
+
)
|
|
5092
|
+
snap["running"] = live is not None
|
|
5050
5093
|
snap["sittings"] = council_state.list_sittings()
|
|
5051
5094
|
return web.json_response(snap)
|
|
5052
5095
|
except Exception as e:
|
|
@@ -141,6 +141,23 @@ body {
|
|
|
141
141
|
position: relative;
|
|
142
142
|
overflow: hidden;
|
|
143
143
|
background: var(--background);
|
|
144
|
+
/* Tablets: keep vertical pan native (terminal scroll) but hand horizontal
|
|
145
|
+
drags to JS for swipe-to-cycle instead of browser back/forward nav. */
|
|
146
|
+
touch-action: pan-y;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* Window content must also opt into pan-y. WebKit/iPadOS resolves touch-action
|
|
150
|
+
on the directly-touched element rather than reliably intersecting with the
|
|
151
|
+
ancestor, so an xterm terminal / Monitor <pre> left at the default `auto`
|
|
152
|
+
lets the browser claim horizontal swipes — that's why swipe-to-cycle only
|
|
153
|
+
fired once the terminal was focused. Forcing pan-y here hands every
|
|
154
|
+
horizontal drag over a window to JS regardless of focus. */
|
|
155
|
+
.wb-body,
|
|
156
|
+
.xterm,
|
|
157
|
+
.xterm-viewport,
|
|
158
|
+
.xterm-screen,
|
|
159
|
+
.session-output {
|
|
160
|
+
touch-action: pan-y;
|
|
144
161
|
}
|
|
145
162
|
|
|
146
163
|
.desktop-wallpaper {
|
|
@@ -1608,6 +1625,13 @@ body {
|
|
|
1608
1625
|
border-color: var(--accent);
|
|
1609
1626
|
}
|
|
1610
1627
|
|
|
1628
|
+
.cmdk-council-note {
|
|
1629
|
+
margin: 8px 2px 0;
|
|
1630
|
+
font-size: 11px;
|
|
1631
|
+
line-height: 1.4;
|
|
1632
|
+
color: var(--text-dim, var(--muted-foreground, #94a3b8));
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1611
1635
|
.cmdk-idea-mic {
|
|
1612
1636
|
position: absolute;
|
|
1613
1637
|
top: 6px;
|
|
@@ -5961,4 +5985,19 @@ body.sidebar-pinned .sidebar-tab {
|
|
|
5961
5985
|
}
|
|
5962
5986
|
.council-section-item:hover { background: var(--hover); }
|
|
5963
5987
|
.council-section-name { font-weight: 600; font-size: 13px; }
|
|
5964
|
-
.council-section-count { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
|
|
5988
|
+
.council-section-count { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
5989
|
+
.council-section-item--open { border-style: dashed; }
|
|
5990
|
+
.council-section-subhead {
|
|
5991
|
+
margin: 10px 2px 2px; font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
|
|
5992
|
+
text-transform: uppercase; color: var(--text-muted);
|
|
5993
|
+
}
|
|
5994
|
+
.council-section-item--archived { flex-wrap: wrap; opacity: 0.85; }
|
|
5995
|
+
.council-section-item--archived:hover { opacity: 1; }
|
|
5996
|
+
.council-section-snip {
|
|
5997
|
+
flex-basis: 100%; font-size: 11px; color: var(--text-muted); font-weight: 400;
|
|
5998
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
5999
|
+
}
|
|
6000
|
+
.council-archived-tag {
|
|
6001
|
+
font-size: 9px; font-weight: 700; letter-spacing: 0.1em; padding: 2px 6px; border-radius: 4px;
|
|
6002
|
+
background: rgba(255,255,255,0.06); color: var(--text-muted); border: 1px solid var(--chrome-border);
|
|
6003
|
+
}
|
|
@@ -44,6 +44,9 @@ html, body {
|
|
|
44
44
|
max-width: 560px;
|
|
45
45
|
margin: 0 auto;
|
|
46
46
|
padding: env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left);
|
|
47
|
+
/* Vertical scrolling stays native; horizontal drags are handed to JS for
|
|
48
|
+
swipe-to-cycle (setupSwipeCycling) instead of becoming scroll/back-nav. */
|
|
49
|
+
touch-action: pan-y;
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
/* Header */
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Command Palette — unified Cmd/Ctrl+K launcher for quick create/open actions.
|
|
3
3
|
*
|
|
4
|
-
* Cmd/Ctrl+K opens
|
|
5
|
-
*
|
|
4
|
+
* Cmd/Ctrl+K opens the root list with "Ask council" selected by default (Esc
|
|
5
|
+
* closes). Root view actions:
|
|
6
|
+
* - Ask council → open the council board to seat/ask a question
|
|
6
7
|
* - New idea → idea (typed or dictated) + derived name → create project
|
|
7
8
|
* → spawn session → idea delivered as the agent's first
|
|
8
9
|
* message → open (you watch it land live)
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
|
|
17
18
|
import { apiFetch } from './api.js';
|
|
18
19
|
import { normalizeMachine, sameMachine } from './session-id.js';
|
|
19
|
-
import { isService } from './service-classification.js';
|
|
20
|
+
import { isService, isCouncil } from './service-classification.js';
|
|
20
21
|
import * as browserStt from './voice/browser-stt.js';
|
|
21
22
|
|
|
22
23
|
const PILL_TYPES = ['feat', 'fix', 'chore', 'refactor', 'docs'];
|
|
@@ -33,6 +34,7 @@ let currentView = 'root'; // 'root' | 'new-idea' | 'new-session' | 'workt
|
|
|
33
34
|
let prefillProject = '';
|
|
34
35
|
|
|
35
36
|
const COMMANDS = [
|
|
37
|
+
{ id: 'ask-council', icon: '🏛', label: 'Ask council', keywords: 'council ask question deliberate lenses brainstorm advice decide soul', run: () => setView('ask-council') },
|
|
36
38
|
{ id: 'new-idea', icon: '💡', label: 'New idea', keywords: 'idea create new project repo clone git init build start', run: () => setView('new-idea') },
|
|
37
39
|
{ id: 'new-session', icon: '▶', label: 'New session', keywords: 'create new session start spawn run project', run: () => setView('new-session') },
|
|
38
40
|
{ id: 'worktree', icon: '⎇', label: 'New worktree', keywords: 'worktree branch quicktask task feat fix base', run: () => setView('worktree') },
|
|
@@ -123,7 +125,7 @@ async function loadSessions() {
|
|
|
123
125
|
if (!names.has(s.name)) out.push(s);
|
|
124
126
|
}
|
|
125
127
|
} catch (e) { /* ignore */ }
|
|
126
|
-
sessionsCache = out.filter((s) => !isService(s.name || ''));
|
|
128
|
+
sessionsCache = out.filter((s) => !isService(s.name || '') && !isCouncil(s.name || ''));
|
|
127
129
|
return sessionsCache;
|
|
128
130
|
}
|
|
129
131
|
|
|
@@ -571,6 +573,87 @@ function bindWorktreeForm(form) {
|
|
|
571
573
|
});
|
|
572
574
|
}
|
|
573
575
|
|
|
576
|
+
// ---------------------------------------------------------------------------
|
|
577
|
+
// Ask council — question-first front door (seat-if-needed → ask → watch board)
|
|
578
|
+
// ---------------------------------------------------------------------------
|
|
579
|
+
|
|
580
|
+
function askCouncilFormHtml() {
|
|
581
|
+
return `
|
|
582
|
+
<div class="quicktask-error" data-error hidden></div>
|
|
583
|
+
<div class="quicktask-progress" data-progress hidden></div>
|
|
584
|
+
<form class="quicktask-form" data-form="ask-council">
|
|
585
|
+
<label class="quicktask-field">
|
|
586
|
+
<span class="quicktask-label">Ask the council</span>
|
|
587
|
+
<textarea name="prompt" class="cmdk-idea-input" rows="4"
|
|
588
|
+
placeholder="A question or decision to put to the lenses…"
|
|
589
|
+
autocomplete="off" spellcheck="false"></textarea>
|
|
590
|
+
</label>
|
|
591
|
+
<p class="cmdk-council-note">One model, six lenses — structured self-critique, not a panel of experts. Seats a council if none is live (~6 sessions).</p>
|
|
592
|
+
<div class="quicktask-footer">
|
|
593
|
+
<button type="button" class="quicktask-btn-cancel" data-action="back">Back</button>
|
|
594
|
+
<button type="submit" class="quicktask-btn-submit">Convene & ask</button>
|
|
595
|
+
</div>
|
|
596
|
+
</form>`;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
function bindAskCouncilForm(form) {
|
|
600
|
+
const input = form.querySelector('textarea[name="prompt"]');
|
|
601
|
+
// Enter submits; Shift+Enter for a newline. Escape must bubble to the
|
|
602
|
+
// palette's overlay handler (goBack), so don't swallow it.
|
|
603
|
+
input?.addEventListener('keydown', (e) => {
|
|
604
|
+
if (e.key === 'Escape') return;
|
|
605
|
+
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); form.requestSubmit(); }
|
|
606
|
+
e.stopPropagation(); // keep other keystrokes off global shortcuts
|
|
607
|
+
});
|
|
608
|
+
form.addEventListener('submit', async (e) => {
|
|
609
|
+
e.preventDefault();
|
|
610
|
+
const prompt = input.value.trim();
|
|
611
|
+
if (!prompt) { input.focus(); return; }
|
|
612
|
+
await submitAskCouncil(prompt);
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/** Resolve a sitting (seat one if none live), fan the prompt out, open the board.
|
|
617
|
+
* Fire-and-forget: we don't wait for the takes — the board fills them live. */
|
|
618
|
+
async function submitAskCouncil(prompt) {
|
|
619
|
+
showProgress('Convening the council…');
|
|
620
|
+
try {
|
|
621
|
+
let sitting = null;
|
|
622
|
+
const sres = await apiFetch('/api/council/sittings');
|
|
623
|
+
const live = (sres.ok ? (await sres.json()).sittings : []) || [];
|
|
624
|
+
if (live.length === 1) {
|
|
625
|
+
sitting = live[0];
|
|
626
|
+
} else if (live.length === 0) {
|
|
627
|
+
showProgress('Seating the council…');
|
|
628
|
+
const st = await apiFetch('/api/council/start', { method: 'POST' });
|
|
629
|
+
const sd = await st.json().catch(() => ({}));
|
|
630
|
+
if (!st.ok) { showError(sd.error || 'Could not seat the council.'); return; }
|
|
631
|
+
sitting = sd.council || null;
|
|
632
|
+
} else {
|
|
633
|
+
// Several live — let the user pick which chamber in the board.
|
|
634
|
+
closeCommandPalette();
|
|
635
|
+
const { openCouncilWindow } = await import('./desktop.js');
|
|
636
|
+
openCouncilWindow(null);
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
showProgress('Asking the council…');
|
|
640
|
+
const body = { prompt };
|
|
641
|
+
if (sitting) body.sitting = sitting;
|
|
642
|
+
const ares = await apiFetch('/api/council/ask', {
|
|
643
|
+
method: 'POST',
|
|
644
|
+
headers: { 'Content-Type': 'application/json' },
|
|
645
|
+
body: JSON.stringify(body),
|
|
646
|
+
});
|
|
647
|
+
const adata = await ares.json().catch(() => ({}));
|
|
648
|
+
if (!ares.ok) { showError(adata.error || 'Could not ask the council.'); return; }
|
|
649
|
+
closeCommandPalette();
|
|
650
|
+
const { openCouncilWindow } = await import('./desktop.js');
|
|
651
|
+
openCouncilWindow(sitting || adata.council || null);
|
|
652
|
+
} catch (err) {
|
|
653
|
+
showError(err?.message || 'Network error');
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
574
657
|
// ---------------------------------------------------------------------------
|
|
575
658
|
// List views (root + open-session)
|
|
576
659
|
// ---------------------------------------------------------------------------
|
|
@@ -650,10 +733,14 @@ function renderView() {
|
|
|
650
733
|
if (currentView === 'new-idea') {
|
|
651
734
|
footer.textContent = '↵ create & run · ⇧↵ newline · esc back';
|
|
652
735
|
body.innerHTML = newIdeaFormHtml();
|
|
736
|
+
} else if (currentView === 'ask-council') {
|
|
737
|
+
footer.textContent = '↵ convene & ask · ⇧↵ newline · esc back';
|
|
738
|
+
body.innerHTML = askCouncilFormHtml();
|
|
653
739
|
} else if (currentView === 'new-session') body.innerHTML = newSessionFormHtml();
|
|
654
740
|
else if (currentView === 'worktree') body.innerHTML = worktreeFormHtml();
|
|
655
741
|
const form = body.querySelector('.quicktask-form');
|
|
656
742
|
if (currentView === 'new-idea') bindNewIdeaForm(form);
|
|
743
|
+
else if (currentView === 'ask-council') bindAskCouncilForm(form);
|
|
657
744
|
else if (currentView === 'new-session') bindNewSessionForm(form);
|
|
658
745
|
else if (currentView === 'worktree') bindWorktreeForm(form);
|
|
659
746
|
}
|
|
@@ -44,6 +44,8 @@ const state = {
|
|
|
44
44
|
roundTexts: {}, // prompt_id -> question text, cached as rounds are visited
|
|
45
45
|
liveness: {}, // soul -> bool (lens session alive — from /status)
|
|
46
46
|
seated: false, // is a sitting present at all
|
|
47
|
+
archived: false, // viewing a dismissed thread (no live sessions)
|
|
48
|
+
running: true, // a live sitting backs the view
|
|
47
49
|
busy: false, // a seat/ask/dismiss POST is in flight
|
|
48
50
|
};
|
|
49
51
|
|
|
@@ -157,6 +159,8 @@ async function loadSnapshot(sitting, promptId) {
|
|
|
157
159
|
function applySnapshot(snap) {
|
|
158
160
|
state.sitting = snap.sitting;
|
|
159
161
|
state.seated = true;
|
|
162
|
+
state.archived = !!snap.archived; // dismissed thread, no live sessions
|
|
163
|
+
state.running = snap.running !== false; // live sitting present
|
|
160
164
|
state.promptId = snap.prompt_id;
|
|
161
165
|
state.promptIds = snap.prompt_ids || [];
|
|
162
166
|
state.latestPromptId = state.promptIds.length
|
|
@@ -295,6 +299,15 @@ function seatControlHtml() {
|
|
|
295
299
|
${state.busy ? 'Seating…' : 'Seat the council'}
|
|
296
300
|
</button>`;
|
|
297
301
|
}
|
|
302
|
+
if (state.archived) {
|
|
303
|
+
// Dismissed thread: read-only, no live sessions to dismiss. Re-asking
|
|
304
|
+
// (from the ask row) re-seats the same roster under the same name.
|
|
305
|
+
return `
|
|
306
|
+
<span class="council-seat-summary council-seat-summary--archived">
|
|
307
|
+
<span class="council-counter">${esc(counterText())}</span>
|
|
308
|
+
<span class="council-archived-tag">ARCHIVED</span>
|
|
309
|
+
</span>`;
|
|
310
|
+
}
|
|
298
311
|
return `
|
|
299
312
|
<span class="council-seat-summary"><span class="council-seat-led"></span><span class="council-counter">${esc(counterText())}</span></span>
|
|
300
313
|
<button class="council-btn council-btn--ghost" data-action="dismiss" ${state.busy ? 'disabled' : ''}>Dismiss</button>`;
|
|
@@ -355,12 +368,18 @@ function roundsCrumbHtml() {
|
|
|
355
368
|
/** The header ASK row — re-prompt the seated sitting; compact input + button. */
|
|
356
369
|
function askHtml() {
|
|
357
370
|
if (!state.seated || !state.sitting) return '';
|
|
371
|
+
const placeholder = state.archived
|
|
372
|
+
? 'Re-ask this thread — re-seats the same lenses…'
|
|
373
|
+
: 'Ask the council, or add context…';
|
|
374
|
+
const label = state.busy
|
|
375
|
+
? (state.archived ? 'Re-seating…' : 'Asking…')
|
|
376
|
+
: (state.archived ? 'Re-seat & ask →' : 'Ask the council →');
|
|
358
377
|
return `
|
|
359
378
|
<div class="council-ask">
|
|
360
379
|
<div class="council-ask-row">
|
|
361
|
-
<textarea class="council-ask-input" rows="1" placeholder="
|
|
380
|
+
<textarea class="council-ask-input" rows="1" placeholder="${esc(placeholder)}" ${state.busy ? 'disabled' : ''}></textarea>
|
|
362
381
|
<button class="council-btn council-btn--primary council-btn--compact" data-action="ask" ${state.busy ? 'disabled' : ''}>
|
|
363
|
-
${
|
|
382
|
+
${label}
|
|
364
383
|
</button>
|
|
365
384
|
</div>
|
|
366
385
|
<div class="council-ask-err" data-slot="ask-err"></div>
|
|
@@ -651,10 +670,33 @@ async function askCouncil(input) {
|
|
|
651
670
|
if (!prompt) { input.focus(); return; }
|
|
652
671
|
state.busy = true;
|
|
653
672
|
const btn = container?.querySelector('[data-action="ask"]');
|
|
654
|
-
|
|
673
|
+
const reseating = state.archived || !state.running;
|
|
674
|
+
if (btn) { btn.disabled = true; btn.textContent = reseating ? 'Re-seating…' : 'Asking…'; }
|
|
655
675
|
input.disabled = true;
|
|
656
676
|
setAskError('');
|
|
657
677
|
try {
|
|
678
|
+
// Archived thread → re-seat the same roster under the same name first,
|
|
679
|
+
// so the fan-out has live lens sessions to land in.
|
|
680
|
+
if (reseating) {
|
|
681
|
+
const startBody = { sitting: state.sitting };
|
|
682
|
+
if (state.roster.length) startBody.roster = state.roster.join(',');
|
|
683
|
+
const sres = await apiFetch('/api/council/start', {
|
|
684
|
+
method: 'POST',
|
|
685
|
+
headers: { 'Content-Type': 'application/json' },
|
|
686
|
+
body: JSON.stringify(startBody),
|
|
687
|
+
});
|
|
688
|
+
const sdata = await sres.json().catch(() => ({}));
|
|
689
|
+
if (!sres.ok) {
|
|
690
|
+
state.busy = false;
|
|
691
|
+
if (btn) { btn.disabled = false; }
|
|
692
|
+
input.disabled = false;
|
|
693
|
+
setAskError(sdata.error || 'Could not re-seat the council.');
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
state.archived = false;
|
|
697
|
+
state.running = true;
|
|
698
|
+
if (btn) btn.textContent = 'Asking…';
|
|
699
|
+
}
|
|
658
700
|
const res = await apiFetch('/api/council/ask', {
|
|
659
701
|
method: 'POST',
|
|
660
702
|
headers: { 'Content-Type': 'application/json' },
|