socialcli 0.3.0__tar.gz → 0.3.2__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 (227) hide show
  1. {socialcli-0.3.0 → socialcli-0.3.2}/.gitignore +3 -0
  2. socialcli-0.3.2/LICENSE +48 -0
  3. {socialcli-0.3.0 → socialcli-0.3.2}/PKG-INFO +12 -13
  4. {socialcli-0.3.0 → socialcli-0.3.2}/README.md +7 -5
  5. socialcli-0.3.2/pyproject.toml +183 -0
  6. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/agent_errors.py +75 -4
  7. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/agent_guide.py +4 -4
  8. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/engagement.py +69 -8
  9. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/engagement_cli.py +23 -3
  10. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/identity.py +30 -13
  11. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/inbox.py +5 -1
  12. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/inventory.py +4 -0
  13. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/batches.py +20 -10
  14. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/changes.py +30 -15
  15. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/community_changes.py +4 -2
  16. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/snippet_readback.py +9 -0
  17. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/youtube_community.py +4 -4
  18. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/youtube_resources.py +13 -3
  19. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/media_preflight.py +7 -2
  20. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/operation_output.py +3 -0
  21. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/postfile.py +12 -14
  22. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/read_reports.py +4 -1
  23. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/ui/assets/agent-manual.md +83 -20
  24. socialcli-0.3.2/socialctl/ui/assets/agents.md +33 -0
  25. socialcli-0.3.0/pyproject.toml +0 -51
  26. socialcli-0.3.0/socialctl/connection_service/__main__.py +0 -33
  27. socialcli-0.3.0/socialctl/connection_service/app.py +0 -496
  28. socialcli-0.3.0/socialctl/connection_service/assets/PLATFORM-LOGOS-LICENSE.txt +0 -50
  29. socialcli-0.3.0/socialctl/connection_service/assets/connection.css +0 -75
  30. socialcli-0.3.0/socialctl/connection_service/assets/facebook.webp +0 -0
  31. socialcli-0.3.0/socialctl/connection_service/assets/instagram.svg +0 -194
  32. socialcli-0.3.0/socialctl/connection_service/assets/socialcli-logo.png +0 -0
  33. socialcli-0.3.0/socialctl/connection_service/assets/tiktok.png +0 -0
  34. socialcli-0.3.0/socialctl/connection_service/assets/youtube.svg +0 -1
  35. socialcli-0.3.0/socialctl/connection_service/landing.py +0 -146
  36. socialcli-0.3.0/socialctl/connection_service/legacy.py +0 -48
  37. socialcli-0.3.0/socialctl/connection_service/peer.py +0 -13
  38. socialcli-0.3.0/socialctl/connection_service/providers.py +0 -324
  39. socialcli-0.3.0/socialctl/connection_service/settings.py +0 -76
  40. socialcli-0.3.0/socialctl/connection_service/store.py +0 -124
  41. socialcli-0.3.0/socialctl/connections/__init__.py +0 -0
  42. socialcli-0.3.0/socialctl/saas/__init__.py +0 -1
  43. socialcli-0.3.0/socialctl/saas/access.py +0 -75
  44. socialcli-0.3.0/socialctl/saas/auth.py +0 -213
  45. socialcli-0.3.0/socialctl/saas/backup.py +0 -124
  46. socialcli-0.3.0/socialctl/saas/billing.py +0 -327
  47. socialcli-0.3.0/socialctl/saas/billing_enrollment.py +0 -1237
  48. socialcli-0.3.0/socialctl/saas/billing_enrollment_schema.py +0 -519
  49. socialcli-0.3.0/socialctl/saas/billing_inventory.py +0 -775
  50. socialcli-0.3.0/socialctl/saas/billing_reconcile.py +0 -127
  51. socialcli-0.3.0/socialctl/saas/billing_routes.py +0 -27
  52. socialcli-0.3.0/socialctl/saas/budget.py +0 -66
  53. socialcli-0.3.0/socialctl/saas/connections.py +0 -374
  54. socialcli-0.3.0/socialctl/saas/consent.py +0 -52
  55. socialcli-0.3.0/socialctl/saas/lifecycle.py +0 -341
  56. socialcli-0.3.0/socialctl/saas/mail.py +0 -89
  57. socialcli-0.3.0/socialctl/saas/maintenance.py +0 -68
  58. socialcli-0.3.0/socialctl/saas/meta_user.py +0 -298
  59. socialcli-0.3.0/socialctl/saas/meta_webhooks.py +0 -358
  60. socialcli-0.3.0/socialctl/saas/migration.py +0 -107
  61. socialcli-0.3.0/socialctl/saas/models.py +0 -8
  62. socialcli-0.3.0/socialctl/saas/operations.py +0 -102
  63. socialcli-0.3.0/socialctl/saas/pages.py +0 -126
  64. socialcli-0.3.0/socialctl/saas/pairing.py +0 -158
  65. socialcli-0.3.0/socialctl/saas/permissions.py +0 -57
  66. socialcli-0.3.0/socialctl/saas/reminders.py +0 -128
  67. socialcli-0.3.0/socialctl/saas/renewal.py +0 -74
  68. socialcli-0.3.0/socialctl/saas/restore_guard.py +0 -229
  69. socialcli-0.3.0/socialctl/saas/revocation.py +0 -97
  70. socialcli-0.3.0/socialctl/saas/rotation.py +0 -114
  71. socialcli-0.3.0/socialctl/saas/routes.py +0 -221
  72. socialcli-0.3.0/socialctl/saas/settings.py +0 -34
  73. socialcli-0.3.0/socialctl/saas/store.py +0 -106
  74. socialcli-0.3.0/socialctl/saas/temporary_media.py +0 -245
  75. socialcli-0.3.0/socialctl/saas/webhooks.py +0 -76
  76. socialcli-0.3.0/socialctl/ui/assets/agents.md +0 -27
  77. socialcli-0.3.0/socialctl/ui/assets/components.css +0 -20
  78. socialcli-0.3.0/socialctl/ui/assets/connection-layout.css +0 -53
  79. socialcli-0.3.0/socialctl/ui/assets/otp.template.html +0 -10
  80. socialcli-0.3.0/socialctl/ui/assets/tokens.css +0 -1
  81. socialcli-0.3.0/socialctl/ui/assets/trial.template.html +0 -11
  82. socialcli-0.3.0/socialctl/ui/assets/web-layout.css +0 -38
  83. socialcli-0.3.0/socialctl/ui/email/otp.html +0 -10
  84. socialcli-0.3.0/socialctl/ui/email/trial.html +0 -11
  85. /socialcli-0.3.0/LICENSE → /socialcli-0.3.2/LICENSE-MIT-LEGACY +0 -0
  86. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/__init__.py +0 -0
  87. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/__main__.py +0 -0
  88. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/adapters/__init__.py +0 -0
  89. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/adapters/base.py +0 -0
  90. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/adapters/errores.py +0 -0
  91. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/adapters/facebook.py +0 -0
  92. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/adapters/instagram.py +0 -0
  93. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/adapters/tiktok.py +0 -0
  94. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/adapters/youtube.py +0 -0
  95. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/approval_cli.py +0 -0
  96. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/auth.py +0 -0
  97. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/authflow.py +0 -0
  98. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/brands.py +0 -0
  99. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/capabilities.py +0 -0
  100. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/capabilities.yml +0 -0
  101. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/cli.py +0 -0
  102. {socialcli-0.3.0/socialctl/connection_service → socialcli-0.3.2/socialctl/connections}/__init__.py +0 -0
  103. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/account_cli.py +0 -0
  104. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/cli.py +0 -0
  105. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/client.py +0 -0
  106. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/credential_cli.py +0 -0
  107. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/credential_store.py +0 -0
  108. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/file_store.py +0 -0
  109. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/keychain.py +0 -0
  110. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/meta_user.py +0 -0
  111. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/rotation_cli.py +0 -0
  112. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/saas_client.py +0 -0
  113. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/connections/temporary_media.py +0 -0
  114. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/delivery_options.py +0 -0
  115. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/executor.py +0 -0
  116. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/formatter.py +0 -0
  117. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/hosted_media.py +0 -0
  118. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/inbox_cli.py +0 -0
  119. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/inventory_cli.py +0 -0
  120. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/inventory_sources.py +0 -0
  121. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/__init__.py +0 -0
  122. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/batch_cli.py +0 -0
  123. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/cli.py +0 -0
  124. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/comments_cli.py +0 -0
  125. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/community_batch_cli.py +0 -0
  126. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/community_batches.py +0 -0
  127. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/community_cli.py +0 -0
  128. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/community_schema.py +0 -0
  129. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/facebook_groups.py +0 -0
  130. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/groups_cli.py +0 -0
  131. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/inbox_readers.py +0 -0
  132. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/meta_changes.py +0 -0
  133. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/meta_cli.py +0 -0
  134. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/meta_client.py +0 -0
  135. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/meta_comment_inbox.py +0 -0
  136. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/meta_comments.py +0 -0
  137. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/meta_errors.py +0 -0
  138. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/meta_pagination.py +0 -0
  139. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/meta_schema.py +0 -0
  140. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/meta_webhooks.py +0 -0
  141. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/metadata_parts.py +0 -0
  142. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/owned_assets.py +0 -0
  143. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/owned_changes.py +0 -0
  144. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/owned_cli.py +0 -0
  145. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/owned_reorder.py +0 -0
  146. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/owned_schema.py +0 -0
  147. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/reply_context.py +0 -0
  148. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/reply_evidence.py +0 -0
  149. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/resource_changes.py +0 -0
  150. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/resource_cli.py +0 -0
  151. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/stories.py +0 -0
  152. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/stories_cli.py +0 -0
  153. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/youtube.py +0 -0
  154. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/youtube_metadata.py +0 -0
  155. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/management/youtube_owned.py +0 -0
  156. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/media.py +0 -0
  157. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/media_cli.py +0 -0
  158. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/media_ingress.py +0 -0
  159. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/media_registry.py +0 -0
  160. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/media_requirements.py +0 -0
  161. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/__init__.py +0 -0
  162. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/almacen.py +0 -0
  163. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/analytics_changes.py +0 -0
  164. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/analytics_cli.py +0 -0
  165. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/analytics_client.py +0 -0
  166. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/analytics_ingest.py +0 -0
  167. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/analytics_schema.py +0 -0
  168. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/base.py +0 -0
  169. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/facebook.py +0 -0
  170. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/insights.py +0 -0
  171. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/instagram.py +0 -0
  172. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/modelos.py +0 -0
  173. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/piezas.py +0 -0
  174. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/reach.py +0 -0
  175. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/reporting_client.py +0 -0
  176. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/resumen.py +0 -0
  177. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/slugs.py +0 -0
  178. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/tiktok.py +0 -0
  179. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/metricas/youtube.py +0 -0
  180. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/migration_cli.py +0 -0
  181. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/migration_files.py +0 -0
  182. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/models.py +0 -0
  183. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/__init__.py +0 -0
  184. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/api_delivery.py +0 -0
  185. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/api_reconcile.py +0 -0
  186. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/approval.py +0 -0
  187. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/cadence.py +0 -0
  188. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/cli.py +0 -0
  189. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/dispatcher.py +0 -0
  190. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/facebook.py +0 -0
  191. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/facebook_reels.py +0 -0
  192. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/first_comment.py +0 -0
  193. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/handoff.py +0 -0
  194. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/instagram_delivery.py +0 -0
  195. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/instagram_runtime.py +0 -0
  196. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/inventory.py +0 -0
  197. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/migration.py +0 -0
  198. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/models.py +0 -0
  199. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/reconcile.py +0 -0
  200. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/remote_data.py +0 -0
  201. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/report.py +0 -0
  202. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/store.py +0 -0
  203. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/verification.py +0 -0
  204. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/native_schedule/youtube.py +0 -0
  205. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/plantillas/accounts.yml +0 -0
  206. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/plantillas/brand.md +0 -0
  207. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/plantillas/estrategia.md +0 -0
  208. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/preflight.py +0 -0
  209. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/publication_policy.py +0 -0
  210. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/publication_status.py +0 -0
  211. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/publication_steps.py +0 -0
  212. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/publish_output.py +0 -0
  213. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/publisher.py +0 -0
  214. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/queue_migration.py +0 -0
  215. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/read_budget.py +0 -0
  216. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/rutas.py +0 -0
  217. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/schedule_remote.py +0 -0
  218. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/schedule_sqlite.py +0 -0
  219. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/scheduler.py +0 -0
  220. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/scheduler_launchd.py +0 -0
  221. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/scheduler_systemd.py +0 -0
  222. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/source_links.py +0 -0
  223. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/ui/__init__.py +0 -0
  224. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/upload_consent.py +0 -0
  225. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/workspace.py +0 -0
  226. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/youtube_data.py +0 -0
  227. {socialcli-0.3.0 → socialcli-0.3.2}/socialctl/youtube_data_service.py +0 -0
@@ -36,3 +36,6 @@ build/
36
36
  **/service.env
37
37
  **/auth.env
38
38
  **/database.env
39
+
40
+ # Private server artifacts must never enter public release uploads.
41
+ private-dist/
@@ -0,0 +1,48 @@
1
+ SocialCli Proprietary Software License
2
+ Version 1 — October 24, 2026
3
+ Copyright (c) 2026 Engels Florentino. All rights reserved.
4
+ SocialCli is operated by Florentino.pro.
5
+
6
+ 1. Scope
7
+ This license applies to SocialCli releases beginning with version 0.3.2 and
8
+ subsequent releases that include this license. It does not revoke or restrict
9
+ rights already granted for earlier MIT-licensed releases. The historical MIT
10
+ notice is preserved in LICENSE-MIT-LEGACY. Third-party components remain subject
11
+ to their own licenses; this license does not replace those terms.
12
+
13
+ 2. Authorized client use
14
+ You may download, install, run and make necessary backup copies of the official
15
+ SocialCli client to access the SocialCli hosted service through an authorized
16
+ account. You may use it for your personal or business social accounts, including
17
+ accounts you are authorized to manage for clients. You may let your authorized
18
+ AI agents operate the client under your supervision and the same account terms.
19
+ Service access requires an eligible trial, subscription or other access expressly
20
+ granted by Florentino.pro. Installing the client does not grant service access,
21
+ provider credentials, unlimited usage or ownership of the software.
22
+
23
+ 3. Reserved rights
24
+ Except as expressly allowed above, required by applicable law, or separately
25
+ agreed in writing by the copyright holder, you may not redistribute, sublicense,
26
+ sell, rent or offer this software as a service; modify or use it to build or run
27
+ a competing product or hosted service; bypass access, subscription or security
28
+ controls; or remove copyright, license or attribution notices. No license to the
29
+ private server implementation is granted to customers. No trademark rights in
30
+ SocialCli or Florentino.pro are granted. You retain your rights in your content
31
+ and data. These restrictions do not limit rights separately granted under the
32
+ legacy MIT license or a third-party license.
33
+
34
+ 4. Service terms
35
+ Use of the hosted service is also subject to https://socialcli.app/terms.html.
36
+ Your subscription pays for service access, not ownership of or redistribution
37
+ rights to the software. Account eligibility and access are determined by the
38
+ service, not by a local client setting.
39
+
40
+ 5. Warranty and liability
41
+ To the maximum extent permitted by applicable law, this software is provided
42
+ "AS IS", without warranties of any kind, including merchantability, fitness
43
+ for a particular purpose and noninfringement. The copyright holder and operator
44
+ are not liable for indirect, incidental, special or consequential damages
45
+ arising from use of the software. Nothing in this license excludes or limits
46
+ rights, remedies or liabilities that cannot lawfully be excluded or limited.
47
+
48
+ For additional permissions, contact admin@socialcli.app.
@@ -1,22 +1,19 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: socialcli
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: SocialCli: publish and manage creator-owned social content from the terminal.
5
5
  Project-URL: Homepage, https://socialcli.app
6
- Project-URL: Repository, https://github.com/engels-florentino/SocialCli
7
- Project-URL: Issues, https://github.com/engels-florentino/SocialCli/issues
8
- License-Expression: MIT
6
+ Project-URL: Documentation, https://socialcli.app/ai-agents.html
7
+ Project-URL: Terms, https://socialcli.app/terms.html
8
+ License-Expression: LicenseRef-SocialCli-Proprietary
9
9
  License-File: LICENSE
10
+ License-File: LICENSE-MIT-LEGACY
10
11
  Requires-Python: >=3.11
11
12
  Requires-Dist: httpx>=0.28.1
12
13
  Requires-Dist: keyring>=25.0
13
14
  Requires-Dist: pydantic>=2.13.5
14
15
  Requires-Dist: pyyaml>=6.0.3
15
16
  Requires-Dist: typer>=0.27.2
16
- Provides-Extra: connection-server
17
- Requires-Dist: cryptography>=43; extra == 'connection-server'
18
- Requires-Dist: fastapi>=0.115; extra == 'connection-server'
19
- Requires-Dist: uvicorn>=0.30; extra == 'connection-server'
20
17
  Provides-Extra: headless-credentials
21
18
  Requires-Dist: cryptography>=43; extra == 'headless-credentials'
22
19
  Description-Content-Type: text/markdown
@@ -25,7 +22,7 @@ Description-Content-Type: text/markdown
25
22
 
26
23
  # SocialCli
27
24
 
28
- **Current source version: 0.3.0.** SocialCli SaaS is the current SocialCli
25
+ **Current stable version: 0.3.1 (published on PyPI). Source preparation: 0.3.2.** SocialCli SaaS is the current SocialCli
29
26
  product. The repository root on `main` is its single development workspace;
30
27
  the CLI, hosted connection service and account/billing components live together
31
28
  here. Earlier versions remain in Git history for reference and migration.
@@ -61,9 +58,9 @@ Stripe uses test mode. Planned access costs
61
58
  USD 10/month after 14 free days from the first successful connection. No real
62
59
  subscriptions are collected in this pilot.
63
60
 
64
- The current client release target is **0.3.0** (published first to TestPyPI and
65
- then to PyPI through the reviewed release workflow). The compatible hosted
66
- runtime is `socialcli-saas-candidate:45fda63`. The client's wheel and
61
+ The current stable client is **0.3.1**, published on TestPyPI and PyPI after
62
+ reviewed CI, matching artifact hashes and clean-install verification.
63
+ The hosted service is managed and verified separately from the CLI release. The client's wheel and
67
64
  source archive are verified against the
68
65
  reviewed build hashes before publication. Provider commercial approvals and live
69
66
  billing cutover remain separate from package publication. See the
@@ -141,7 +138,9 @@ Metrics and management permissions are separate from publishing permissions. A v
141
138
 
142
139
  Read [CONTRIBUTING.md](CONTRIBUTING.md). For questions or bugs, open an [issue](https://github.com/engels-florentino/SocialCli/issues) without tokens, keys, `.env` files or private logs. Report vulnerabilities through the private channel described in [SECURITY.md](SECURITY.md).
143
140
 
144
- [MIT license](LICENSE). SocialCli is not affiliated with the platforms it integrates.
141
+ [Proprietary license](LICENSE) for 0.3.2 and later. Earlier releases retain their
142
+ [MIT license](LICENSE-MIT-LEGACY). The hosted server is private and is not included
143
+ in public client distributions. SocialCli is not affiliated with the platforms it integrates.
145
144
 
146
145
  ## Account, media and scheduling
147
146
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # SocialCli
4
4
 
5
- **Current source version: 0.3.0.** SocialCli SaaS is the current SocialCli
5
+ **Current stable version: 0.3.1 (published on PyPI). Source preparation: 0.3.2.** SocialCli SaaS is the current SocialCli
6
6
  product. The repository root on `main` is its single development workspace;
7
7
  the CLI, hosted connection service and account/billing components live together
8
8
  here. Earlier versions remain in Git history for reference and migration.
@@ -38,9 +38,9 @@ Stripe uses test mode. Planned access costs
38
38
  USD 10/month after 14 free days from the first successful connection. No real
39
39
  subscriptions are collected in this pilot.
40
40
 
41
- The current client release target is **0.3.0** (published first to TestPyPI and
42
- then to PyPI through the reviewed release workflow). The compatible hosted
43
- runtime is `socialcli-saas-candidate:45fda63`. The client's wheel and
41
+ The current stable client is **0.3.1**, published on TestPyPI and PyPI after
42
+ reviewed CI, matching artifact hashes and clean-install verification.
43
+ The hosted service is managed and verified separately from the CLI release. The client's wheel and
44
44
  source archive are verified against the
45
45
  reviewed build hashes before publication. Provider commercial approvals and live
46
46
  billing cutover remain separate from package publication. See the
@@ -118,7 +118,9 @@ Metrics and management permissions are separate from publishing permissions. A v
118
118
 
119
119
  Read [CONTRIBUTING.md](CONTRIBUTING.md). For questions or bugs, open an [issue](https://github.com/engels-florentino/SocialCli/issues) without tokens, keys, `.env` files or private logs. Report vulnerabilities through the private channel described in [SECURITY.md](SECURITY.md).
120
120
 
121
- [MIT license](LICENSE). SocialCli is not affiliated with the platforms it integrates.
121
+ [Proprietary license](LICENSE) for 0.3.2 and later. Earlier releases retain their
122
+ [MIT license](LICENSE-MIT-LEGACY). The hosted server is private and is not included
123
+ in public client distributions. SocialCli is not affiliated with the platforms it integrates.
122
124
 
123
125
  ## Account, media and scheduling
124
126
 
@@ -0,0 +1,183 @@
1
+ [project]
2
+ name = "socialcli"
3
+ version = "0.3.2"
4
+ description = "SocialCli: publish and manage creator-owned social content from the terminal."
5
+ readme = "README.md"
6
+ license = "LicenseRef-SocialCli-Proprietary"
7
+ license-files = ["LICENSE", "LICENSE-MIT-LEGACY"]
8
+ requires-python = ">=3.11"
9
+ dependencies = [
10
+ "httpx>=0.28.1",
11
+ "keyring>=25.0",
12
+ "pydantic>=2.13.5",
13
+ "pyyaml>=6.0.3",
14
+ "typer>=0.27.2",
15
+ ]
16
+
17
+ [project.scripts]
18
+ socialcli = "socialctl.cli:app"
19
+ socialctl = "socialctl.cli:app"
20
+
21
+ [project.urls]
22
+ Homepage = "https://socialcli.app"
23
+ Documentation = "https://socialcli.app/ai-agents.html"
24
+ Terms = "https://socialcli.app/terms.html"
25
+
26
+ [project.optional-dependencies]
27
+ headless-credentials = ["cryptography>=43"]
28
+
29
+ [dependency-groups]
30
+ dev = [
31
+ "cryptography>=43",
32
+ "fastapi>=0.115",
33
+ "pytest>=9.1.1",
34
+ "respx>=0.23.1",
35
+ ]
36
+
37
+ [build-system]
38
+ requires = ["hatchling>=1.27"]
39
+ build-backend = "hatchling.build"
40
+
41
+
42
+ # Public client boundary. New modules require explicit review before distribution.
43
+ [tool.hatch.build]
44
+ only-include = [
45
+ "socialctl/__init__.py",
46
+ "socialctl/__main__.py",
47
+ "socialctl/agent_errors.py",
48
+ "socialctl/agent_guide.py",
49
+ "socialctl/approval_cli.py",
50
+ "socialctl/auth.py",
51
+ "socialctl/authflow.py",
52
+ "socialctl/brands.py",
53
+ "socialctl/capabilities.py",
54
+ "socialctl/cli.py",
55
+ "socialctl/delivery_options.py",
56
+ "socialctl/engagement.py",
57
+ "socialctl/engagement_cli.py",
58
+ "socialctl/executor.py",
59
+ "socialctl/formatter.py",
60
+ "socialctl/hosted_media.py",
61
+ "socialctl/identity.py",
62
+ "socialctl/inbox.py",
63
+ "socialctl/inbox_cli.py",
64
+ "socialctl/inventory.py",
65
+ "socialctl/inventory_cli.py",
66
+ "socialctl/inventory_sources.py",
67
+ "socialctl/media.py",
68
+ "socialctl/media_cli.py",
69
+ "socialctl/media_ingress.py",
70
+ "socialctl/media_preflight.py",
71
+ "socialctl/media_registry.py",
72
+ "socialctl/media_requirements.py",
73
+ "socialctl/migration_cli.py",
74
+ "socialctl/migration_files.py",
75
+ "socialctl/models.py",
76
+ "socialctl/operation_output.py",
77
+ "socialctl/postfile.py",
78
+ "socialctl/preflight.py",
79
+ "socialctl/publication_policy.py",
80
+ "socialctl/publication_status.py",
81
+ "socialctl/publication_steps.py",
82
+ "socialctl/publish_output.py",
83
+ "socialctl/publisher.py",
84
+ "socialctl/queue_migration.py",
85
+ "socialctl/read_budget.py",
86
+ "socialctl/read_reports.py",
87
+ "socialctl/rutas.py",
88
+ "socialctl/schedule_remote.py",
89
+ "socialctl/schedule_sqlite.py",
90
+ "socialctl/scheduler.py",
91
+ "socialctl/scheduler_launchd.py",
92
+ "socialctl/scheduler_systemd.py",
93
+ "socialctl/source_links.py",
94
+ "socialctl/upload_consent.py",
95
+ "socialctl/workspace.py",
96
+ "socialctl/youtube_data.py",
97
+ "socialctl/youtube_data_service.py",
98
+ "socialctl/adapters",
99
+ "socialctl/connections",
100
+ "socialctl/management",
101
+ "socialctl/metricas",
102
+ "socialctl/native_schedule",
103
+ "socialctl/plantillas",
104
+ "socialctl/capabilities.yml",
105
+ "socialctl/ui/__init__.py",
106
+ "socialctl/ui/assets/agents.md",
107
+ "socialctl/ui/assets/agent-manual.md"
108
+ ]
109
+ exclude = ["**/.env", "**/.env.*", "**/*.env", "**/.secrets/**", "**/__pycache__/**", "**/*.pyc", "**/*.key", "**/*.pem", "**/*.sqlite3*"]
110
+
111
+ [tool.hatch.build.targets.wheel]
112
+ dev-mode-dirs = ["."]
113
+
114
+ [tool.hatch.build.targets.sdist]
115
+ only-include = [
116
+ "socialctl/__init__.py",
117
+ "socialctl/__main__.py",
118
+ "socialctl/agent_errors.py",
119
+ "socialctl/agent_guide.py",
120
+ "socialctl/approval_cli.py",
121
+ "socialctl/auth.py",
122
+ "socialctl/authflow.py",
123
+ "socialctl/brands.py",
124
+ "socialctl/capabilities.py",
125
+ "socialctl/cli.py",
126
+ "socialctl/delivery_options.py",
127
+ "socialctl/engagement.py",
128
+ "socialctl/engagement_cli.py",
129
+ "socialctl/executor.py",
130
+ "socialctl/formatter.py",
131
+ "socialctl/hosted_media.py",
132
+ "socialctl/identity.py",
133
+ "socialctl/inbox.py",
134
+ "socialctl/inbox_cli.py",
135
+ "socialctl/inventory.py",
136
+ "socialctl/inventory_cli.py",
137
+ "socialctl/inventory_sources.py",
138
+ "socialctl/media.py",
139
+ "socialctl/media_cli.py",
140
+ "socialctl/media_ingress.py",
141
+ "socialctl/media_preflight.py",
142
+ "socialctl/media_registry.py",
143
+ "socialctl/media_requirements.py",
144
+ "socialctl/migration_cli.py",
145
+ "socialctl/migration_files.py",
146
+ "socialctl/models.py",
147
+ "socialctl/operation_output.py",
148
+ "socialctl/postfile.py",
149
+ "socialctl/preflight.py",
150
+ "socialctl/publication_policy.py",
151
+ "socialctl/publication_status.py",
152
+ "socialctl/publication_steps.py",
153
+ "socialctl/publish_output.py",
154
+ "socialctl/publisher.py",
155
+ "socialctl/queue_migration.py",
156
+ "socialctl/read_budget.py",
157
+ "socialctl/read_reports.py",
158
+ "socialctl/rutas.py",
159
+ "socialctl/schedule_remote.py",
160
+ "socialctl/schedule_sqlite.py",
161
+ "socialctl/scheduler.py",
162
+ "socialctl/scheduler_launchd.py",
163
+ "socialctl/scheduler_systemd.py",
164
+ "socialctl/source_links.py",
165
+ "socialctl/upload_consent.py",
166
+ "socialctl/workspace.py",
167
+ "socialctl/youtube_data.py",
168
+ "socialctl/youtube_data_service.py",
169
+ "socialctl/adapters",
170
+ "socialctl/connections",
171
+ "socialctl/management",
172
+ "socialctl/metricas",
173
+ "socialctl/native_schedule",
174
+ "socialctl/plantillas",
175
+ "socialctl/capabilities.yml",
176
+ "socialctl/ui/__init__.py",
177
+ "socialctl/ui/assets/agents.md",
178
+ "socialctl/ui/assets/agent-manual.md",
179
+ "pyproject.toml",
180
+ "README.md",
181
+ "LICENSE",
182
+ "LICENSE-MIT-LEGACY"
183
+ ]
@@ -32,6 +32,10 @@ _ACTIONS = {
32
32
  # Only fixed internal codes acquire action semantics. Provider text is diagnostic,
33
33
  # never a command, an expiry signal or evidence that a write was not accepted.
34
34
  _CATALOG = {
35
+ 'reply_history_purged': ('user_action', 'Prior reply evidence was removed by retention. Review the preserved journal and platform before any new draft. Do not delete replay-blocking markers or repeat an uncertain write.'),
36
+ 'dry_run_required': ('correct_input', 'inbox-draft requires --dry-run to prepare a preview. No provider content write was started.'),
37
+ 'reply_input_invalid': ('correct_input', 'Use a version 1 reply file with a nonempty replies list (1–100 items). Each reply requires platform, account_id, comment_id and text. media_id is read from the inbox, not supplied in this file.'),
38
+ 'target_validation_failed': ('inspect', 'Local target verification failed. Inspect the diagnostic reason; this does not establish a provider rejection or invalid credentials.'),
35
39
  'approval_mismatch': ('user_action', 'The supplied approval does not match this exact preview. Obtain the owner approval before applying.'),
36
40
  'approval_required': ('user_action', 'Show the complete preview and obtain explicit approval of its exact fingerprint.'),
37
41
  'operation_cancelled': ('inspect', 'Approval was cancelled. No write was started by this command.'),
@@ -108,6 +112,7 @@ def error_document(exc: BaseException, *, read_only: bool) -> dict:
108
112
  from socialctl.management.meta_schema import MetaError, MetaUncertain
109
113
  from socialctl.metricas.base import SinPermiso
110
114
  from socialctl.youtube_data import YouTubeDataBusy, YouTubeDataCleanupError
115
+ from socialctl.identity import ReadError
111
116
 
112
117
  # A read flow may refresh a token via POST. A lost response to that operation
113
118
  # cannot be classified as a harmless GET retry merely from the CLI command.
@@ -124,7 +129,7 @@ def error_document(exc: BaseException, *, read_only: bool) -> dict:
124
129
  429:'rate_limited',503:'provider_unavailable'}.get(exc.status,'service_rejected')
125
130
  elif isinstance(exc, (ResourceUncertain, YouTubeUpdateUncertain, CommentUncertain, MetaUncertain)):
126
131
  code = 'operation_uncertain'
127
- elif isinstance(exc, (AuthError, YouTubeManagementError, ResourceError, CommentError, MetaError)) and getattr(exc, '_socialcli_error_code', None) is not None:
132
+ elif isinstance(exc, (AuthError, YouTubeManagementError, ChangeError, ResourceError, CommentError, MetaError, ReadError)) and getattr(exc, '_socialcli_error_code', None) is not None:
128
133
  code = exc._socialcli_error_code
129
134
  elif isinstance(exc, ReadDeadlineExceeded): code = 'read_deadline'
130
135
  elif isinstance(exc, ReadResponseTooLarge): code = 'response_too_large'
@@ -144,21 +149,66 @@ def error_document(exc: BaseException, *, read_only: bool) -> dict:
144
149
  429:'rate_limited'}.get(status,'provider_unavailable' if status>=500 else 'request_rejected')
145
150
  if type(status) is int else 'operation_rejected')
146
151
  elif isinstance(exc, httpx.RequestError): code = 'provider_response_invalid'
152
+ elif isinstance(exc, ReadError):
153
+ code = {'credentials_missing': 'authorization_unavailable', 'credentials_expired': 'authorization_unavailable',
154
+ 'permission_denied': 'permissions_required', 'rate_limited': 'rate_limited',
155
+ 'timeout': 'transport_failure', 'transport_error': 'transport_failure',
156
+ 'invalid_response': 'provider_response_invalid', 'provider_error': 'provider_unavailable',
157
+ 'configuration_missing': 'account_not_configured'}.get(exc.code, 'target_validation_failed')
158
+ elif isinstance(exc, ResourceError): code = 'target_validation_failed'
147
159
  elif isinstance(exc, ChangeError): code = 'operation_rejected'
148
160
  elif isinstance(exc, YouTubeDataBusy): code = 'local_data_busy'
149
161
  elif isinstance(exc, (OSError, YouTubeDataCleanupError)): code = 'storage_failure'
150
162
  elif isinstance(exc, ValueError): code = 'invalid_local_state'
151
163
  else: code = 'operation_failed'
152
- return error_for_code(code,read_only=read_only)
164
+ result = error_for_code(code,read_only=read_only)
165
+ # Local validation is not evidence of a rejection by the hosted service.
166
+ if code == 'operation_rejected' and not isinstance(exc, ServiceRejected):
167
+ result['message'] = _CATALOG[code][1]
168
+ diagnostic = safe_diagnostic(getattr(exc, '_socialcli_diagnostic', None))
169
+ if isinstance(exc, ChangeError) and not diagnostic:
170
+ diagnostic = {'source': 'local'}
171
+ if isinstance(exc, ServiceRejected):
172
+ diagnostic.update(source='socialcli', http_status=exc.status)
173
+ elif isinstance(exc, httpx.HTTPStatusError):
174
+ diagnostic.update(http_status=exc.response.status_code, request_method=exc.request.method)
175
+ if diagnostic:
176
+ result['diagnostic'] = safe_diagnostic(diagnostic)
177
+ return result
178
+
179
+
180
+ def safe_diagnostic(value):
181
+ """Allow only fixed machine labels, never URLs, bodies, headers or prose."""
182
+ if not isinstance(value, dict):
183
+ return {}
184
+ allowed = {
185
+ 'source': {'local', 'socialcli', 'youtube'},
186
+ 'stage': {'input_validation', 'workspace_read', 'file_read', 'credential_read', 'identity_read', 'provider_read', 'provider_write', 'target_read', 'reply_coverage', 'proposal_preparation', 'baseline_check', 'readback'},
187
+ 'request_method': {'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE'},
188
+ 'operation': {'channels', 'videos', 'comments', 'commentThreads', 'playlistItems'},
189
+ 'write_state': {'not_started', 'unknown', 'accepted'},
190
+ 'content_write_state': {'not_started'},
191
+ 'reason': {'thread_unverifiable', 'thread_identity_mismatch', 'thread_total_unverifiable', 'comment_binding_mismatch', 'parent_mismatch', 'replies_not_allowed', 'incomplete_reply_list', 'readback_mismatch'},
192
+ 'provider_reason': {'commentsDisabled', 'quotaExceeded', 'dailyLimitExceeded', 'rateLimitExceeded', 'userRateLimitExceeded', 'insufficientPermissions', 'forbidden', 'authError', 'invalidValue', 'videoNotFound', 'commentNotFound', 'commentThreadNotFound', 'processingFailure', 'operationNotSupported'},
193
+ }
194
+ clean = {key: val for key, val in value.items()
195
+ if key in allowed and isinstance(val, str) and val in allowed[key]}
196
+ status = value.get('http_status')
197
+ if type(status) is int and 100 <= status <= 599:
198
+ clean['http_status'] = status
199
+ return clean
153
200
 
154
201
 
155
202
  def with_error_code(wrapper: Exception, cause: BaseException, *, read_only: bool,
156
203
  fallback: str | None = None) -> Exception:
157
204
  """Keep only a fixed code across a sanitized wrapper, never raw exception data."""
158
- code = error_document(cause, read_only=read_only)['code']
205
+ detail = error_document(cause, read_only=read_only)
206
+ code = detail['code']
159
207
  if code == 'operation_failed' and fallback is not None:
160
208
  code = error_for_code(fallback, read_only=read_only)['code']
161
209
  wrapper._socialcli_error_code = code
210
+ if detail.get('diagnostic'):
211
+ wrapper._socialcli_diagnostic = detail['diagnostic']
162
212
  return wrapper
163
213
 
164
214
 
@@ -166,7 +216,28 @@ def with_http_error_code(wrapper: Exception, response, *, read_only: bool) -> Ex
166
216
  import httpx
167
217
  cause = httpx.HTTPStatusError('Provider request rejected', request=response.request,
168
218
  response=response)
169
- return with_error_code(wrapper, cause, read_only=read_only)
219
+ wrapper = with_error_code(wrapper, cause, read_only=read_only)
220
+ if response.request.url.host == 'www.googleapis.com':
221
+ diagnostic = {'source': 'youtube', 'http_status': response.status_code,
222
+ 'request_method': response.request.method,
223
+ 'stage': 'provider_read' if read_only else 'provider_write',
224
+ 'operation': response.request.url.path.rsplit('/', 1)[-1],
225
+ 'write_state': 'not_started' if read_only else 'unknown'}
226
+ try:
227
+ reasons = response.json().get('error', {}).get('errors', [])
228
+ for row in reasons[:16]:
229
+ reason = safe_diagnostic({'provider_reason': row.get('reason')}) if isinstance(row, dict) else {}
230
+ if reason:
231
+ diagnostic.update(reason)
232
+ if reason['provider_reason'] in {'quotaExceeded', 'dailyLimitExceeded', 'rateLimitExceeded', 'userRateLimitExceeded'}:
233
+ wrapper._socialcli_error_code = 'rate_limited' if read_only else 'operation_uncertain'
234
+ elif reason['provider_reason'] == 'commentsDisabled' and read_only:
235
+ wrapper._socialcli_error_code = 'comments_disabled'
236
+ break
237
+ except (ValueError, TypeError, AttributeError):
238
+ pass
239
+ wrapper._socialcli_diagnostic = safe_diagnostic(diagnostic)
240
+ return wrapper
170
241
 
171
242
 
172
243
  def emit_error(exc: Exception, *, read_only: bool) -> None:
@@ -3,11 +3,11 @@ from importlib.resources import files
3
3
  import re
4
4
 
5
5
  TOPICS={
6
- 'setup':('Install the reviewed candidate','Authorize the installation, then the social account','Persist and recover','Publication gate','Explicit approval and preflight'),
6
+ 'setup':('What agents can do','Install the reviewed release','Authorize the installation, then the social account','Persist and recover','Publication gate','Explicit approval and preflight'),
7
7
  'publish':('Publication gate','Temporary Instagram media','Canonical publishing workflow','Check supplied media locally','Explicit approval and preflight'),
8
8
  'schedule':('Publication gate','Temporary Instagram media','Scheduling and temporary media','Native scheduling input examples (offline)','Explicit approval and preflight'),
9
- 'inbox':('Publication gate','Read metrics and prepare engagement','Read diagnostics','Comment API corrections','Explicit approval and preflight','Resumable batches and reply context'),
10
- 'errors':('Persist and recover','Recovery and error actions','Read diagnostics','Comment API corrections','Explicit approval and preflight','Resumable batches and reply context'),
9
+ 'inbox':('Publication gate','Read metrics and prepare engagement','Read diagnostics','Comment API evidence and limits','Explicit approval and preflight','Resumable batches and reply context','Purged reply history'),
10
+ 'errors':('Persist and recover','Recovery and error actions','Read diagnostics','Comment API evidence and limits','Explicit approval and preflight','Resumable batches and reply context','Purged reply history'),
11
11
  'permissions':('Installation connection access',),
12
12
  }
13
13
 
@@ -20,4 +20,4 @@ def guide(topic):
20
20
  sections=re.split(r'(?=^## )',full,flags=re.MULTILINE)
21
21
  chosen=[section for section in sections if any(section.startswith('## '+heading) for heading in TOPICS[topic])]
22
22
  return ('# SocialCli agent guide: '+topic+'\n\n'+''.join(chosen)+
23
- '\nNext: socialcli agent-guide publish; socialcli agent-guide schedule; socialcli agent-guide inbox; socialcli agent-guide errors.\n')
23
+ '\nNext: socialcli agent-guide publish; socialcli agent-guide schedule; socialcli agent-guide inbox; socialcli agent-guide errors; socialcli agent-guide permissions; socialcli agent-guide all.\n')