taskuary 0.3.2.6__tar.gz → 0.3.2.7__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.
- {taskuary-0.3.2.6/taskuary.egg-info → taskuary-0.3.2.7}/PKG-INFO +2 -2
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/README.md +1 -1
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/pyproject.toml +1 -1
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/guard.py +1 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/server.py +17 -0
- taskuary-0.3.2.7/taskuary/update.py +179 -0
- taskuary-0.3.2.6/taskuary/web/assets/GeneralWorkspace-D46ydeAJ.css → taskuary-0.3.2.7/taskuary/web/assets/GeneralWorkspace-BpkuvgFU.css +1 -1
- taskuary-0.3.2.6/taskuary/web/assets/GeneralWorkspace-CCZEIxwO.js → taskuary-0.3.2.7/taskuary/web/assets/GeneralWorkspace-Cmu6KGGe.js +2 -2
- taskuary-0.3.2.7/taskuary/web/assets/SocialView-kma4W7JV.js +1 -0
- taskuary-0.3.2.6/taskuary/web/assets/index-gbbR3m6-.js → taskuary-0.3.2.7/taskuary/web/assets/index-rF2UKXaH.js +110 -110
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/web/index.html +1 -1
- {taskuary-0.3.2.6 → taskuary-0.3.2.7/taskuary.egg-info}/PKG-INFO +2 -2
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary.egg-info/SOURCES.txt +6 -4
- taskuary-0.3.2.7/tests/test_update.py +185 -0
- taskuary-0.3.2.6/taskuary/web/assets/SocialView-8UXis6mV.js +0 -1
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/LICENSE +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/setup.cfg +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/__init__.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/agents.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/aisetup.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/artifacts.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/assistant.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/aws.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/azure.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/blackboard.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/browserview.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/calendar.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/categories.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/channels.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/ci.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/cli.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/climodels.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/clis.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/coder.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/compose.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/config.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/context.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/counsel.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/db.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/demo.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/desktop.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/devtools.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/digest.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/docsync.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/evalset.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/general.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/github.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/handbook.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/handraise.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/histgen.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/hooks.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/imapmail.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/imessage.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/ingest.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/intacct.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/interview.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/knowledge.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/learn.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/learnedgraph.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/llm.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/logs.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/mcp.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/messengers.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/msauth.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/mssql.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/outbound.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/outbox.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/ownwork.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/phone.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/playbooks.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/pm.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/policy.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/problems.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/promptmap.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/proof.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/proposals.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/quickbooks.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/rank.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/reports.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/research.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/reshape.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/responder.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/routing.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/scopes.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/selfclose.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/semantic.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/senders.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/setup.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/sharepoint.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/sheets.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/spawn.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/store.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/teller.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/templates/coder.md +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/templates/counsel.md +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/templates/digest.md +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/templates/learned.md +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/templates/playbook.md +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/templates/soul.md +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/templates/style.md +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/templates/triage.md +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/terminal.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/testing.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/toil.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/triage.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/verdicts.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/voice.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/wabridge.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/waitroom.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/web/assets/index-6GBZ9nXN.css +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/web/favicon.ico +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/web/favicon.png +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/webguard.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/whatsapp/bridge.mjs +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/whatsapp/package.json +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/whoami.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary/witness.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary.egg-info/dependency_links.txt +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary.egg-info/entry_points.txt +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary.egg-info/requires.txt +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/taskuary.egg-info/top_level.txt +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_agent_environment.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_agent_source.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_agent_wall.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_aisetup.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_answered_yourself.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_answers.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_api.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_assistant.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_assistant_verdicts.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_async_triage.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_audit_chain.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_aws_region.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_blackboard.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_browser_session.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_browserview.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_calendar.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_calendar_today.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_categories.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_cc_triage.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_chat_doors.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_chat_queue.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_climodels.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_clis.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_cloud.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_cloud_sources.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_compose.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_compose_sources.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_config.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_context.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_core.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_counsel.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_cwlogs_paging.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_demo.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_desktop.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_devtools.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_diff_review.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_digest_brief.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_docs_and_llm.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_docs_flow.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_duplicate_connectors.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_factory.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_feed_working.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_finished_chat_stays_finished.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_general.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_github_auto.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_guard.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_handbook.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_handbook_topics.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_handoff_channels.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_handraise.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_harvest.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_histgen.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_home_is_never_yours.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_imap_history.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_imapmail.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_imessage.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_intacct.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_kind_dispatch.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_knowledge.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_learnedgraph.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_local_file.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_mail_folders.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_mark_read.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_mcp.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_meeting_prep.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_message_thread.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_messengers.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_msauth.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_mssql.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_noop_ending.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_not_coding.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_note_retrieval.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_outbound_reports.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_own_rows_no_reply.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_playbooks.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_pm.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_poll_overlap.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_poll_sources.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_pr_comments.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_problems.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_promptmap_and_catalog.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_proof_ci_proposals.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_pypi_downloads.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_quickbooks.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_rank.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_reply_channels.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_reply_voice.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_report_alerts.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_report_triage.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_research.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_reviews.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_scopes.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_seed_fits_a_tty.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_seeded_reports.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_semantic.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_send_targets.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_setup.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_sheets_sharepoint.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_someone_else_replied.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_soul_interview.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_stay_open.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_stay_open_doors.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_store_app_cli.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_store_hotpaths.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_sync_clock.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_task_identity.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_teller.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_terminal.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_toil.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_triage_dataset.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_urgent_and_handoff.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_verdict_paths.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_verdict_sticks.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_vision.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_voice.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_wabridge.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_waitroom.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_watermark.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_web_entrypoint.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_webguard.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_whatsapp_documents.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_whatsapp_images.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_whoami.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_withdrawn.py +0 -0
- {taskuary-0.3.2.6 → taskuary-0.3.2.7}/tests/test_witness.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: taskuary
|
|
3
|
-
Version: 0.3.2.
|
|
3
|
+
Version: 0.3.2.7
|
|
4
4
|
Summary: Automate your job - the local-first operating system for your work: AI triage in, coding agents out.
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: Homepage, https://github.com/ldbumble/taskuary
|
|
@@ -64,7 +64,7 @@ and replies wait for your approval. Nothing sends or ships without you.
|
|
|
64
64
|
|
|
65
65
|

|
|
66
66
|
|
|
67
|
-
Taskuary is early—currently **v0.3.2.
|
|
67
|
+
Taskuary is early—currently **v0.3.2.7**—and moving fast. The funnel, review queue,
|
|
68
68
|
agent sessions, and reports pipeline are in daily use; breaking changes are still possible
|
|
69
69
|
before 1.0.
|
|
70
70
|
|
|
@@ -13,7 +13,7 @@ and replies wait for your approval. Nothing sends or ships without you.
|
|
|
13
13
|
|
|
14
14
|

|
|
15
15
|
|
|
16
|
-
Taskuary is early—currently **v0.3.2.
|
|
16
|
+
Taskuary is early—currently **v0.3.2.7**—and moving fast. The funnel, review queue,
|
|
17
17
|
agent sessions, and reports pipeline are in daily use; breaking changes are still possible
|
|
18
18
|
before 1.0.
|
|
19
19
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "taskuary"
|
|
7
|
-
version = "0.3.2.
|
|
7
|
+
version = "0.3.2.7"
|
|
8
8
|
description = "Automate your job - the local-first operating system for your work: AI triage in, coding agents out."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -57,6 +57,7 @@ DENIED = (
|
|
|
57
57
|
(r'POST|PUT|PATCH', r'^/api/settings', 'the settings decide what agents may do'),
|
|
58
58
|
(r'POST|PUT|PATCH|DELETE', r'^/api/(policies|agents)', 'the rules and the agent profiles'),
|
|
59
59
|
(r'POST|PUT|PATCH|DELETE', r'^/api/(docs?|playbooks)(/|$)', 'SOUL.md, the playbooks and the rest are the owner\'s word, not an agent\'s - propose, do not write'),
|
|
60
|
+
(r'POST', r'^/api/update$', 'replacing the program is the owner\'s decision'),
|
|
60
61
|
)
|
|
61
62
|
_DENIED = tuple((re.compile(f'^({m})$', re.I), re.compile(p), why) for m, p, why in DENIED)
|
|
62
63
|
|
|
@@ -197,6 +197,23 @@ _started = datetime.now().isoformat(sep=' ', timespec='seconds')
|
|
|
197
197
|
@app.get('/api/version')
|
|
198
198
|
def version(): return {'version': _ver, 'started': _started}
|
|
199
199
|
|
|
200
|
+
# ── update in place (update.py): Settings → Updates ─────────────────────────────────────
|
|
201
|
+
@app.get('/api/update')
|
|
202
|
+
def update_check(force: int = 0):
|
|
203
|
+
from . import update
|
|
204
|
+
return update.check(force=bool(force))
|
|
205
|
+
|
|
206
|
+
@app.post('/api/update')
|
|
207
|
+
def update_apply():
|
|
208
|
+
"""Fetch the latest release and swap it in. The answer goes out first; the process ends a
|
|
209
|
+
moment later so the new build can start. Owner-only: guard.py refuses an agent token."""
|
|
210
|
+
from . import update
|
|
211
|
+
try: out = update.apply()
|
|
212
|
+
except Exception as e: raise HTTPException(422, str(e))
|
|
213
|
+
store.audit('app', 0, 'update', ACTOR, detail={k: v for k, v in out.items() if k != 'pip'})
|
|
214
|
+
if out.get('restarting'): update.exit_soon()
|
|
215
|
+
return out
|
|
216
|
+
|
|
200
217
|
def _can_send(channel, has_message=True, gh_ok=None) -> bool:
|
|
201
218
|
"""Can an approved reply actually LEAVE on this channel? One answer for the whole app -
|
|
202
219
|
outbound.can_reply - so the Approve button, triage and the coder wrap-up cannot
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"""Update in place, from Settings: check what the latest release is, fetch it, swap it in, come back.
|
|
2
|
+
|
|
3
|
+
Everything the owner has - connections, tokens, the database, the operator documents, the
|
|
4
|
+
playbooks - lives under ~/.taskuary (config.home()), never beside the program. So an update is
|
|
5
|
+
only ever a program swap: nothing in the data folder is touched, and the new build opens the same
|
|
6
|
+
database the old one closed. That is what makes "keep the connection and all the settings" free.
|
|
7
|
+
|
|
8
|
+
Three ways Taskuary can be installed, three roads:
|
|
9
|
+
exe Taskuary.exe (PyInstaller, taskuary.spec). A running exe cannot overwrite itself on
|
|
10
|
+
Windows, so the new one is downloaded beside it as Taskuary.new.exe and a tiny batch
|
|
11
|
+
script does the rest after we exit: wait for our PID to go, move the new file over
|
|
12
|
+
the old, start it with the same arguments, delete itself.
|
|
13
|
+
pip a wheel in a venv: `pip install -U taskuary`, then relaunch the same command line.
|
|
14
|
+
source a checkout (`pip install -e .`, the developer's machine): updating means `git pull`,
|
|
15
|
+
which is not ours to run in somebody's repository - say so instead.
|
|
16
|
+
|
|
17
|
+
The latest version is the GitHub release the publish workflow cuts on every tag, and the exe is
|
|
18
|
+
the asset it attaches at a fixed URL (releases/latest/download/Taskuary.exe). No token, no extra
|
|
19
|
+
service, and the same file a person would download by hand.
|
|
20
|
+
"""
|
|
21
|
+
import os, re, sys, threading, time
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
import requests
|
|
25
|
+
from loguru import logger
|
|
26
|
+
|
|
27
|
+
from . import __version__
|
|
28
|
+
|
|
29
|
+
REPO = 'ldbumble/taskuary'
|
|
30
|
+
LATEST_API = f'https://api.github.com/repos/{REPO}/releases/latest'
|
|
31
|
+
EXE_URL = f'https://github.com/{REPO}/releases/latest/download/Taskuary.exe'
|
|
32
|
+
TIMEOUT = 20
|
|
33
|
+
_cache = {'at': 0.0, 'result': None}
|
|
34
|
+
CACHE_S = 600 # GitHub allows 60 anonymous calls an hour; the header pill asks often
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def how() -> str:
|
|
38
|
+
"""'exe' | 'pip' | 'source' - which road an update takes on this install."""
|
|
39
|
+
if getattr(sys, 'frozen', False): return 'exe'
|
|
40
|
+
if (Path(__file__).parent.parent / 'pyproject.toml').is_file(): return 'source'
|
|
41
|
+
return 'pip'
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _parts(v: str) -> tuple:
|
|
45
|
+
return tuple(int(x) for x in re.findall(r'\d+', str(v or '')))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def newer(latest: str, current: str) -> bool:
|
|
49
|
+
"""Is `latest` a later release than `current`? Dotted integers, any depth; a bad string is
|
|
50
|
+
never newer - an update button must not fire on a parse error."""
|
|
51
|
+
a, b = _parts(latest), _parts(current)
|
|
52
|
+
if not a or not b: return False
|
|
53
|
+
n = max(len(a), len(b))
|
|
54
|
+
return a + (0,) * (n - len(a)) > b + (0,) * (n - len(b))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def check(force: bool = False) -> dict:
|
|
58
|
+
"""What is out there vs what is running. Cached ten minutes; a failure to reach GitHub is a
|
|
59
|
+
fact in the answer, not an exception - the card says 'could not check' and stays useful."""
|
|
60
|
+
if not force and _cache['result'] and time.time() - _cache['at'] < CACHE_S: return _cache['result']
|
|
61
|
+
out = {'current': __version__, 'how': how(), 'latest': None, 'newer': False, 'url': None, 'notes': None, 'error': None}
|
|
62
|
+
try:
|
|
63
|
+
r = requests.get(LATEST_API, timeout=TIMEOUT, headers={'Accept': 'application/vnd.github+json'})
|
|
64
|
+
r.raise_for_status()
|
|
65
|
+
j = r.json()
|
|
66
|
+
tag = str(j.get('tag_name') or '').lstrip('v')
|
|
67
|
+
out.update({'latest': tag or None, 'newer': newer(tag, __version__), 'notes': j.get('html_url'),
|
|
68
|
+
'url': next((a.get('browser_download_url') for a in j.get('assets') or []
|
|
69
|
+
if str(a.get('name') or '').lower() == 'taskuary.exe'), EXE_URL)})
|
|
70
|
+
except Exception as e:
|
|
71
|
+
out['error'] = f'could not reach GitHub to check: {str(e)[:160]}'
|
|
72
|
+
_cache.update({'at': time.time(), 'result': out})
|
|
73
|
+
return out
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# ── the exe road ────────────────────────────────────────────────────────────────────────
|
|
77
|
+
def _download(url: str, dest: Path, progress=None) -> int:
|
|
78
|
+
"""Stream the new exe beside the old one. Size-checked against Content-Length and sniffed
|
|
79
|
+
for the PE header: a half-downloaded or HTML-error-page 'exe' must never be swapped in."""
|
|
80
|
+
with requests.get(url, stream=True, timeout=TIMEOUT, allow_redirects=True) as r:
|
|
81
|
+
r.raise_for_status()
|
|
82
|
+
total = int(r.headers.get('Content-Length') or 0)
|
|
83
|
+
got = 0
|
|
84
|
+
with open(dest, 'wb') as f:
|
|
85
|
+
for chunk in r.iter_content(1 << 20):
|
|
86
|
+
if not chunk: continue
|
|
87
|
+
f.write(chunk); got += len(chunk)
|
|
88
|
+
if progress: progress(got, total)
|
|
89
|
+
if total and got != total:
|
|
90
|
+
dest.unlink(missing_ok=True)
|
|
91
|
+
raise RuntimeError(f'download stopped short: {got:,} of {total:,} bytes')
|
|
92
|
+
with open(dest, 'rb') as f: head = f.read(2)
|
|
93
|
+
if head != b'MZ':
|
|
94
|
+
dest.unlink(missing_ok=True)
|
|
95
|
+
raise RuntimeError('what came down is not a Windows program - the release asset may be missing')
|
|
96
|
+
return got
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def swap_script(exe: Path, new: Path, pid: int, args: list) -> str:
|
|
100
|
+
"""The batch that finishes the job after this process has gone. Waits for the PID (the exe
|
|
101
|
+
is locked while it runs), moves the new file over the old (retrying - antivirus likes to hold
|
|
102
|
+
a fresh download for a second), starts the new build with the SAME arguments, removes itself."""
|
|
103
|
+
q = lambda s: '"' + str(s).replace('"', '""') + '"'
|
|
104
|
+
argstr = ' '.join(q(a) for a in args)
|
|
105
|
+
return '\r\n'.join([
|
|
106
|
+
'@echo off',
|
|
107
|
+
'setlocal',
|
|
108
|
+
':wait',
|
|
109
|
+
f'tasklist /FI "PID eq {pid}" 2>nul | find "{pid}" >nul',
|
|
110
|
+
'if not errorlevel 1 (timeout /t 1 /nobreak >nul & goto wait)',
|
|
111
|
+
'set /a tries=0',
|
|
112
|
+
':swap',
|
|
113
|
+
f'move /Y {q(new)} {q(exe)} >nul 2>&1',
|
|
114
|
+
'if errorlevel 1 (',
|
|
115
|
+
' set /a tries+=1',
|
|
116
|
+
' if %tries% geq 30 goto giveup',
|
|
117
|
+
' timeout /t 1 /nobreak >nul',
|
|
118
|
+
' goto swap',
|
|
119
|
+
')',
|
|
120
|
+
f'start "" {q(exe)} {argstr}'.rstrip(),
|
|
121
|
+
'del "%~f0"',
|
|
122
|
+
'exit /b 0',
|
|
123
|
+
':giveup',
|
|
124
|
+
f'start "" {q(exe)} {argstr}'.rstrip(),
|
|
125
|
+
'del "%~f0"',
|
|
126
|
+
'exit /b 1',
|
|
127
|
+
]) + '\r\n'
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _apply_exe(url: str, progress=None) -> dict:
|
|
131
|
+
exe = Path(sys.executable).resolve()
|
|
132
|
+
new = exe.with_name('Taskuary.new.exe')
|
|
133
|
+
size = _download(url, new, progress)
|
|
134
|
+
script = exe.with_name('taskuary-update.cmd')
|
|
135
|
+
script.write_text(swap_script(exe, new, os.getpid(), sys.argv[1:]), encoding='utf-8')
|
|
136
|
+
from . import spawn
|
|
137
|
+
import subprocess
|
|
138
|
+
# detached: it must outlive us, and it must not die when our (nonexistent) console does
|
|
139
|
+
spawn.popen(['cmd', '/c', str(script)], cwd=str(exe.parent), close_fds=True,
|
|
140
|
+
creationflags=getattr(subprocess, 'DETACHED_PROCESS', 0) | getattr(subprocess, 'CREATE_NEW_PROCESS_GROUP', 0))
|
|
141
|
+
logger.info(f'update: {size:,} bytes downloaded to {new.name}; {script.name} takes over when this process exits')
|
|
142
|
+
return {'how': 'exe', 'downloaded': size, 'restarting': True}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# ── the pip road ────────────────────────────────────────────────────────────────────────
|
|
146
|
+
def _apply_pip(progress=None) -> dict:
|
|
147
|
+
from . import spawn
|
|
148
|
+
if progress: progress(0, 0)
|
|
149
|
+
r = spawn.run([sys.executable, '-m', 'pip', 'install', '-U', '--no-input', 'taskuary'],
|
|
150
|
+
capture_output=True, text=True, timeout=600)
|
|
151
|
+
if r.returncode != 0:
|
|
152
|
+
raise RuntimeError('pip could not update: ' + (r.stderr or r.stdout or '').strip()[-400:])
|
|
153
|
+
# relaunch the same command line, detached, once we are gone
|
|
154
|
+
import subprocess
|
|
155
|
+
kw = ({'creationflags': getattr(subprocess, 'DETACHED_PROCESS', 0) | getattr(subprocess, 'CREATE_NEW_PROCESS_GROUP', 0)}
|
|
156
|
+
if os.name == 'nt' else {'start_new_session': True})
|
|
157
|
+
spawn.popen([sys.executable, *sys.argv], close_fds=True, **kw)
|
|
158
|
+
return {'how': 'pip', 'restarting': True, 'pip': (r.stdout or '').strip()[-300:]}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def apply(progress=None) -> dict:
|
|
162
|
+
"""Do it. Returns what happened; the caller ends the process (exit_soon) when 'restarting'."""
|
|
163
|
+
road = how()
|
|
164
|
+
if road == 'source':
|
|
165
|
+
raise RuntimeError('this is a source checkout - update it with `git pull` in the repository, then restart')
|
|
166
|
+
info = check(force=True)
|
|
167
|
+
if info.get('error'): raise RuntimeError(info['error'])
|
|
168
|
+
if not info.get('newer'): raise RuntimeError(f'already on the latest release ({__version__})')
|
|
169
|
+
return _apply_exe(info.get('url') or EXE_URL, progress) if road == 'exe' else _apply_pip(progress)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def exit_soon(delay: float = 1.5):
|
|
173
|
+
"""Leave AFTER the HTTP answer has gone out. os._exit, not sys.exit: uvicorn runs in a
|
|
174
|
+
thread and pywebview owns the main one; a polite exit from a request handler goes nowhere."""
|
|
175
|
+
def _go():
|
|
176
|
+
time.sleep(delay)
|
|
177
|
+
logger.info('update: exiting so the new build can start')
|
|
178
|
+
os._exit(0)
|
|
179
|
+
threading.Thread(target=_go, daemon=True).start()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.tq-aui-thread{height:100%;min-height:0;overflow:hidden;display:flex;flex-direction:column;background:#fbfaf7;color:#292824}.tq-aui-viewport{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;flex-direction:column;padding:18px;box-sizing:border-box;scrollbar-width:thin}.tq-aui-welcome{margin:auto auto 18px;max-width:560px;display:flex;align-items:flex-start;gap:10px;color:#667164}.tq-aui-welcome-title{color:#343832;font-weight:700;font-size:15px}.tq-aui-welcome-copy{color:#77766f;font-size:12.5px;margin-top:3px;line-height:1.45}.tq-aui-message{width:min(760px,92%);margin:0 auto 18px;display:grid;grid-template-columns:66px minmax(0,1fr);gap:10px;align-items:start}.tq-aui-role{padding-top:8px;color:#8b877e;font:600 9px/1.2 Cascadia Mono,Consolas,monospace;letter-spacing:.14em;text-transform:uppercase}.tq-aui-user-bubble{justify-self:start;max-width:88%;border:1px solid #dfdbd3;background:#f1eee8;border-radius:13px;padding:9px 13px;font-size:13px;line-height:1.48}.tq-aui-user-bubble p{margin:0;white-space:pre-wrap!important}.tq-aui-agent-body{min-width:0;padding:5px 3px}.tq-aui-report-action{width:min(760px,92%);margin:2px auto 14px;padding:10px 12px;border:1px dashed #d8d1c5;border-radius:11px;background:#f8f5ee;display:flex;align-items:center;gap:12px}.tq-aui-report-action>div{flex:1;min-width:0;display:flex;flex-direction:column}.tq-aui-report-action b{color:#4d514b;font-size:12px}.tq-aui-report-action span{color:#858078;font-size:10.5px}.tq-aui-progress{margin:0 0 8px;border:1px dashed #ddd7cd;border-radius:9px;color:#77766f;font-size:11.5px}.tq-aui-progress summary{cursor:pointer;padding:6px 9px;font-weight:650;color:#676b64}.tq-aui-progress>div{padding:0 9px 8px;white-space:pre-wrap;line-height:1.45}.tq-aui-tool{margin:0 0 7px;border:1px solid #ddd8cf;border-radius:9px;background:#faf8f4;overflow:hidden}.tq-aui-tool summary{min-height:31px;padding:5px 9px;display:flex;align-items:center;gap:7px;cursor:pointer;list-style:none;font-size:11.5px}.tq-aui-tool summary::-webkit-details-marker{display:none}.tq-aui-tool summary b{color:#4d514b}.tq-aui-tool summary span:not(.tq-aui-tool-dot){color:#858078;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tq-aui-tool summary em{margin-left:auto;color:#8d897f;font:9px/1.2 Cascadia Mono,Consolas,monospace;font-style:normal;text-transform:uppercase}.tq-aui-tool-dot{width:7px;height:7px;flex:0 0 7px;border-radius:50%;background:#78917a}.tq-aui-tool-running .tq-aui-tool-dot{background:#c99b42;animation:tqAuiPulse 1.2s ease-in-out infinite}.tq-aui-tool-error .tq-aui-tool-dot{background:#9a4e53}.tq-aui-tool pre{margin:0;padding:8px 10px;max-height:220px;overflow:auto;border-top:1px solid #e5e0d8;background:#22231f;color:#e8e4dc;font:10.5px/1.45 Cascadia Mono,Consolas,monospace;white-space:pre-wrap}@keyframes tqAuiPulse{50%{opacity:.3}}.tq-aui-footer{flex:0 0 auto;padding:10px 18px 8px;background:#fbfaf7;border-top:1px solid #e4e0d9}.tq-aui-composer{width:min(820px,100%);margin:0 auto;min-height:48px;display:flex;align-items:flex-end;gap:5px;padding:6px 7px;border:1px solid #d5d0c7;background:#fff;border-radius:13px;box-shadow:0 2px 8px #39352d0b}.tq-aui-input{flex:1;resize:none;border:0;outline:0;background:transparent;color:#292824;font:inherit;font-size:13px;line-height:1.45;padding:7px 5px;max-height:150px}.tq-aui-input::placeholder{color:#8f8b84}.tq-aui-send,.tq-aui-cancel{width:34px;height:34px;flex:0 0 34px;border:0;border-radius:9px;display:grid;place-items:center;cursor:pointer;color:#fff;background:#738275}.tq-aui-send:disabled{cursor:default;opacity:.4}.tq-aui-cancel{background:#9a6d65}.tq-aui-cancel:disabled{display:none}.tq-aui-hint{margin:5px auto 0;text-align:center;color:#a09b92;font:9px/1.2 Cascadia Mono,Consolas,monospace}.tq-aui-attachments{width:min(820px,100%);margin:0 auto 6px;display:flex;flex-wrap:wrap;gap:5px}@media (max-width: 700px){.tq-aui-viewport{padding-left:10px;padding-right:10px}.tq-aui-message{width:100%;grid-template-columns:1fr;gap:3px}.tq-aui-role{padding-top:0}.tq-aui-footer{padding-left:10px;padding-right:10px}}
|
|
1
|
+
.tq-aui-thread{height:100%;min-height:0;overflow:hidden;display:flex;flex-direction:column;background:#fbfaf7;color:#292824}.tq-aui-viewport{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;flex-direction:column;padding:18px;box-sizing:border-box;scrollbar-width:thin}.tq-aui-welcome{margin:auto auto 18px;max-width:560px;display:flex;align-items:flex-start;gap:10px;color:#667164}.tq-aui-welcome-title{color:#343832;font-weight:700;font-size:15px}.tq-aui-welcome-copy{color:#77766f;font-size:12.5px;margin-top:3px;line-height:1.45}.tq-aui-message{width:min(760px,92%);margin:0 auto 18px;display:grid;grid-template-columns:66px minmax(0,1fr);gap:10px;align-items:start}.tq-aui-role{padding-top:8px;color:#8b877e;font:600 9px/1.2 Cascadia Mono,Consolas,monospace;letter-spacing:.14em;text-transform:uppercase}.tq-aui-user-bubble{justify-self:start;max-width:88%;border:1px solid #dfdbd3;background:#f1eee8;border-radius:13px;padding:9px 13px;font-size:13px;line-height:1.48}.tq-aui-user-bubble p{margin:0;white-space:pre-wrap!important}.tq-aui-agent-body{min-width:0;padding:5px 3px}.tq-aui-report-action{width:min(760px,92%);margin:2px auto 14px;padding:10px 12px;border:1px dashed #d8d1c5;border-radius:11px;background:#f8f5ee;display:flex;align-items:center;gap:12px}.tq-aui-report-action>div{flex:1;min-width:0;display:flex;flex-direction:column}.tq-aui-report-action b{color:#4d514b;font-size:12px}.tq-aui-report-action span{color:#858078;font-size:10.5px}.tq-aui-progress{margin:0 0 8px;border:1px dashed #ddd7cd;border-radius:9px;color:#77766f;font-size:11.5px}.tq-aui-progress summary{cursor:pointer;padding:6px 9px;font-weight:650;color:#676b64}.tq-aui-progress>div{padding:0 9px 8px;white-space:pre-wrap;line-height:1.45}.tq-aui-tool{margin:0 0 7px;border:1px solid #ddd8cf;border-radius:9px;background:#faf8f4;overflow:hidden}.tq-aui-tool summary{min-height:31px;padding:5px 9px;display:flex;align-items:center;gap:7px;cursor:pointer;list-style:none;font-size:11.5px}.tq-aui-tool summary::-webkit-details-marker{display:none}.tq-aui-tool summary b{color:#4d514b}.tq-aui-tool summary span:not(.tq-aui-tool-dot){color:#858078;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tq-aui-tool summary em{margin-left:auto;color:#8d897f;font:9px/1.2 Cascadia Mono,Consolas,monospace;font-style:normal;text-transform:uppercase}.tq-aui-tool-dot{width:7px;height:7px;flex:0 0 7px;border-radius:50%;background:#78917a}.tq-aui-tool-running .tq-aui-tool-dot{background:#c99b42;animation:tqAuiPulse 1.2s ease-in-out infinite}.tq-aui-tool-error .tq-aui-tool-dot{background:#9a4e53}.tq-aui-tool pre{margin:0;padding:8px 10px;max-height:220px;overflow:auto;border-top:1px solid #e5e0d8;background:#22231f;color:#e8e4dc;font:10.5px/1.45 Cascadia Mono,Consolas,monospace;white-space:pre-wrap}@keyframes tqAuiPulse{50%{opacity:.3}}.tq-aui-footer{flex:0 0 auto;padding:10px 18px 8px;background:#fbfaf7;border-top:1px solid #e4e0d9}.tq-aui-composer{width:min(820px,100%);margin:0 auto;min-height:48px;display:flex;align-items:flex-end;gap:5px;padding:6px 7px;border:1px solid #d5d0c7;background:#fff;border-radius:13px;box-shadow:0 2px 8px #39352d0b}.tq-aui-input{flex:1;resize:none;border:0;outline:0;background:transparent;color:#292824;font:inherit;font-size:13px;line-height:1.45;padding:7px 5px;max-height:150px}.tq-aui-input::placeholder{color:#8f8b84}.tq-aui-send,.tq-aui-cancel{width:34px;height:34px;flex:0 0 34px;border:0;border-radius:9px;display:grid;place-items:center;cursor:pointer;color:#fff;background:#738275}.tq-aui-send:disabled{cursor:default;opacity:.4}.tq-aui-cancel{background:#9a6d65}.tq-aui-cancel:disabled{display:none}.tq-aui-hint{margin:5px auto 0;text-align:center;color:#a09b92;font:9px/1.2 Cascadia Mono,Consolas,monospace}.tq-aui-attachments{width:min(820px,100%);margin:0 auto 6px;display:flex;flex-wrap:wrap;gap:5px}@media (max-width: 700px){.tq-aui-viewport{padding-left:10px;padding-right:10px}.tq-aui-message{width:100%;grid-template-columns:1fr;gap:3px}.tq-aui-role{padding-top:0}.tq-aui-footer{padding-left:10px;padding-right:10px}}@media (max-width: 600px){.tq-aui-report-action{flex-direction:column;align-items:stretch;gap:10px}}
|