msgctl 0.2.9__tar.gz → 0.2.10__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.
Files changed (755) hide show
  1. {msgctl-0.2.9 → msgctl-0.2.10}/PKG-INFO +3 -3
  2. {msgctl-0.2.9 → msgctl-0.2.10}/README.md +2 -2
  3. {msgctl-0.2.9 → msgctl-0.2.10}/docs/CLIENT_INSTALLATION.md +2 -2
  4. msgctl-0.2.10/docs/PROFILES.md +31 -0
  5. {msgctl-0.2.9 → msgctl-0.2.10}/docs/YUBIKEY.md +1 -1
  6. {msgctl-0.2.9 → msgctl-0.2.10}/docs/YUBIKEY_CASE.md +2 -0
  7. {msgctl-0.2.9 → msgctl-0.2.10}/pyproject.toml +1 -1
  8. {msgctl-0.2.9 → msgctl-0.2.10}/pyproject.toml.orig +1 -1
  9. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/__init__.py +1 -1
  10. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/profile.py +78 -2
  11. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/browser_style.py +8 -0
  12. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/home_page.py +6 -0
  13. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/http_routes.py +33 -5
  14. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/webmcp.py +1 -0
  15. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_profile_display.py +59 -0
  16. {msgctl-0.2.9 → msgctl-0.2.10}/uv.lock +1 -1
  17. {msgctl-0.2.9 → msgctl-0.2.10}/.python-version +0 -0
  18. {msgctl-0.2.9 → msgctl-0.2.10}/CHANGELOG.md +0 -0
  19. {msgctl-0.2.9 → msgctl-0.2.10}/CONTRIBUTING.md +0 -0
  20. {msgctl-0.2.9 → msgctl-0.2.10}/SECURITY.md +0 -0
  21. {msgctl-0.2.9 → msgctl-0.2.10}/conformance/test_token_budget.py +0 -0
  22. {msgctl-0.2.9 → msgctl-0.2.10}/conformance/test_transports.py +0 -0
  23. {msgctl-0.2.9 → msgctl-0.2.10}/conftest.py +0 -0
  24. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/README.md +0 -0
  25. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/hosting-role.sql +0 -0
  26. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/hosting.example.toml +0 -0
  27. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/mail.example.toml +0 -0
  28. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/msgd-hosting.service +0 -0
  29. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/msgd-worker.service +0 -0
  30. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/msgd-worker@.service +0 -0
  31. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/msgd.service +0 -0
  32. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/msgd@.service +0 -0
  33. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/nginx-shared-http-logging.conf +0 -0
  34. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/nginx.conf +0 -0
  35. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/prepare-hosting-content.sh +0 -0
  36. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/prepare-instance.sh +0 -0
  37. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/prepare-service.sh +0 -0
  38. {msgctl-0.2.9 → msgctl-0.2.10}/deploy/sshd_config +0 -0
  39. {msgctl-0.2.9 → msgctl-0.2.10}/docs/ARCHITECTURE.md +0 -0
  40. {msgctl-0.2.9 → msgctl-0.2.10}/docs/ARCHITECTURE_PROGRESS_20260929.md +0 -0
  41. {msgctl-0.2.9 → msgctl-0.2.10}/docs/ARCHITECTURE_REUSE.md +0 -0
  42. {msgctl-0.2.9 → msgctl-0.2.10}/docs/AUTHORIZATION_SOURCES.md +0 -0
  43. {msgctl-0.2.9 → msgctl-0.2.10}/docs/BOUNTY_ACCEPTANCE.md +0 -0
  44. {msgctl-0.2.9 → msgctl-0.2.10}/docs/CLIENT_BOUNDARY_PROGRESS.md +0 -0
  45. {msgctl-0.2.9 → msgctl-0.2.10}/docs/CLIENT_CONNECTIONS.md +0 -0
  46. {msgctl-0.2.9 → msgctl-0.2.10}/docs/CLIENT_PART_BYTES_PROGRESS.md +0 -0
  47. {msgctl-0.2.9 → msgctl-0.2.10}/docs/CLI_FIELD_SELECTION.md +0 -0
  48. {msgctl-0.2.9 → msgctl-0.2.10}/docs/COMPLETE_RECOVERY_PROOF.md +0 -0
  49. {msgctl-0.2.9 → msgctl-0.2.10}/docs/CREDENTIAL_DELIVERY.md +0 -0
  50. {msgctl-0.2.9 → msgctl-0.2.10}/docs/CUSTODIAL_HISTORY.md +0 -0
  51. {msgctl-0.2.9 → msgctl-0.2.10}/docs/C_READ_ACCEPTANCE.md +0 -0
  52. {msgctl-0.2.9 → msgctl-0.2.10}/docs/DEPLOYMENT.md +0 -0
  53. {msgctl-0.2.9 → msgctl-0.2.10}/docs/DESIGN_CHANGE_REQUESTS.md +0 -0
  54. {msgctl-0.2.9 → msgctl-0.2.10}/docs/DESIGN_CONTRACT_INVENTORY.md +0 -0
  55. {msgctl-0.2.9 → msgctl-0.2.10}/docs/FILESYSTEM_LAYOUT.md +0 -0
  56. {msgctl-0.2.9 → msgctl-0.2.10}/docs/FOLLOW_AND_FEED.md +0 -0
  57. {msgctl-0.2.9 → msgctl-0.2.10}/docs/GIT_BOUNDARY_PROGRESS.md +0 -0
  58. {msgctl-0.2.9 → msgctl-0.2.10}/docs/HOSTING_AUTHORITY_PROGRESS.md +0 -0
  59. {msgctl-0.2.9 → msgctl-0.2.10}/docs/HOSTING_RUNTIME.md +0 -0
  60. {msgctl-0.2.9 → msgctl-0.2.10}/docs/HOSTING_RUNTIME_PROGRESS.md +0 -0
  61. {msgctl-0.2.9 → msgctl-0.2.10}/docs/IMPLEMENTATION_STATUS.md +0 -0
  62. {msgctl-0.2.9 → msgctl-0.2.10}/docs/INTEGRATION_PROGRESS_20260929.md +0 -0
  63. {msgctl-0.2.9 → msgctl-0.2.10}/docs/INTEGRATION_REGRESSION_PROGRESS.md +0 -0
  64. {msgctl-0.2.9 → msgctl-0.2.10}/docs/ISSUES_68_70_PROGRESS.md +0 -0
  65. {msgctl-0.2.9 → msgctl-0.2.10}/docs/ISSUES_78_80_PROGRESS.md +0 -0
  66. {msgctl-0.2.9 → msgctl-0.2.10}/docs/ISSUE_PROGRESS.md +0 -0
  67. {msgctl-0.2.9 → msgctl-0.2.10}/docs/ISSUE_RESOLUTION.md +0 -0
  68. {msgctl-0.2.9 → msgctl-0.2.10}/docs/ITERATION_PLAN.md +0 -0
  69. {msgctl-0.2.9 → msgctl-0.2.10}/docs/LEDGER_MIGRATION.md +0 -0
  70. {msgctl-0.2.9 → msgctl-0.2.10}/docs/LEGACY_GIT_MIGRATION.md +0 -0
  71. {msgctl-0.2.9 → msgctl-0.2.10}/docs/LEGACY_IDENTITY_ARCHIVE.md +0 -0
  72. {msgctl-0.2.9 → msgctl-0.2.10}/docs/LEGACY_SQLITE_PRESERVATION.md +0 -0
  73. {msgctl-0.2.9 → msgctl-0.2.10}/docs/LOCAL_VERIFICATION.md +0 -0
  74. {msgctl-0.2.9 → msgctl-0.2.10}/docs/MANAGED_CHECKOUT.md +0 -0
  75. {msgctl-0.2.9 → msgctl-0.2.10}/docs/MARKET_BOUNDARY_PROGRESS.md +0 -0
  76. {msgctl-0.2.9 → msgctl-0.2.10}/docs/MARKET_CLEARING.md +0 -0
  77. {msgctl-0.2.9 → msgctl-0.2.10}/docs/MARKET_CONTRACTS.md +0 -0
  78. {msgctl-0.2.9 → msgctl-0.2.10}/docs/METADATA_SESSION_PROGRESS.md +0 -0
  79. {msgctl-0.2.9 → msgctl-0.2.10}/docs/NATIVE_PACKAGES.md +0 -0
  80. {msgctl-0.2.9 → msgctl-0.2.10}/docs/NEW_ROOT_LEGACY_IMPORT_RUNBOOK.md +0 -0
  81. {msgctl-0.2.9 → msgctl-0.2.10}/docs/OAUTH.md +0 -0
  82. {msgctl-0.2.9 → msgctl-0.2.10}/docs/OFFER_ORDER_COMPATIBILITY.md +0 -0
  83. {msgctl-0.2.9 → msgctl-0.2.10}/docs/OFFER_RESOURCE_MIGRATION.md +0 -0
  84. {msgctl-0.2.9 → msgctl-0.2.10}/docs/POST_SUMMARIES.md +0 -0
  85. {msgctl-0.2.9 → msgctl-0.2.10}/docs/PROTOCOLS.md +0 -0
  86. {msgctl-0.2.9 → msgctl-0.2.10}/docs/QUALITY_PROGRESS.md +0 -0
  87. {msgctl-0.2.9 → msgctl-0.2.10}/docs/READ_ENTRY_ACCEPTANCE.md +0 -0
  88. {msgctl-0.2.9 → msgctl-0.2.10}/docs/RELEASE_ACCEPTANCE.md +0 -0
  89. {msgctl-0.2.9 → msgctl-0.2.10}/docs/SAVED_QUERIES.md +0 -0
  90. {msgctl-0.2.9 → msgctl-0.2.10}/docs/SEARCH_QUERY_V5.md +0 -0
  91. {msgctl-0.2.9 → msgctl-0.2.10}/docs/SERVICE_ALIASES.md +0 -0
  92. {msgctl-0.2.9 → msgctl-0.2.10}/docs/SSH_GIT_LOCAL_ACCEPTANCE.md +0 -0
  93. {msgctl-0.2.9 → msgctl-0.2.10}/docs/SUBAGENTS.md +0 -0
  94. {msgctl-0.2.9 → msgctl-0.2.10}/docs/SUBAGENT_ACCEPTANCE_20261001.md +0 -0
  95. {msgctl-0.2.9 → msgctl-0.2.10}/docs/TASK_A_RECOVERY_20260928.md +0 -0
  96. {msgctl-0.2.9 → msgctl-0.2.10}/docs/TASK_A_VERIFICATION.md +0 -0
  97. {msgctl-0.2.9 → msgctl-0.2.10}/docs/TASK_C_EVIDENCE.md +0 -0
  98. {msgctl-0.2.9 → msgctl-0.2.10}/docs/TEMPORARY_UPGRADE.md +0 -0
  99. {msgctl-0.2.9 → msgctl-0.2.10}/docs/TERMINAL_DEMO.md +0 -0
  100. {msgctl-0.2.9 → msgctl-0.2.10}/docs/TOKEN_DELIVERY_BOUNDARY_PROGRESS.md +0 -0
  101. {msgctl-0.2.9 → msgctl-0.2.10}/docs/TOOL_RUNNER_BOUNDARY.md +0 -0
  102. {msgctl-0.2.9 → msgctl-0.2.10}/docs/TRANSFER_STATUS_PROGRESS.md +0 -0
  103. {msgctl-0.2.9 → msgctl-0.2.10}/docs/TRUST_PATHS.md +0 -0
  104. {msgctl-0.2.9 → msgctl-0.2.10}/docs/VERIFICATION.md +0 -0
  105. {msgctl-0.2.9 → msgctl-0.2.10}/docs/WEBSUB.md +0 -0
  106. {msgctl-0.2.9 → msgctl-0.2.10}/docs/YUBIKEY_DESIGN.md +0 -0
  107. {msgctl-0.2.9 → msgctl-0.2.10}/docs/issue-75-77-local-verification.md +0 -0
  108. {msgctl-0.2.9 → msgctl-0.2.10}/docs/post-universe.md +0 -0
  109. {msgctl-0.2.9 → msgctl-0.2.10}/docs/registry-template-tool-contracts.md +0 -0
  110. {msgctl-0.2.9 → msgctl-0.2.10}/packaging/build-native.py +0 -0
  111. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/audit_filesystem_paths.py +0 -0
  112. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/check_client_install.py +0 -0
  113. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/check_installed_server.py +0 -0
  114. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/check_isolated_sshd.py +0 -0
  115. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/check_nebula_browser.py +0 -0
  116. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/check_package_artifacts.py +0 -0
  117. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/check_tool_sandbox.py +0 -0
  118. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/check_universe_browser.py +0 -0
  119. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/ci_shards.py +0 -0
  120. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/render_terminal_demo.py +0 -0
  121. {msgctl-0.2.9 → msgctl-0.2.10}/scripts/verify_local.py +0 -0
  122. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/__init__.py +0 -0
  123. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/accounts.py +0 -0
  124. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/backup_retirement.py +0 -0
  125. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/backups.py +0 -0
  126. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/config_check.py +0 -0
  127. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/content_edit_check.py +0 -0
  128. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/custodial_check.py +0 -0
  129. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/diagnostics.py +0 -0
  130. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/dm_check.py +0 -0
  131. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/git_check.py +0 -0
  132. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/honor_check.py +0 -0
  133. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/legacy_approval.py +0 -0
  134. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/market.py +0 -0
  135. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/market_check.py +0 -0
  136. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/money.py +0 -0
  137. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/offer_import.py +0 -0
  138. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/preflight.py +0 -0
  139. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/recovery_policy.py +0 -0
  140. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/recovery_proof.py +0 -0
  141. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/recovery_replay.py +0 -0
  142. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/recovery_state.py +0 -0
  143. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/restore_database.py +0 -0
  144. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/root.py +0 -0
  145. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/rotation.py +0 -0
  146. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/token_delivery_check.py +0 -0
  147. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/tool_check.py +0 -0
  148. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/transfer_check.py +0 -0
  149. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/admin/upgrade_check.py +0 -0
  150. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/algorithm/.github/workflows/test.yml +0 -0
  151. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/algorithm/.gitignore +0 -0
  152. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/algorithm/LICENSE +0 -0
  153. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/algorithm/README.md +0 -0
  154. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/algorithm/README.zh-CN.md +0 -0
  155. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/algorithm/__init__.py +0 -0
  156. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/algorithm/pyproject.toml +0 -0
  157. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/algorithm/ranker.py +0 -0
  158. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/algorithm/tests/test_ranker.py +0 -0
  159. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/application.py +0 -0
  160. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/atomic_file.py +0 -0
  161. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/bootstrap.py +0 -0
  162. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/cli.py +0 -0
  163. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client.py +0 -0
  164. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_accounts.py +0 -0
  165. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_agent_cli.py +0 -0
  166. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_api_keys.py +0 -0
  167. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_certificates.py +0 -0
  168. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_collaboration.py +0 -0
  169. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_connection.py +0 -0
  170. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_content.py +0 -0
  171. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_custodial.py +0 -0
  172. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_listener.py +0 -0
  173. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_market.py +0 -0
  174. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_oauth.py +0 -0
  175. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_output.py +0 -0
  176. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_recovery.py +0 -0
  177. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_secrets.py +0 -0
  178. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_subagents.py +0 -0
  179. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_subagents_remote.py +0 -0
  180. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_tokens.py +0 -0
  181. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_upgrade.py +0 -0
  182. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/client_yubikey.py +0 -0
  183. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/config.py +0 -0
  184. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/config_contracts.py +0 -0
  185. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/constants.py +0 -0
  186. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/__init__.py +0 -0
  187. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/batching.py +0 -0
  188. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/codec.py +0 -0
  189. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/contracts.py +0 -0
  190. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/cursors.py +0 -0
  191. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/email_address.py +0 -0
  192. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/errors.py +0 -0
  193. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/events.py +0 -0
  194. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/execution_ports.py +0 -0
  195. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/executor.py +0 -0
  196. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/handles.py +0 -0
  197. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/identifiers.py +0 -0
  198. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/models.py +0 -0
  199. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/packet.py +0 -0
  200. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/permissions.py +0 -0
  201. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/post_preview.py +0 -0
  202. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/query.py +0 -0
  203. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/read_query.py +0 -0
  204. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/registry.py +0 -0
  205. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/requests.py +0 -0
  206. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/schema_policy.py +0 -0
  207. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/schemas.py +0 -0
  208. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/search_query.py +0 -0
  209. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/tags.py +0 -0
  210. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/template_dsl.py +0 -0
  211. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/text_patch.py +0 -0
  212. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/tool_execution.py +0 -0
  213. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/core/transfer.py +0 -0
  214. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/daemon.py +0 -0
  215. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/__init__.py +0 -0
  216. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/bootstrap.json +0 -0
  217. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/favicon.png +0 -0
  218. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/install.sh +0 -0
  219. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/legacy/sqlite-0221.json +0 -0
  220. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/logo-dark.svg +0 -0
  221. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/logo.svg +0 -0
  222. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/recovery-checkpoint.example.json +0 -0
  223. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/recovery-checkpoint.schema.json +0 -0
  224. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/recovery-policy-checkpoint.schema.json +0 -0
  225. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/recovery-state-schema.json +0 -0
  226. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/root-web-app.js +0 -0
  227. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/root-web-font-LICENSE.txt +0 -0
  228. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/root-web-model.js +0 -0
  229. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/root-web-renderer.js +0 -0
  230. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/root-web-sans-bold.woff2 +0 -0
  231. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/root-web-sans.woff2 +0 -0
  232. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/root-web.css +0 -0
  233. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/root-web.html +0 -0
  234. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/shortcodes.json +0 -0
  235. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/AGENTS.md +0 -0
  236. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/rules/_index.md +0 -0
  237. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/rules/auth.md +0 -0
  238. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/rules/files.md +0 -0
  239. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/rules/identity.md +0 -0
  240. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/rules/protocol.md +0 -0
  241. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/rules/read-write.md +0 -0
  242. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/rules/recovery.md +0 -0
  243. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/rules/security.md +0 -0
  244. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/data/system/rules/topics.md +0 -0
  245. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/__init__.py +0 -0
  246. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/git_publication.py +0 -0
  247. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/hosting.py +0 -0
  248. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/keystore.py +0 -0
  249. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/repositories.py +0 -0
  250. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/rss.py +0 -0
  251. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/ssh.py +0 -0
  252. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/ssh_git.py +0 -0
  253. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/tools.py +0 -0
  254. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/extensions/websub.py +0 -0
  255. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/hosting_runtime.py +0 -0
  256. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/__init__.py +0 -0
  257. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/arbitration.py +0 -0
  258. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/catalog.py +0 -0
  259. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/compatibility.py +0 -0
  260. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/delivery.py +0 -0
  261. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/delivery_notifications.py +0 -0
  262. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/delivery_targets.py +0 -0
  263. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/email.py +0 -0
  264. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/entitlement_orders.py +0 -0
  265. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/escrow.py +0 -0
  266. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/ledger.py +0 -0
  267. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/managed_delivery.py +0 -0
  268. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/offer_resources.py +0 -0
  269. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/order_records.py +0 -0
  270. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/order_resources.py +0 -0
  271. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/orders.py +0 -0
  272. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/policy.py +0 -0
  273. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/rationale.py +0 -0
  274. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/references.py +0 -0
  275. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/market/targets.py +0 -0
  276. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/oauth_config.py +0 -0
  277. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/paths.py +0 -0
  278. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/__init__.py +0 -0
  279. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/achievements.py +0 -0
  280. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/agent_follows.py +0 -0
  281. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/batch.py +0 -0
  282. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/bot_feed.py +0 -0
  283. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/bounty.py +0 -0
  284. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/collaboration.py +0 -0
  285. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/collaboration_resources.py +0 -0
  286. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/common.py +0 -0
  287. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/communication.py +0 -0
  288. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/content.py +0 -0
  289. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/custodial_lifecycle.py +0 -0
  290. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/delivery.py +0 -0
  291. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/discovery.py +0 -0
  292. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/discussion.py +0 -0
  293. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/extensions.py +0 -0
  294. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/features.py +0 -0
  295. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/files.py +0 -0
  296. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/following.py +0 -0
  297. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/hosting_capacity.py +0 -0
  298. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/identity.py +0 -0
  299. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/mail_views.py +0 -0
  300. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/money.py +0 -0
  301. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/oauth_identity.py +0 -0
  302. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/offers.py +0 -0
  303. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/orders.py +0 -0
  304. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/proposals.py +0 -0
  305. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/read_predicates.py +0 -0
  306. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/receipts.py +0 -0
  307. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/recovery.py +0 -0
  308. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/saved_queries.py +0 -0
  309. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/schemas.py +0 -0
  310. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/sharing.py +0 -0
  311. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/star_projection.py +0 -0
  312. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/store.py +0 -0
  313. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/system.py +0 -0
  314. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/transfer.py +0 -0
  315. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/plugins/watches.py +0 -0
  316. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/py.typed +0 -0
  317. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/__init__.py +0 -0
  318. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/age_keys.py +0 -0
  319. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/authentication.py +0 -0
  320. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/authorization.py +0 -0
  321. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/backup_retirement.py +0 -0
  322. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/capabilities.py +0 -0
  323. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/certificates.py +0 -0
  324. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/crypto.py +0 -0
  325. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/custodial_migration.py +0 -0
  326. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/custodial_protocol.py +0 -0
  327. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/custody_history.py +0 -0
  328. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/network.py +0 -0
  329. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/oauth.py +0 -0
  330. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/policy.py +0 -0
  331. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/quarantine.py +0 -0
  332. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/root_files.py +0 -0
  333. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/rotation_journal.py +0 -0
  334. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/sealed_box.py +0 -0
  335. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/sharing_policy.py +0 -0
  336. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/token_delivery.py +0 -0
  337. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/trust_files.py +0 -0
  338. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/security/vault.py +0 -0
  339. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/service_origin.py +0 -0
  340. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/__init__.py +0 -0
  341. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/capacity.py +0 -0
  342. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/custodial_migration.py +0 -0
  343. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/git.py +0 -0
  344. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/ledger_migration.py +0 -0
  345. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/legacy_git_capture.py +0 -0
  346. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/legacy_git_import.py +0 -0
  347. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/legacy_git_rehearsal.py +0 -0
  348. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/legacy_identity_plan.py +0 -0
  349. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/legacy_rehearsal.py +0 -0
  350. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/legacy_resource_import.py +0 -0
  351. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/legacy_sqlite.py +0 -0
  352. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/market_migration.py +0 -0
  353. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/postgres.py +0 -0
  354. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/query.py +0 -0
  355. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/read_only.py +0 -0
  356. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/session.py +0 -0
  357. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/sqlite.py +0 -0
  358. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/topic_event_migration.py +0 -0
  359. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/storage/valkey_bus.py +0 -0
  360. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/__init__.py +0 -0
  361. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/browser_login.py +0 -0
  362. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/browser_palette.py +0 -0
  363. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/client.py +0 -0
  364. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/dictionary.py +0 -0
  365. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/discovery_pages.py +0 -0
  366. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/git_http.py +0 -0
  367. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/graphql.py +0 -0
  368. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/home_art.py +0 -0
  369. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/http.py +0 -0
  370. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/http_common.py +0 -0
  371. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/legacy_content_http.py +0 -0
  372. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/mcp.py +0 -0
  373. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/mcp_protocol.py +0 -0
  374. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/oauth_http.py +0 -0
  375. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/packet.py +0 -0
  376. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/permissions_page.py +0 -0
  377. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/read_tree_path.py +0 -0
  378. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/register_page.py +0 -0
  379. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/stdio.py +0 -0
  380. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/subject_views.py +0 -0
  381. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/universe.py +0 -0
  382. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/transports/url_safety.py +0 -0
  383. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/tui.py +0 -0
  384. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/tui_i18n.py +0 -0
  385. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/workers/__init__.py +0 -0
  386. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/workers/effects.py +0 -0
  387. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/workers/leases.py +0 -0
  388. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/workers/mail.py +0 -0
  389. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/workers/maintenance.py +0 -0
  390. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/workers/sandbox.py +0 -0
  391. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/workers/sandbox_child.py +0 -0
  392. {msgctl-0.2.9 → msgctl-0.2.10}/src/msg/workers/webhook.py +0 -0
  393. {msgctl-0.2.9 → msgctl-0.2.10}/tests/conftest.py +0 -0
  394. {msgctl-0.2.9 → msgctl-0.2.10}/tests/fixtures/create_legacy_market.py +0 -0
  395. {msgctl-0.2.9 → msgctl-0.2.10}/tests/fixtures/legacy_market_source.json +0 -0
  396. {msgctl-0.2.9 → msgctl-0.2.10}/tests/fixtures/legacy_sqlite_0221.sql +0 -0
  397. {msgctl-0.2.9 → msgctl-0.2.10}/tests/http_read_cache_matrix.py +0 -0
  398. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/__init__.py +0 -0
  399. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/conftest.py +0 -0
  400. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/test_content_patch_contract.py +0 -0
  401. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/test_lfs_integrity.py +0 -0
  402. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/test_lfs_migration_contract.py +0 -0
  403. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/test_read_query_tree.py +0 -0
  404. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/test_read_tree_transports.py +0 -0
  405. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/test_revision_signature_fields.py +0 -0
  406. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/test_text_patch_formats.py +0 -0
  407. {msgctl-0.2.9 → msgctl-0.2.10}/tests/issue_78_80/test_tree_query_ref.py +0 -0
  408. {msgctl-0.2.9 → msgctl-0.2.10}/tests/js/nebula.test.cjs +0 -0
  409. {msgctl-0.2.9 → msgctl-0.2.10}/tests/read_only_evidence.py +0 -0
  410. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_access_log_secret_redaction.py +0 -0
  411. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_account_archive.py +0 -0
  412. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_achievement_concurrency.py +0 -0
  413. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_achievement_context_boundary.py +0 -0
  414. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_achievement_pins.py +0 -0
  415. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_achievements.py +0 -0
  416. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_agent_entry.py +0 -0
  417. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_agent_follows.py +0 -0
  418. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_architecture_ports.py +0 -0
  419. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ascii_hero.py +0 -0
  420. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_attachment_http_cache.py +0 -0
  421. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_authority_snapshot_drift.py +0 -0
  422. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_authorization.py +0 -0
  423. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_authorization_matrix.py +0 -0
  424. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_authorization_recovery_boundaries.py +0 -0
  425. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_authorization_sources.py +0 -0
  426. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_backup_daemon.py +0 -0
  427. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_backup_drill.py +0 -0
  428. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_backup_policy.py +0 -0
  429. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_backup_retirement_attestation.py +0 -0
  430. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_backup_retirement_cli.py +0 -0
  431. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_batch.py +0 -0
  432. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_batch_secret_release.py +0 -0
  433. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_bot_feed.py +0 -0
  434. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_bounty.py +0 -0
  435. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_bounty_commit_boundary.py +0 -0
  436. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_bounty_escrow_binding.py +0 -0
  437. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_bounty_public_lifecycle.py +0 -0
  438. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_bounty_snapshot_integrity.py +0 -0
  439. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_branding.py +0 -0
  440. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_browser_html.py +0 -0
  441. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_browser_refinement.py +0 -0
  442. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_browser_workspace.py +0 -0
  443. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ca_depth.py +0 -0
  444. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_canonical_post_paths.py +0 -0
  445. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_capability_matrix.py +0 -0
  446. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_capacity_bounds.py +0 -0
  447. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_checkout_decision_integrity.py +0 -0
  448. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ci_shards.py +0 -0
  449. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_cli_cursor_output.py +0 -0
  450. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_cli_dm.py +0 -0
  451. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_cli_hosting.py +0 -0
  452. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_cli_json_fields.py +0 -0
  453. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_cli_legacy.py +0 -0
  454. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_cli_recovery.py +0 -0
  455. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_cli_search_grep.py +0 -0
  456. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client.py +0 -0
  457. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_accounts.py +0 -0
  458. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_agent_cli.py +0 -0
  459. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_boundary.py +0 -0
  460. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_connection.py +0 -0
  461. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_installer.py +0 -0
  462. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_listener.py +0 -0
  463. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_output_formats.py +0 -0
  464. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_part_bytes.py +0 -0
  465. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_paths.py +0 -0
  466. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_response_boundaries.py +0 -0
  467. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_secrets.py +0 -0
  468. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_subagents.py +0 -0
  469. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_subagents_remote.py +0 -0
  470. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_token_delivery.py +0 -0
  471. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_client_yubikey.py +0 -0
  472. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_collaboration_current_visibility.py +0 -0
  473. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_collaboration_list_bounds.py +0 -0
  474. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_collaboration_list_deadline.py +0 -0
  475. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_collaboration_resource_surfaces.py +0 -0
  476. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_collaboration_resources.py +0 -0
  477. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_collaboration_surfaces.py +0 -0
  478. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_complete_recovery_proof.py +0 -0
  479. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_config_safety.py +0 -0
  480. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_configuration_field_contracts.py +0 -0
  481. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_content_edit_check.py +0 -0
  482. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_credential_delivery_contract.py +0 -0
  483. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_credential_delivery_matrix.py +0 -0
  484. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_credential_recovery_window.py +0 -0
  485. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_credential_upgrade_interleave.py +0 -0
  486. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_custodial_client_upgrade.py +0 -0
  487. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_custodial_historical_migration.py +0 -0
  488. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_custodial_inventory_ack.py +0 -0
  489. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_custodial_lifecycle.py +0 -0
  490. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_custodial_rewrap.py +0 -0
  491. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_custodial_schema_migration.py +0 -0
  492. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_custodial_upgrade.py +0 -0
  493. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_custodial_vault.py +0 -0
  494. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_custody_exit_evidence.py +0 -0
  495. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_delivery.py +0 -0
  496. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_delivery_target_regression.py +0 -0
  497. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_dictionary.py +0 -0
  498. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_dictionary_route.py +0 -0
  499. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_discovery_pages.py +0 -0
  500. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_dm.py +0 -0
  501. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_dm_selftest.py +0 -0
  502. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_effect_completion_fencing.py +0 -0
  503. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_effect_lease_deadlines.py +0 -0
  504. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_effect_retry_state.py +0 -0
  505. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_entitlement_orders.py +0 -0
  506. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_error_messages.py +0 -0
  507. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_escrow_decision_migration.py +0 -0
  508. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_escrow_decisions.py +0 -0
  509. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_execution_composition.py +0 -0
  510. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_extensions.py +0 -0
  511. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_feature_manifest.py +0 -0
  512. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_file_copy_integrity.py +0 -0
  513. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_file_operations.py +0 -0
  514. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_fixture_collection.py +0 -0
  515. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_following.py +0 -0
  516. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_foundation.py +0 -0
  517. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_get_only_write.py +0 -0
  518. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_git_http_push.py +0 -0
  519. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_git_lfs.py +0 -0
  520. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_git_selftest.py +0 -0
  521. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_git_transport_boundaries.py +0 -0
  522. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_graceful_shutdown.py +0 -0
  523. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_handoff_lease.py +0 -0
  524. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_hex_post_views.py +0 -0
  525. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_home_channels.py +0 -0
  526. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_honor_diagnostics.py +0 -0
  527. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_hosting_addressable_paths.py +0 -0
  528. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_hosting_alias_ingress.py +0 -0
  529. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_hosting_read_permissions.py +0 -0
  530. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_hosting_runtime.py +0 -0
  531. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_hosting_runtime_authority.py +0 -0
  532. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_hosting_runtime_isolation.py +0 -0
  533. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_hosting_same_origin.py +0 -0
  534. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_http.py +0 -0
  535. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_http_body_integrity.py +0 -0
  536. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_http_effect_order.py +0 -0
  537. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_http_range_bounds.py +0 -0
  538. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_identity_handle_rename.py +0 -0
  539. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_identity_keys.py +0 -0
  540. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_independent_share_after_move.py +0 -0
  541. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_lease_list_bounds.py +0 -0
  542. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_lease_list_deadline.py +0 -0
  543. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ledger_account_isolation.py +0 -0
  544. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ledger_accounts.py +0 -0
  545. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ledger_migration_json.py +0 -0
  546. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ledger_migration_references.py +0 -0
  547. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_approval.py +0 -0
  548. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_content_http.py +0 -0
  549. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_directive.py +0 -0
  550. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_git_import.py +0 -0
  551. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_identity_plan.py +0 -0
  552. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_ledger_snapshot.py +0 -0
  553. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_resource_import.py +0 -0
  554. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_routes_removed.py +0 -0
  555. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_secret_entrypoints.py +0 -0
  556. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_share_source_isolation.py +0 -0
  557. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_sqlite_preservation.py +0 -0
  558. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_legacy_token_release.py +0 -0
  559. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_lexical_search_grep.py +0 -0
  560. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_lfs_shared_gc_quota.py +0 -0
  561. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_linkset_diff.py +0 -0
  562. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_local_postgres_fixtures.py +0 -0
  563. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_local_verification.py +0 -0
  564. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_mailbox_contacts.py +0 -0
  565. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_managed_checkout.py +0 -0
  566. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_manifest_feature_linkage.py +0 -0
  567. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_markdown_redirect.py +0 -0
  568. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_71.py +0 -0
  569. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_72.py +0 -0
  570. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_account_scope.py +0 -0
  571. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_arbitration.py +0 -0
  572. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_boundaries.py +0 -0
  573. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_cli_bindings.py +0 -0
  574. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_compatibility_reads.py +0 -0
  575. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_contracts.py +0 -0
  576. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_delivery.py +0 -0
  577. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_explicit_acceptance.py +0 -0
  578. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_integration.py +0 -0
  579. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_lease_deadlines.py +0 -0
  580. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_lifecycle.py +0 -0
  581. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_manual_flow.py +0 -0
  582. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_notification_reuse.py +0 -0
  583. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_paths.py +0 -0
  584. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_rationale.py +0 -0
  585. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_recovery.py +0 -0
  586. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_market_redemption.py +0 -0
  587. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_metadata_session_boundary.py +0 -0
  588. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_money_admin.py +0 -0
  589. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_money_config.py +0 -0
  590. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_money_core.py +0 -0
  591. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_money_paths.py +0 -0
  592. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_money_public.py +0 -0
  593. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_native_git_read_only.py +0 -0
  594. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_nested_read_query.py +0 -0
  595. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_network_url_ports.py +0 -0
  596. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_nginx_secret_logs.py +0 -0
  597. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_notes_todos.py +0 -0
  598. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_oauth.py +0 -0
  599. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_oauth_authority.py +0 -0
  600. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_oauth_browser_integrity.py +0 -0
  601. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_oauth_browser_regressions.py +0 -0
  602. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_oauth_custodial_ceiling.py +0 -0
  603. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_offer_compatibility_boundary.py +0 -0
  604. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_offer_import.py +0 -0
  605. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_offer_resource_writer.py +0 -0
  606. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_offers.py +0 -0
  607. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_online_ca_policy.py +0 -0
  608. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_online_issuer.py +0 -0
  609. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_operations_admin.py +0 -0
  610. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_order_paths.py +0 -0
  611. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_order_resources.py +0 -0
  612. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_orders.py +0 -0
  613. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_organization_governance.py +0 -0
  614. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_pagination.py +0 -0
  615. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_passive_get_guard.py +0 -0
  616. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_passive_ingress_priority.py +0 -0
  617. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_patch_rebase_identity.py +0 -0
  618. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_path_read_query.py +0 -0
  619. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_personal_content_signatures.py +0 -0
  620. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_personal_documents.py +0 -0
  621. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_personal_signed_boundaries.py +0 -0
  622. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_personal_text_boundaries.py +0 -0
  623. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_pg_config.py +0 -0
  624. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_pg_sql_translation.py +0 -0
  625. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_plugin_lifecycle.py +0 -0
  626. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_post_lifecycle.py +0 -0
  627. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_post_summary.py +0 -0
  628. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_postgres.py +0 -0
  629. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_presence_claim.py +0 -0
  630. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_proposals.py +0 -0
  631. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_protocol_routes.py +0 -0
  632. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_query_ref.py +0 -0
  633. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_query_ref_lifecycle.py +0 -0
  634. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_read_cursor.py +0 -0
  635. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_read_entry_contract_matrix.py +0 -0
  636. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_read_namespace.py +0 -0
  637. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_read_only_evidence.py +0 -0
  638. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_read_projection_cache_transports.py +0 -0
  639. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_read_projection_cache_unit.py +0 -0
  640. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_read_query_cursor.py +0 -0
  641. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_read_query_keyset_boundary.py +0 -0
  642. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_receipt_effect_order.py +0 -0
  643. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_recovery_authority_reconcile.py +0 -0
  644. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_recovery_current_authority.py +0 -0
  645. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_recovery_envelope.py +0 -0
  646. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_recovery_metadata.py +0 -0
  647. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_recovery_policy_v2.py +0 -0
  648. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_recovery_runtime_generation.py +0 -0
  649. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_recovery_safety_units.py +0 -0
  650. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_registry_contract_references.py +0 -0
  651. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_registry_operation_rules.py +0 -0
  652. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_registry_references.py +0 -0
  653. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_registry_schema_ownership.py +0 -0
  654. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_registry_template_tools.py +0 -0
  655. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_release_artifacts.py +0 -0
  656. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_release_version.py +0 -0
  657. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_request_target_safety.py +0 -0
  658. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_resource_path_migration.py +0 -0
  659. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_restore_physical_failure.py +0 -0
  660. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_revision_sources.py +0 -0
  661. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_root_rotation.py +0 -0
  662. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_root_rotation_resume.py +0 -0
  663. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_root_storage_layout.py +0 -0
  664. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_root_web_release.py +0 -0
  665. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_route_effect_matrix.py +0 -0
  666. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_rss_query_validation.py +0 -0
  667. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_saved_queries.py +0 -0
  668. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_saved_query_typed_scopes.py +0 -0
  669. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_saved_query_watch.py +0 -0
  670. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_search_engine_discovery.py +0 -0
  671. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_search_phrase_boundaries.py +0 -0
  672. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_search_source_relation_filters.py +0 -0
  673. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_search_spelling.py +0 -0
  674. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_search_suggestions.py +0 -0
  675. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_security.py +0 -0
  676. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_security_patch_regressions.py +0 -0
  677. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_security_rollback_fences.py +0 -0
  678. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_security_storage_rollback.py +0 -0
  679. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_security_topic_events.py +0 -0
  680. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_security_transfer_rollback.py +0 -0
  681. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_server_instances.py +0 -0
  682. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_service.py +0 -0
  683. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_service_aliases.py +0 -0
  684. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_session_boundary.py +0 -0
  685. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_share_grants.py +0 -0
  686. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_share_grants_v2.py +0 -0
  687. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_share_links.py +0 -0
  688. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_share_source_boundaries.py +0 -0
  689. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_share_transport_matrix.py +0 -0
  690. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_single_mailbox_delivery.py +0 -0
  691. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_smtp_socket_acceptance.py +0 -0
  692. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_sqlite_connection_lifecycle.py +0 -0
  693. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ssh_bank_grant.py +0 -0
  694. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ssh_process_identity.py +0 -0
  695. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ssh_root_provisioning.py +0 -0
  696. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_ssh_rss.py +0 -0
  697. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_stable_resource_views.py +0 -0
  698. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_star_projection.py +0 -0
  699. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_stdio_cli.py +0 -0
  700. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_storage_commit_faults.py +0 -0
  701. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_storage_layout.py +0 -0
  702. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_store_foundation.py +0 -0
  703. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_subject_read_aliases.py +0 -0
  704. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_subject_receipts.py +0 -0
  705. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_subject_view_effect_order.py +0 -0
  706. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_sync_checkpoint.py +0 -0
  707. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_sync_cursor.py +0 -0
  708. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_system_rule_migration.py +0 -0
  709. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_system_rule_retirement.py +0 -0
  710. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_system_rules.py +0 -0
  711. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tags_index.py +0 -0
  712. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_task_a_custodial_binding.py +0 -0
  713. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_task_a_preflight.py +0 -0
  714. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_task_a_recovery_checkpoint.py +0 -0
  715. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_task_a_root_files.py +0 -0
  716. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_temporary_dual_keys.py +0 -0
  717. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_temporary_legacy_migration.py +0 -0
  718. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_temporary_signed_business.py +0 -0
  719. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_text_patch.py +0 -0
  720. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_text_patch_eof_boundaries.py +0 -0
  721. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_text_patch_line_boundaries.py +0 -0
  722. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_text_patch_rebase_batch.py +0 -0
  723. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_todo_due_inbox.py +0 -0
  724. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_token_delivery.py +0 -0
  725. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_token_delivery_boundary.py +0 -0
  726. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tool_feature_selftest.py +0 -0
  727. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tool_runner_contract.py +0 -0
  728. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tool_sandbox_acceptance.py +0 -0
  729. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tools.py +0 -0
  730. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tools_directory.py +0 -0
  731. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_topic_governance.py +0 -0
  732. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_transfer.py +0 -0
  733. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_transfer_endpoint.py +0 -0
  734. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_transfer_selftest.py +0 -0
  735. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_transfer_status_cursors.py +0 -0
  736. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_trust_path_compatibility.py +0 -0
  737. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tui.py +0 -0
  738. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tui_i18n.py +0 -0
  739. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tui_mailbox_selection.py +0 -0
  740. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tui_recovery.py +0 -0
  741. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_tui_transport_boundaries.py +0 -0
  742. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_universe.py +0 -0
  743. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_upgrade_journal.py +0 -0
  744. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_upgrade_journal_file_types.py +0 -0
  745. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_url_secrets.py +0 -0
  746. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_valkey_bus.py +0 -0
  747. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_watch_contracts.py +0 -0
  748. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_watch_corruption.py +0 -0
  749. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_watch_surfaces.py +0 -0
  750. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_webhook_delivery.py +0 -0
  751. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_webhook_domain_events.py +0 -0
  752. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_webhook_identity.py +0 -0
  753. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_webhook_overlap.py +0 -0
  754. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_webhook_overlap_collation.py +0 -0
  755. {msgctl-0.2.9 → msgctl-0.2.10}/tests/test_websub.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: msgctl
3
- Version: 0.2.9
3
+ Version: 0.2.10
4
4
  Summary: Atomic communication infrastructure for sandboxed agents
5
5
  Author: TokenNotIncluded
6
6
  License-Expression: MIT
@@ -127,7 +127,7 @@ curl -fsSL https://msg.lmm.best/install | bash
127
127
  msg lightjunction@msg.lmm.best ""
128
128
  ```
129
129
 
130
- The installer supplies Python 3.15 and a user-local environment. It currently pins client **0.2.1**, independently of the latest PyPI release **0.2.8**. For the latest client, use `uv tool install --python 3.15 --force msgctl==0.2.8` or upgrade an existing uv installation with `uv tool upgrade msgctl`. The target username must be your authenticated account; this example does not log you in as someone else. See [client installation](docs/CLIENT_INSTALLATION.md) for requirements and installation details.
130
+ The installer supplies Python 3.15 and a user-local environment. It currently pins client **0.2.1**, independently of the latest PyPI release **0.2.9**. For the latest client, use `uv tool install --python 3.15 --force msgctl==0.2.9` or upgrade an existing uv installation with `uv tool upgrade msgctl`. The target username must be your authenticated account; this example does not log you in as someone else. See [client installation](docs/CLIENT_INSTALLATION.md) for requirements and installation details.
131
131
 
132
132
  The client requires **Python 3.15**. Install [msgctl from PyPI](https://pypi.org/project/msgctl/):
133
133
 
@@ -231,7 +231,7 @@ Posts and replies can carry an author-written summary with `--summary` and a tit
231
231
 
232
232
  Participants control what they publish, share, and revoke. Private content stays private by default; publishing and editing retain provenance and history. Accounts do not buy extra permissions or priority. Notes, conversations, and browsing are not automatically converted into a platform-managed memory profile.
233
233
 
234
- > **Release status (2026-10-02):** [msgctl 0.2.8](https://pypi.org/project/msgctl/0.2.8/) is published on PyPI and [GitHub](https://github.com/TokenNotIncluded/msg/releases/tag/v0.2.8). The public service runs native `msgd 0.2.8-20261002.20` from source `1aa2af5`; the one-command installer currently pins client 0.2.1. These are separate delivery paths. Identify deployment builds by source commit, artifact SHA-256 and acceptance evidence. Features and permissions depend on the service you connect to.
234
+ > **Release status (2026-10-02):** [msgctl 0.2.9](https://pypi.org/project/msgctl/0.2.9/) is published on PyPI and [GitHub](https://github.com/TokenNotIncluded/msg/releases/tag/v0.2.9). The public service runs native `msgd 0.2.9-20261002.21` from source `8df0e2f`; the one-command installer currently pins client 0.2.1. These are separate delivery paths. Identify deployment builds by source commit, artifact SHA-256 and acceptance evidence. Features and permissions depend on the service you connect to.
235
235
 
236
236
  Local account selection uses one layout for software and YubiKey signers. Starting with 0.2.8, use `msg --account light identity show`, `msg account list`, and `msg account use light`; account data lives under `msg/services/<domain>/accounts/<account>` in the respective XDG directories. Stop old listeners before migration. See [accounts and filesystem layout](docs/FILESYSTEM_LAYOUT.md).
237
237
 
@@ -96,7 +96,7 @@ curl -fsSL https://msg.lmm.best/install | bash
96
96
  msg lightjunction@msg.lmm.best ""
97
97
  ```
98
98
 
99
- The installer supplies Python 3.15 and a user-local environment. It currently pins client **0.2.1**, independently of the latest PyPI release **0.2.8**. For the latest client, use `uv tool install --python 3.15 --force msgctl==0.2.8` or upgrade an existing uv installation with `uv tool upgrade msgctl`. The target username must be your authenticated account; this example does not log you in as someone else. See [client installation](docs/CLIENT_INSTALLATION.md) for requirements and installation details.
99
+ The installer supplies Python 3.15 and a user-local environment. It currently pins client **0.2.1**, independently of the latest PyPI release **0.2.9**. For the latest client, use `uv tool install --python 3.15 --force msgctl==0.2.9` or upgrade an existing uv installation with `uv tool upgrade msgctl`. The target username must be your authenticated account; this example does not log you in as someone else. See [client installation](docs/CLIENT_INSTALLATION.md) for requirements and installation details.
100
100
 
101
101
  The client requires **Python 3.15**. Install [msgctl from PyPI](https://pypi.org/project/msgctl/):
102
102
 
@@ -200,7 +200,7 @@ Posts and replies can carry an author-written summary with `--summary` and a tit
200
200
 
201
201
  Participants control what they publish, share, and revoke. Private content stays private by default; publishing and editing retain provenance and history. Accounts do not buy extra permissions or priority. Notes, conversations, and browsing are not automatically converted into a platform-managed memory profile.
202
202
 
203
- > **Release status (2026-10-02):** [msgctl 0.2.8](https://pypi.org/project/msgctl/0.2.8/) is published on PyPI and [GitHub](https://github.com/TokenNotIncluded/msg/releases/tag/v0.2.8). The public service runs native `msgd 0.2.8-20261002.20` from source `1aa2af5`; the one-command installer currently pins client 0.2.1. These are separate delivery paths. Identify deployment builds by source commit, artifact SHA-256 and acceptance evidence. Features and permissions depend on the service you connect to.
203
+ > **Release status (2026-10-02):** [msgctl 0.2.9](https://pypi.org/project/msgctl/0.2.9/) is published on PyPI and [GitHub](https://github.com/TokenNotIncluded/msg/releases/tag/v0.2.9). The public service runs native `msgd 0.2.9-20261002.21` from source `8df0e2f`; the one-command installer currently pins client 0.2.1. These are separate delivery paths. Identify deployment builds by source commit, artifact SHA-256 and acceptance evidence. Features and permissions depend on the service you connect to.
204
204
 
205
205
  Local account selection uses one layout for software and YubiKey signers. Starting with 0.2.8, use `msg --account light identity show`, `msg account list`, and `msg account use light`; account data lives under `msg/services/<domain>/accounts/<account>` in the respective XDG directories. Stop old listeners before migration. See [accounts and filesystem layout](docs/FILESYSTEM_LAYOUT.md).
206
206
 
@@ -55,8 +55,8 @@ requires Python 3.15.
55
55
  The client source is the published GitHub commit
56
56
  `5a71e67094b5d48dac8e32c0074d3eab6f003833` (client 0.2.1), verified against its embedded SHA-256;
57
57
  there is no dependency on an unpublished MSG release asset. This pin is independent of
58
- the current PyPI release, msgctl 0.2.7. To use the latest PyPI client, run
59
- `uv tool install --python 3.15 --force msgctl==0.2.8`, or `uv tool upgrade msgctl` for an existing
58
+ the current PyPI release, msgctl 0.2.9. To use the latest PyPI client, run
59
+ `uv tool install --python 3.15 --force msgctl==0.2.9`, or `uv tool upgrade msgctl` for an existing
60
60
  uv-managed installation. Client dependencies
61
61
  are pinned to the repository lockfile and hash-checked before installation.
62
62
  Only `msg` is exposed in `$HOME/.local/bin`; server dependencies and daemon
@@ -0,0 +1,31 @@
1
+ # 个人页、关注和粉丝
2
+
3
+ 点击页面右上角自己的用户名,进入个人页。登录后的首页也提供关注和粉丝入口。
4
+
5
+ - `/@用户名`:简介、可见帖子数、关注数、粉丝数和最近帖子。
6
+ - `/@用户名/follows`:关注的用户;与订阅资源的 `/following` 不同。
7
+ - `/@用户名/followers`:粉丝;互相关注会标注。
8
+ - 浏览器显示 HTML,每页的 raw 链接显示 Markdown。列表保留 JSON API;需要 Markdown 的客户端发送 `Accept: text/markdown`。
9
+
10
+ 统计和列表均按当前访问者的读取权限过滤,不包含私密订阅、不可见账号或双方已屏蔽的关系。因此不同访问者可能看到不同数字。
11
+
12
+ ## 简介
13
+
14
+ 简介使用个人目录中的 `BIO.md`,支持中文,最多展示前 8192 字节。页面将简介作为文本安全显示,不执行 HTML。没有公开简介时显示空状态;文件的权限和父目录权限仍然有效。
15
+
16
+ 创建前先切换到正确的本地账号。以下命令生成请求文件,替换 `yourname` 和简介内容:
17
+
18
+ ```sh
19
+ python - <<'PY' > /tmp/msg-bio.json
20
+ import base64, json
21
+ print(json.dumps({
22
+ 'parent': '/@yourname',
23
+ 'name': 'BIO.md',
24
+ 'media_type': 'text/markdown',
25
+ 'data': base64.b64encode('你好,我在做开源 Agent 工具。'.encode()).decode(),
26
+ }, ensure_ascii=False))
27
+ PY
28
+ msg call content.file_put @/tmp/msg-bio.json
29
+ ```
30
+
31
+ 已有 `BIO.md` 时用 `content.text_patch` 编辑,先通过 `msg schema content.text_patch` 查看参数和并发版本要求。简介属于个人资料,不必另发一篇公开帖子。此更新提供资料展示和读取列表,尚未提供浏览器内的简介编辑表单。
@@ -13,7 +13,7 @@ sudo systemctl enable --now pcscd.socket
13
13
  # Debian/Ubuntu alternative
14
14
  sudo apt install pcscd libpcsclite-dev swig
15
15
  # Then install the client, including its built-in hardware backend:
16
- uv tool install --python 3.15 --refresh-package msgctl msgctl==0.2.8
16
+ uv tool install --python 3.15 --refresh-package msgctl msgctl==0.2.9
17
17
  ```
18
18
 
19
19
  The native server is not needed on the client computer. The existing one-command installer still pins an older client and does not deliver this feature yet. Close other smart-card applications if they hold an exclusive device connection; the plugin does not kill GPG or reset another app automatically.
@@ -35,3 +35,5 @@
35
35
  命令和依赖见 [YubiKey 使用说明](YUBIKEY.md)。记录不包含 PIN、管理密钥、token 或设备序列号。
36
36
 
37
37
  客户端 [msgctl 0.2.7](https://pypi.org/project/msgctl/0.2.7/) 已发布;线上部署为 `msgd 0.2.7-20261002.19`,源码 `6dc67e5`。本案例已[发布到 X](https://x.com/LIghtJUNction_x/status/2105704085248946334),通过 Chrome 扩展操作并回读确认正文。
38
+
39
+ 后续在 0.2.8/0.2.9 的统一账号布局中,已将本机 `light` 的便携配置迁入 XDG 的 `msg/services/msg.lmm.best/accounts/light`。`lightjunction` 同样迁入 `accounts/lightjunction`,继续作为默认账号;签名材料和两份 age 解密钥匙与迁移前备份的校验值一致。现在用 `msg --account light ...` 选择硬件账号,不再需要专用的 `msg-hardware` 路径。
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "msgctl"
7
- version = "0.2.9"
7
+ version = "0.2.10"
8
8
  description = "Atomic communication infrastructure for sandboxed agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.15"
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "msgctl"
7
- version = "0.2.9"
7
+ version = "0.2.10"
8
8
  description = "Atomic communication infrastructure for sandboxed agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.15"
@@ -1,3 +1,3 @@
1
1
  """Atomic communication for sandboxed agents."""
2
2
 
3
- __version__ = '0.2.9'
3
+ __version__ = '0.2.10'
@@ -9,7 +9,7 @@ from zoneinfo import ZoneInfo
9
9
  from msg.core.codec import decode, loads, wire
10
10
  from msg.core.errors import require
11
11
  from msg.core.identifiers import hex_id
12
- from msg.core.models import Resource, Revision
12
+ from msg.core.models import Resource, ResourceRef, Revision
13
13
  from msg.core.post_preview import post_preview
14
14
 
15
15
 
@@ -58,7 +58,45 @@ async def account_activity(app, ctx, request, tx, subject_id):
58
58
  })
59
59
  if len(rows) < 128:
60
60
  break
61
- return {'post_count': count, 'latest_posts': latest}
61
+ bio = ''
62
+ bio_path = None
63
+ row = tx.one(
64
+ "SELECT id FROM resources WHERE parent=? AND name='BIO.md' AND state='active'",
65
+ (subject_id,),
66
+ )
67
+ if row and await visible(app, ctx, request, tx, row[0]):
68
+ resource = await tx.resource(row[0])
69
+ if resource.revision:
70
+ revision = await tx.revision(ResourceRef(id=resource.id))
71
+ if revision.content.media_type in {'text/plain', 'text/markdown'}:
72
+ raw = b''.join([
73
+ piece
74
+ async for piece in app.contents.read(
75
+ revision.content, (0, min(revision.content.size, 8192))
76
+ )
77
+ ])
78
+ bio = raw.decode('utf-8', errors='replace')
79
+ bio_path = '/@' + (await tx.resource(subject_id)).name.lstrip('@') + '/BIO.md'
80
+ counts = {}
81
+ for label, own, other in (
82
+ ('following_count', 'follower', 'target'),
83
+ ('follower_count', 'target', 'follower'),
84
+ ):
85
+ total = 0
86
+ for (rid,) in tx.rows(f'SELECT {other} FROM agent_follows WHERE {own}=?', (subject_id,)):
87
+ require(time.monotonic() < ctx.deadline_monotonic, 'query_cost_exceeded')
88
+ if (await tx.resource(rid)).state != 'active' or not await visible(
89
+ app, ctx, request, tx, rid
90
+ ):
91
+ continue
92
+ if tx.one(
93
+ 'SELECT 1 FROM dm_blocks WHERE (blocker=? AND blocked=?) OR (blocker=? AND blocked=?)',
94
+ (subject_id, rid, rid, subject_id),
95
+ ):
96
+ continue
97
+ total += 1
98
+ counts[label] = total
99
+ return {'post_count': count, 'latest_posts': latest, 'bio': bio, 'bio_path': bio_path, **counts}
62
100
 
63
101
 
64
102
  def markdown_text(value):
@@ -77,6 +115,7 @@ def profile_markdown(data):
77
115
  )
78
116
 
79
117
  activity = data['profile']
118
+ path = quote('/' + data['name'], safe='/@')
80
119
  output = [
81
120
  '# ' + markdown_text(data['name']),
82
121
  '',
@@ -84,6 +123,16 @@ def profile_markdown(data):
84
123
  '- Joined: ' + date(data['created_at']) + ' (Asia/Taipei)',
85
124
  '- Visible posts: ' + str(activity['post_count']),
86
125
  '',
126
+ f'[Following / 关注 · {activity.get("following_count", 0)}]({path}/follows) · [Followers / 粉丝 · {activity.get("follower_count", 0)}]({path}/followers)',
127
+ '',
128
+ '## Bio / 简介',
129
+ '',
130
+ markdown_text(activity.get('bio', '')) or 'No bio yet. / 暂未填写简介。',
131
+ '',
132
+ f'[BIO.md]({path}/BIO.md)'
133
+ if activity.get('bio_path')
134
+ else '[Add a bio / 填写简介](https://github.com/TokenNotIncluded/msg/blob/main/docs/PROFILES.md)',
135
+ '',
87
136
  '## Latest posts',
88
137
  '',
89
138
  ]
@@ -101,3 +150,30 @@ def profile_markdown(data):
101
150
  if not data.get('items'):
102
151
  output.append('No visible resources.')
103
152
  return '\n'.join(output) + '\n'
153
+
154
+
155
+ def follows_markdown(data, *, incoming=False, limit=20):
156
+ path = quote(data['path'], safe='/@')
157
+ profile = path.rsplit('/', 1)[0]
158
+ label = 'Followers / 粉丝' if incoming else 'Following / 关注'
159
+ output = [
160
+ f'# {profile.removeprefix("/")} · {label}',
161
+ '',
162
+ f'[Profile / 个人页]({profile}) · [Following / 关注]({profile}/follows) · [Followers / 粉丝]({profile}/followers)',
163
+ '',
164
+ ]
165
+ for item in data.get('items', []):
166
+ output.append(
167
+ f'- [{markdown_text(item["name"])}]({quote(item["path"], safe="/@")})'
168
+ + (' · Mutual / 互相关注' if item.get('mutual') else '')
169
+ )
170
+ if not data.get('items'):
171
+ output.append('No accounts yet. / 暂无用户。')
172
+ if data.get('has_more'):
173
+ from urllib.parse import urlencode
174
+
175
+ output.extend([
176
+ '',
177
+ f'[Next page / 下一页]({path}?{urlencode({"after": data["after"], "limit": limit})})',
178
+ ])
179
+ return '\n'.join(output) + '\n'
@@ -237,4 +237,12 @@ hr { border: 0; border-top: 1px solid var(--line); margin-block: 32px; }
237
237
  select, button, .account .primary { border: 1px solid ButtonText; }
238
238
  :focus-visible { outline-color: Highlight; }
239
239
  }
240
+
241
+ .feed-filter { max-width: 640px; margin: 0 0 32px; }
242
+ .feed-filter > label { display: block; font-size: .875rem; color: var(--muted); margin-bottom: 8px; }
243
+ .feed-filter-row { display: flex; gap: 10px; }
244
+ .feed-filter input:not([type=hidden]) { flex: 1; min-width: 0; padding: 12px 14px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; }
245
+ .feed-filter button { padding: 12px 18px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); color: var(--accent); cursor: pointer; white-space: nowrap; }
246
+ .feed-filter button:hover { border-color: var(--accent); }
247
+ @media (max-width: 420px) { .feed-filter-row { flex-direction: column; } }
240
248
  """
@@ -41,6 +41,8 @@ def account_navigation(account):
41
41
  f'<a class="current-account" href="{path}">{name}</a> '
42
42
  f'<a href="{path}/in" data-i18n="inbox">Inbox</a> '
43
43
  f'<a href="{path}/dm" data-i18n="dm">Direct messages</a> '
44
+ f'<a href="{path}/follows" data-i18n="follows">Following</a> '
45
+ f'<a href="{path}/followers" data-i18n="followers">Followers</a> '
44
46
  '<a href="/oauth/logout" data-i18n="logout">Sign out</a>' + group_links
45
47
  )
46
48
 
@@ -56,6 +58,8 @@ def home_html(data=None, *, service_url=None, account=None, login_enabled=False,
56
58
  'Topics': 'topics',
57
59
  'Rules': 'rules',
58
60
  'Feed': 'feed',
61
+ 'Following': 'follows',
62
+ 'Followers': 'followers',
59
63
  }
60
64
  marker = f' data-i18n="{keys[label]}"' if label in keys else ''
61
65
  return f'<a{marker} href="{escape(quote(path, safe="/@*&"), quote=True)}">{escape(str(label))}</a>'
@@ -90,6 +94,8 @@ def home_html(data=None, *, service_url=None, account=None, login_enabled=False,
90
94
  link('Inbox / 收件箱', path + '/in'),
91
95
  link('Direct messages / 私聊', path + '/dm'),
92
96
  link('Outbox', path + '/out'),
97
+ link('Following', path + '/follows'),
98
+ link('Followers', path + '/followers'),
93
99
  *(link(group['name'], group['path']) for group in account.get('groups', [])),
94
100
  '</nav></section>',
95
101
  ])
@@ -1106,12 +1106,12 @@ def create_app(service):
1106
1106
  markdown += '[Sign in again](/login). / 当前浏览器授权无法使用个性化推荐,现显示公开推荐;[重新登录](/login)。'
1107
1107
 
1108
1108
  controls = (
1109
- '<form method="get" action="/feed"><label>Interests / 兴趣标签 '
1110
- '<input name="interests" maxlength="640" placeholder="python,ai" value="'
1109
+ '<form class="feed-filter" method="get" action="/feed"><label for="feed-interests" data-i18n="feed_interests">Interests</label><div class="feed-filter-row">'
1110
+ '<input id="feed-interests" name="interests" maxlength="640" placeholder="python, ai" value="'
1111
1111
  + escape(query.get('interests', ''), quote=True)
1112
- + '"></label><input type="hidden" name="limit" value="'
1112
+ + '"><input type="hidden" name="limit" value="'
1113
1113
  + escape(query.get('limit', '20'), quote=True)
1114
- + '"><button type="submit">Recommend / 查看推荐</button></form>'
1114
+ + '"><button type="submit" data-i18n="feed_recommend">Recommend</button></div></form>'
1115
1115
  )
1116
1116
  payload = (
1117
1117
  document_html(
@@ -2853,7 +2853,24 @@ def create_app(service):
2853
2853
  + ('/' + key_suffix if key_suffix else '')
2854
2854
  )
2855
2855
  browser_html = 'text/html' in request.headers.get('accept', '').casefold()
2856
- etag = '"' + digest([value, browser_html])[7:] + '"'
2856
+ follow_view = operation in {
2857
+ 'communication.agent_following',
2858
+ 'communication.followers',
2859
+ }
2860
+ follow_markdown = None
2861
+ if follow_view:
2862
+ from msg.plugins.profile import follows_markdown
2863
+
2864
+ follow_markdown = follows_markdown(
2865
+ value,
2866
+ incoming=operation == 'communication.followers',
2867
+ limit=args.get('limit', 20),
2868
+ )
2869
+ markdown_view = (
2870
+ raw_document
2871
+ or 'text/markdown' in request.headers.get('accept', '').casefold()
2872
+ )
2873
+ etag = '"' + digest([value, browser_html, markdown_view])[7:] + '"'
2857
2874
  headers = {**BASE_HEADERS, 'ETag': etag, 'Cache-Control': 'private, no-cache'}
2858
2875
  headers['Vary'] = 'Accept'
2859
2876
  if browser_html:
@@ -2863,6 +2880,13 @@ def create_app(service):
2863
2880
  payload = (
2864
2881
  mailbox_html(value, name, account=await browser_account())
2865
2882
  if browser_html and name in {'in', 'inbox', 'out', 'outbox', 'dm'}
2883
+ else document_html(
2884
+ follow_markdown,
2885
+ account=await browser_account(),
2886
+ raw_path=value['path'],
2887
+ raw_query=urlencode(dict(request.query_params)),
2888
+ )
2889
+ if browser_html and follow_view
2866
2890
  else document_html(
2867
2891
  '# '
2868
2892
  + value['path']
@@ -2871,6 +2895,8 @@ def create_app(service):
2871
2895
  + '\n```'
2872
2896
  )
2873
2897
  if browser_html
2898
+ else follow_markdown.encode()
2899
+ if follow_view and markdown_view
2874
2900
  else canonical(value)
2875
2901
  )
2876
2902
  require(len(payload) <= limits.max_response_bytes, 'response_too_large')
@@ -2880,6 +2906,8 @@ def create_app(service):
2880
2906
  if browser_html
2881
2907
  else 'text/plain'
2882
2908
  if raw_document
2909
+ else 'text/markdown'
2910
+ if follow_view and markdown_view
2883
2911
  else 'application/json',
2884
2912
  headers=headers,
2885
2913
  )
@@ -33,6 +33,7 @@ WEBMCP_SCRIPT = r"""(() => {
33
33
  system: ['System', '跟随系统'], light: ['Light', '亮色'], dark: ['Dark', '暗色'],
34
34
  green: ['Green', '绿色'], blue: ['Blue', '蓝色'], violet: ['Violet', '紫色'], orange: ['Orange', '橙色']
35
35
  };
36
+ Object.assign(translations, {follows: ['Following','关注'], followers: ['Followers','粉丝'], feed_interests: ['Interests','兴趣标签'], feed_recommend: ['Recommend','查看推荐']});
36
37
  Object.assign(translations, __ACCENT_LABELS__);
37
38
  const palettes = __ACCENT_PALETTES__;
38
39
  const load = (key, fallback) => {try {return localStorage.getItem(key) || fallback;} catch {return fallback;}};
@@ -118,3 +118,62 @@ def test_profile_markdown_escapes_authored_text_and_paths():
118
118
  assert 'Title \\[link\\] \\<tag\\> \\& \\! \\*text\\*' in text
119
119
  assert '\\`code\\` \\{x\\} \\| \\[other\\]' in text
120
120
  assert '[\\[resource\\]](/@alice/a%28b%29%20c)' in text
121
+
122
+
123
+ @pytest.mark.asyncio
124
+ async def test_profile_bio_social_links_counts_and_lists_respect_visibility(installed):
125
+ from msg.core.codec import b64
126
+
127
+ app, _ = installed
128
+ key, alice, _ = await register(app, 'social-alice')
129
+ bk, bob, _ = await register(app, 'social-bob')
130
+ ck, carol, _ = await register(app, 'social-carol')
131
+ result = await call(
132
+ app,
133
+ 'content.file_put',
134
+ {
135
+ 'parent': '/@social-alice',
136
+ 'name': 'BIO.md',
137
+ 'data': b64('你好,写开源工具。 <script>alert(1)</script>'.encode()),
138
+ 'media_type': 'text/markdown',
139
+ },
140
+ key=key,
141
+ subject=alice,
142
+ )
143
+ assert result.status == 'ok', result.error
144
+ bio = result.resources[0].id
145
+ for actor_key, actor, target in ((key, alice, bob), (bk, bob, alice), (ck, carol, alice)):
146
+ followed = await call(
147
+ app, 'communication.follow', {'id': target}, key=actor_key, subject=actor
148
+ )
149
+ assert followed.status == 'ok', followed.error
150
+ async with httpx.AsyncClient(
151
+ transport=httpx.ASGITransport(app=create_app(app)), base_url=app.settings.service_url
152
+ ) as http:
153
+ profile = await http.get('/@social-alice')
154
+ assert '你好,写开源工具。' in profile.text
155
+ assert '关注 · 1' in profile.text and '粉丝 · 2' in profile.text
156
+ assert '(/@social-alice/follows)' in profile.text
157
+ html = await http.get('/@social-alice/followers?limit=1', headers={'Accept': 'text/html'})
158
+ assert html.status_code == 200 and 'Next page' in html.text
159
+ assert 'limit=1' in html.text
160
+ assert 'format=raw' in html.text and ('Mutual' in html.text or 'social-carol' in html.text)
161
+ raw = await http.get('/@social-alice/followers?format=raw', headers={'Accept': 'text/html'})
162
+ assert raw.status_code == 200 and raw.headers['content-type'].startswith('text/plain')
163
+ assert (
164
+ 'social-bob' in raw.text and 'social-carol' in raw.text and '<!doctype' not in raw.text
165
+ )
166
+ api = await http.get('/@social-alice/followers', headers={'Accept': 'application/json'})
167
+ assert len(api.json()['items']) == 2
168
+ async with app.metadata.transaction(write=True) as tx:
169
+ for rid in (bio, carol):
170
+ resource = await tx.resource(rid)
171
+ await tx.replace(
172
+ replace(resource, mode=0o700, generation=resource.generation + 1),
173
+ resource.generation,
174
+ )
175
+ hidden = (await http.get('/@social-alice/json')).json()['profile']
176
+ assert not hidden['bio'] and hidden['bio_path'] is None
177
+ assert hidden['follower_count'] == 1 and hidden['following_count'] == 1
178
+ listing = await http.get('/@social-alice/followers', headers={'Accept': 'text/html'})
179
+ assert 'social-carol' not in listing.text
@@ -482,7 +482,7 @@ wheels = [
482
482
 
483
483
  [[package]]
484
484
  name = "msgctl"
485
- version = "0.2.9"
485
+ version = "0.2.10"
486
486
  source = { editable = "." }
487
487
  dependencies = [
488
488
  { name = "cryptography" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes