netizen-cli 0.15.0__tar.gz → 0.15.1__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 (366) hide show
  1. {netizen_cli-0.15.0/netizen_cli.egg-info → netizen_cli-0.15.1}/PKG-INFO +2 -1
  2. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/__init__.py +1 -1
  3. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/file_previews.py +35 -9
  4. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/admin.css +81 -2
  5. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/admin.js +251 -46
  6. netizen_cli-0.15.0/netizen_cli/admin/static/project-files.css → netizen_cli-0.15.1/netizen_cli/admin/static/content-preview.css +65 -14
  7. netizen_cli-0.15.1/netizen_cli/admin/static/content-preview.js +10 -0
  8. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/file-browser.js +163 -30
  9. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/index.html +77 -17
  10. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/web.py +41 -22
  11. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/management/service.py +3 -3
  12. {netizen_cli-0.15.0 → netizen_cli-0.15.1/netizen_cli.egg-info}/PKG-INFO +2 -1
  13. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli.egg-info/SOURCES.txt +2 -1
  14. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli.egg-info/requires.txt +1 -0
  15. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/pyproject.toml +2 -1
  16. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/admin.md +27 -10
  17. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cli_packaging.py +6 -1
  18. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/MANIFEST.in +0 -0
  19. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/README.md +0 -0
  20. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/_build.py +0 -0
  21. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/config.example.yaml +0 -0
  22. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/__main__.py +0 -0
  23. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/account_rate_limits.py +0 -0
  24. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/__init__.py +0 -0
  25. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/auth.py +0 -0
  26. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/credentials.py +0 -0
  27. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/errors.py +0 -0
  28. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/feishu.py +0 -0
  29. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/login.py +0 -0
  30. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/port_config.py +0 -0
  31. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/presentation.py +0 -0
  32. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/queries.py +0 -0
  33. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/attachment-files.js +0 -0
  34. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/chat-picker.css +0 -0
  35. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/chat-picker.js +0 -0
  36. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/identity.js +0 -0
  37. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/login.html +0 -0
  38. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/login.js +0 -0
  39. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/netizen.svg +0 -0
  40. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/progress-card.js +0 -0
  41. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/project-files.js +0 -0
  42. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/question-notifications.js +0 -0
  43. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/session-access.js +0 -0
  44. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/vendor/ace/LICENSE +0 -0
  45. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/vendor/ace/README.md +0 -0
  46. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/vendor/ace/ace.js +0 -0
  47. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/vendor/ace/mode-javascript.js +0 -0
  48. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/vendor/ace/mode-json.js +0 -0
  49. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/vendor/ace/mode-markdown.js +0 -0
  50. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/vendor/ace/mode-python.js +0 -0
  51. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/static/worktrees.js +0 -0
  52. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/transport.py +0 -0
  53. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/admin/users.py +0 -0
  54. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/attachments.py +0 -0
  55. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/bindings.py +0 -0
  56. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/builtin_skills.py +0 -0
  57. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/__init__.py +0 -0
  58. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/callbacks.py +0 -0
  59. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/chat_target.py +0 -0
  60. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/controls.py +0 -0
  61. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/defaults.py +0 -0
  62. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/fork.py +0 -0
  63. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/pagination.py +0 -0
  64. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/questions.py +0 -0
  65. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/reply.py +0 -0
  66. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/scheduled.py +0 -0
  67. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/session_ids.py +0 -0
  68. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/status.py +0 -0
  69. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/usage.py +0 -0
  70. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cards/workspace.py +0 -0
  71. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/__init__.py +0 -0
  72. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/completion_mentions.py +0 -0
  73. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/input_preparation.py +0 -0
  74. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/messages.py +0 -0
  75. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/ports.py +0 -0
  76. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/question_inputs.py +0 -0
  77. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/reactions.py +0 -0
  78. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/reply_presenter.py +0 -0
  79. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/reply_suppression.py +0 -0
  80. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/session_pages.py +0 -0
  81. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel/topics.py +0 -0
  82. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/channel_app.py +0 -0
  83. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/chat_avatars.py +0 -0
  84. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/chat_targets.py +0 -0
  85. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cli.py +0 -0
  86. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cli_data.py +0 -0
  87. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cli_packages.py +0 -0
  88. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cli_services.py +0 -0
  89. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cli_setup.py +0 -0
  90. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cli_update.py +0 -0
  91. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cli_update_restore.py +0 -0
  92. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/cli_update_worker.py +0 -0
  93. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/codex_runtime.py +0 -0
  94. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/completion_mention.py +0 -0
  95. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/database_migrations.py +0 -0
  96. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/defaults/__init__.py +0 -0
  97. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/defaults/models.py +0 -0
  98. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/defaults/service.py +0 -0
  99. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/defaults/store.py +0 -0
  100. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/deployment/__init__.py +0 -0
  101. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/deployment/restart_worker.py +0 -0
  102. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/deployment/update_executor.py +0 -0
  103. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/deployment/update_protocol.py +0 -0
  104. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/domain.py +0 -0
  105. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/error_messages.py +0 -0
  106. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/experience.py +0 -0
  107. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/feishu_app_onboarding.py +0 -0
  108. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/feishu_app_permissions.py +0 -0
  109. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/feishu_links.py +0 -0
  110. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/file_inputs.py +0 -0
  111. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/git_status.py +0 -0
  112. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/image_inputs.py +0 -0
  113. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/instance.py +0 -0
  114. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/lark_app.py +0 -0
  115. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/main.py +0 -0
  116. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/management/__init__.py +0 -0
  117. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/management/attachment_files.py +0 -0
  118. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/management/blocking_io.py +0 -0
  119. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/management/chat_directory.py +0 -0
  120. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/management/chat_labels.py +0 -0
  121. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/management/coordination.py +0 -0
  122. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/management/project_files.py +0 -0
  123. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/management/updates.py +0 -0
  124. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/markdown_images.py +0 -0
  125. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/mcp_transport.py +0 -0
  126. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/message_content.py +0 -0
  127. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/message_history.py +0 -0
  128. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/message_preparation.py +0 -0
  129. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/message_projection.py +0 -0
  130. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/migrations/__init__.py +0 -0
  131. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/migrations/schema.py +0 -0
  132. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/migrations/v14.py +0 -0
  133. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/migrations/v15.py +0 -0
  134. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/migrations/v16.py +0 -0
  135. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/migrations/v17.py +0 -0
  136. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/migrations/v18.py +0 -0
  137. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/migrations/v19.py +0 -0
  138. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/migrations/v20.py +0 -0
  139. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/model_settings.py +0 -0
  140. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/package_resources.py +0 -0
  141. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/pagination.py +0 -0
  142. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/partial_answers.py +0 -0
  143. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/progress_card_config.py +0 -0
  144. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/progress_card_settings.py +0 -0
  145. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/project_files.py +0 -0
  146. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/projects.py +0 -0
  147. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/prompt_projection.py +0 -0
  148. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/question_notifications.py +0 -0
  149. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/quoted_context.py +0 -0
  150. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/result_images.py +0 -0
  151. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/runtime/__init__.py +0 -0
  152. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/runtime/contracts.py +0 -0
  153. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/runtime/name_writes.py +0 -0
  154. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/runtime/thread_naming.py +0 -0
  155. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/schedules/__init__.py +0 -0
  156. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/schedules/mcp.py +0 -0
  157. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/schedules/models.py +0 -0
  158. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/schedules/scheduler.py +0 -0
  159. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/schedules/service.py +0 -0
  160. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/schedules/store.py +0 -0
  161. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sdk_gap_adapter.py +0 -0
  162. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/service_launcher.py +0 -0
  163. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/session_inventory.py +0 -0
  164. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/session_settings.py +0 -0
  165. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sessions/__init__.py +0 -0
  166. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sessions/delegation.py +0 -0
  167. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sessions/errors.py +0 -0
  168. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sessions/mcp.py +0 -0
  169. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sessions/policy.py +0 -0
  170. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sessions/presentation.py +0 -0
  171. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sessions/schema.py +0 -0
  172. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sessions/service.py +0 -0
  173. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/sessions/sources.py +0 -0
  174. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/settings.py +0 -0
  175. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/skill_references.py +0 -0
  176. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/task_text.py +0 -0
  177. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/terminal_cleanup.py +0 -0
  178. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/thread_history.py +0 -0
  179. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/turn_activity.py +0 -0
  180. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/turn_files.py +0 -0
  181. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/turn_patch_children.py +0 -0
  182. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/turn_plan_observer.py +0 -0
  183. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/user_questions.py +0 -0
  184. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/worktrees/errors.py +0 -0
  185. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/worktrees/git.py +0 -0
  186. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/worktrees/models.py +0 -0
  187. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/worktrees/policy.py +0 -0
  188. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/worktrees/service.py +0 -0
  189. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/worktrees/settings.py +0 -0
  190. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli/worktrees/store.py +0 -0
  191. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli.egg-info/dependency_links.txt +0 -0
  192. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli.egg-info/entry_points.txt +0 -0
  193. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/netizen_cli.egg-info/top_level.txt +0 -0
  194. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/setup.cfg +0 -0
  195. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-lark/SKILL.md +0 -0
  196. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-runtime-guidance/SKILL.md +0 -0
  197. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/SKILL.md +0 -0
  198. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/commands.md +0 -0
  199. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/concepts.md +0 -0
  200. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/faq.md +0 -0
  201. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/feedback-and-files.md +0 -0
  202. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/fork-side-goal.md +0 -0
  203. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/messages.md +0 -0
  204. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/native-capabilities.md +0 -0
  205. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/scheduled-tasks.md +0 -0
  206. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/session-collaboration.md +0 -0
  207. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/sessions.md +0 -0
  208. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/status-and-control.md +0 -0
  209. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/skills/netizen-user-guide/references/user-guide.md +0 -0
  210. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_account_rate_limits.py +0 -0
  211. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_admin_update_executor_probe.py +0 -0
  212. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_attachments.py +0 -0
  213. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_binding_scheduled_channel.py +0 -0
  214. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_bindings.py +0 -0
  215. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_card_error_feedback.py +0 -0
  216. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cards.py +0 -0
  217. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_channel_app.py +0 -0
  218. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_channel_fixtures.py +0 -0
  219. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_channel_input_preparation.py +0 -0
  220. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_chat_avatars.py +0 -0
  221. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_chat_target_cards.py +0 -0
  222. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_check_sdk.py +0 -0
  223. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cli.py +0 -0
  224. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cli_data.py +0 -0
  225. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cli_distribution.py +0 -0
  226. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cli_integration.py +0 -0
  227. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cli_packages.py +0 -0
  228. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cli_services.py +0 -0
  229. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cli_setup.py +0 -0
  230. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cli_update.py +0 -0
  231. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_codex_runtime.py +0 -0
  232. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_codex_sdk_capabilities.py +0 -0
  233. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_codex_sdk_upgrade_0161.py +0 -0
  234. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_codex_sdk_upgrade_0163.py +0 -0
  235. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_completion_mention_cards.py +0 -0
  236. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_completion_mentions.py +0 -0
  237. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_completion_topic_delivery.py +0 -0
  238. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_configuration_publication.py +0 -0
  239. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_cron_chat_targets.py +0 -0
  240. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_database_migrations.py +0 -0
  241. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_defaults_cards.py +0 -0
  242. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_defaults_channel.py +0 -0
  243. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_defaults_runtime.py +0 -0
  244. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_defaults_worktree_channel.py +0 -0
  245. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_deployment.py +0 -0
  246. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_documentation_links.py +0 -0
  247. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_domain_experience.py +0 -0
  248. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_error_messages.py +0 -0
  249. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_feishu_app_onboarding.py +0 -0
  250. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_feishu_app_permissions.py +0 -0
  251. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_file_input_channel.py +0 -0
  252. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_file_inputs.py +0 -0
  253. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_file_pagination.py +0 -0
  254. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_fork_cards.py +0 -0
  255. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_git_status.py +0 -0
  256. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_goal_reply_separation.py +0 -0
  257. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_image_inputs.py +0 -0
  258. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_lark_app.py +0 -0
  259. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_lark_sdk_contract.py +0 -0
  260. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_latest_answer.py +0 -0
  261. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_main.py +0 -0
  262. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_markdown_images.py +0 -0
  263. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_message_content.py +0 -0
  264. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_message_history.py +0 -0
  265. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_message_material_inputs.py +0 -0
  266. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_message_preparation.py +0 -0
  267. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_migration_schema_validation.py +0 -0
  268. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_model_settings.py +0 -0
  269. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_name_writes.py +0 -0
  270. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_optional_progress_card_settings_migration.py +0 -0
  271. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_pagination.py +0 -0
  272. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_partial_answer_delivery.py +0 -0
  273. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_partial_answers.py +0 -0
  274. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_persistent_fork_bindings.py +0 -0
  275. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_persistent_fork_channel.py +0 -0
  276. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_persistent_fork_runtime.py +0 -0
  277. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_child_files.py +0 -0
  278. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_feishu_completion_mention.py +0 -0
  279. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_feishu_partial_answers.py +0 -0
  280. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_feishu_turn_file_card.py +0 -0
  281. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_persistent_fork.py +0 -0
  282. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_python_sdk.py +0 -0
  283. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_scheduled_tasks.py +0 -0
  284. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_sdk_completion_race.py +0 -0
  285. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_sdk_response_recovery.py +0 -0
  286. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_skill_execution.py +0 -0
  287. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_probe_thread_naming.py +0 -0
  288. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_progress_card_config.py +0 -0
  289. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_progress_card_entrypoints.py +0 -0
  290. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_progress_card_presentation.py +0 -0
  291. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_progress_card_settings_migration.py +0 -0
  292. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_project_delete_channel.py +0 -0
  293. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_project_delete_runtime.py +0 -0
  294. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_project_deletion_storage.py +0 -0
  295. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_project_files.py +0 -0
  296. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_prompt_projection.py +0 -0
  297. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_question_cards.py +0 -0
  298. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_question_channel.py +0 -0
  299. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_question_notification_config.py +0 -0
  300. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_question_target_parity.py +0 -0
  301. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_quoted_context.py +0 -0
  302. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_release_script.py +0 -0
  303. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_rename_name_channel.py +0 -0
  304. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_reply_suppression.py +0 -0
  305. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_repository_hygiene.py +0 -0
  306. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_result_images.py +0 -0
  307. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_resume_channel.py +0 -0
  308. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_retired_deployment.py +0 -0
  309. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_runtime_resume_activation.py +0 -0
  310. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_runtime_thread_naming.py +0 -0
  311. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_auto_archive_migration.py +0 -0
  312. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_card_retry.py +0 -0
  313. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_cards.py +0 -0
  314. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_mcp.py +0 -0
  315. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_run_now.py +0 -0
  316. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_scope_matrix.py +0 -0
  317. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_service.py +0 -0
  318. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_trigger_cards.py +0 -0
  319. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_workspace_cards.py +0 -0
  320. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_workspace_migration.py +0 -0
  321. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_workspace_service.py +0 -0
  322. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedule_workspace_storage.py +0 -0
  323. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_scheduled_auto_archive.py +0 -0
  324. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_scheduled_channel.py +0 -0
  325. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_scheduled_runtime.py +0 -0
  326. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_scheduled_worktrees.py +0 -0
  327. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_scheduler.py +0 -0
  328. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_scheduler_presenter.py +0 -0
  329. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_schedules_storage.py +0 -0
  330. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_sdk_gap_adapter.py +0 -0
  331. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_service_launcher.py +0 -0
  332. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_session_card_pages.py +0 -0
  333. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_session_collaboration_app.py +0 -0
  334. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_session_defaults.py +0 -0
  335. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_session_defaults_migration.py +0 -0
  336. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_session_external_runtime.py +0 -0
  337. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_session_id_cards.py +0 -0
  338. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_session_policy.py +0 -0
  339. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_session_settings.py +0 -0
  340. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_session_tools.py +0 -0
  341. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_settings_projects.py +0 -0
  342. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_status_cards.py +0 -0
  343. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_status_commands.py +0 -0
  344. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_suppress_reply.py +0 -0
  345. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_task_text.py +0 -0
  346. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_terminal_cleanup.py +0 -0
  347. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_thread_history.py +0 -0
  348. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_thread_naming.py +0 -0
  349. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_turn_activity.py +0 -0
  350. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_turn_files.py +0 -0
  351. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_turn_patch_children.py +0 -0
  352. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_turn_patch_statistics.py +0 -0
  353. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_turn_plan_observer.py +0 -0
  354. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_update_executor.py +0 -0
  355. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_usage_card.py +0 -0
  356. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_usage_control.py +0 -0
  357. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_user_guide_skill.py +0 -0
  358. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_user_questions.py +0 -0
  359. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_worktree_channel_cwd.py +0 -0
  360. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_worktree_git.py +0 -0
  361. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_worktree_new.py +0 -0
  362. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_worktree_runtime_cwd.py +0 -0
  363. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_worktree_service.py +0 -0
  364. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_worktree_settings.py +0 -0
  365. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_worktree_storage.py +0 -0
  366. {netizen_cli-0.15.0 → netizen_cli-0.15.1}/tests/test_worktree_tools_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netizen-cli
3
- Version: 0.15.0
3
+ Version: 0.15.1
4
4
  Summary: Use native Codex threads through a Feishu Channel.
5
5
  Requires-Python: <3.15,>=3.11
6
6
  Requires-Dist: h11==0.16.0
@@ -12,6 +12,7 @@ Requires-Dist: mdformat==1.0.0
12
12
  Requires-Dist: mdformat-gfm==1.0.0
13
13
  Requires-Dist: mcp==2.2.0
14
14
  Requires-Dist: openai-codex==0.163.0
15
+ Requires-Dist: psutil==7.2.2
15
16
  Requires-Dist: pydantic==2.13.4
16
17
  Requires-Dist: PyYAML==6.0.3
17
18
  Requires-Dist: qrcode==8.2
@@ -1,3 +1,3 @@
1
1
  """Netizen: a thin Feishu Channel for native Codex Threads."""
2
2
 
3
- __version__ = "0.15.0"
3
+ __version__ = "0.15.1"
@@ -1,4 +1,4 @@
1
- """Bounded, inert Markdown previews for the authenticated Project file browser."""
1
+ """Bounded, inert Markdown previews for authenticated Admin readers."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -6,6 +6,7 @@ from collections.abc import Callable, Iterator, Sequence
6
6
  from urllib.parse import unquote, urlsplit
7
7
 
8
8
  from markdown_it import MarkdownIt
9
+ from markdown_it.rules_core import StateCore
9
10
  from markdown_it.token import Token
10
11
 
11
12
 
@@ -18,13 +19,29 @@ _MARKDOWN = MarkdownIt("commonmark", {
18
19
  "html": False,
19
20
  "linkify": False,
20
21
  "maxNesting": 20,
21
- })
22
+ }).enable("table")
22
23
 
23
24
 
24
25
  class PreviewUnavailable(ValueError):
25
26
  """The source remains viewable, but its rendered preview exceeds a budget."""
26
27
 
27
28
 
29
+ class _BoundedBlockTokens(list[Token]):
30
+ def append(self, token: Token) -> None:
31
+ # Tables pad missing cells while parsing. Stop before that expansion can
32
+ # allocate an unbounded token graph, not merely after parse() returns.
33
+ if len(self) >= MAX_MARKDOWN_TOKENS:
34
+ raise PreviewUnavailable("Markdown 内容过于复杂,请查看源码。")
35
+ super().append(token)
36
+
37
+
38
+ def _limit_block_tokens(state: StateCore) -> None:
39
+ state.tokens = _BoundedBlockTokens(state.tokens)
40
+
41
+
42
+ _MARKDOWN.core.ruler.before("block", "preview_token_budget", _limit_block_tokens)
43
+
44
+
28
45
  def _unsafe_characters(value: str) -> bool:
29
46
  return "\\" in value or any(
30
47
  ord(char) < 32 or 127 <= ord(char) <= 159 for char in value
@@ -139,8 +156,8 @@ def _check_render_budget(tokens: Sequence[Token]) -> None:
139
156
  def render_markdown(
140
157
  text: str,
141
158
  *,
142
- path: str,
143
- image_url: Callable[[str], str],
159
+ path: str | None = None,
160
+ image_url: Callable[[str], str] | None = None,
144
161
  ) -> str:
145
162
  """Render safe HTML; image_url maps a root-relative file to its Admin endpoint.
146
163
 
@@ -149,6 +166,7 @@ def render_markdown(
149
166
  carry ``data-file-browser-directory="true"``.
150
167
  Remote images and fragment-only links remain inert. No filesystem or network
151
168
  access occurs here; the file endpoint separately validates image contents.
169
+ Without a file context, local links and all images remain inert.
152
170
  """
153
171
  try:
154
172
  length = len(text.encode("utf-8"))
@@ -156,9 +174,9 @@ def render_markdown(
156
174
  raise PreviewUnavailable("文件包含无法预览的文本编码,请查看源码。") from exc
157
175
  if length > MAX_MARKDOWN_BYTES:
158
176
  raise PreviewUnavailable("Markdown 文件超过 256 KiB,请查看源码。")
159
- if not path or _local_path(path, []) != path:
177
+ if path is not None and (not path or _local_path(path, []) != path):
160
178
  raise PreviewUnavailable("Markdown 文件路径无效,请查看源码。")
161
- directory = path.split("/")[:-1]
179
+ directory = path.split("/")[:-1] if path is not None else []
162
180
  env: dict[str, object] = {}
163
181
  tokens = _MARKDOWN.parse(text, env)
164
182
  if sum(1 for _ in _tokens(tokens)) > MAX_MARKDOWN_TOKENS:
@@ -167,7 +185,13 @@ def render_markdown(
167
185
 
168
186
  images = 0
169
187
  for token in _tokens(tokens):
170
- if token.type == "link_open":
188
+ if token.type in {"th_open", "td_open"}:
189
+ # The Admin CSP forbids inline style attributes; table alignment
190
+ # uses fixed classes from the shared preview stylesheet instead.
191
+ alignment = token.attrs.pop("style", None)
192
+ if alignment in {"text-align:left", "text-align:center", "text-align:right"}:
193
+ token.attrSet("class", "markdown-align-" + alignment.split(":")[1])
194
+ elif token.type == "link_open":
171
195
  target = _target(token.attrGet("href") or "", directory)
172
196
  token.attrs.pop("href", None)
173
197
  if target is None:
@@ -177,14 +201,16 @@ def render_markdown(
177
201
  token.attrSet("href", value)
178
202
  token.attrSet("rel", "noopener noreferrer")
179
203
  token.attrSet("target", "_blank")
180
- else:
204
+ elif path is not None:
181
205
  token.attrSet("href", "#")
182
206
  token.attrSet("data-file-browser-path", value)
183
207
  if kind == "directory":
184
208
  token.attrSet("data-file-browser-directory", "true")
185
209
  elif token.type == "image":
186
210
  target = _target(token.attrGet("src") or "", directory)
187
- if target is None or target[0] != "local":
211
+ if path is None or image_url is None:
212
+ _replace_image(token, "此处不加载图片")
213
+ elif target is None or target[0] != "local":
188
214
  _replace_image(token, "仅预览当前根目录内的相对路径图片")
189
215
  elif images >= MAX_MARKDOWN_IMAGES:
190
216
  _replace_image(token, "本页最多预览 8 张图片")
@@ -249,6 +249,49 @@ body.schedule-drawer-open, body.defaults-drawer-open, body.session-settings-draw
249
249
  .editor-drawer::backdrop { background: rgb(16 33 63 / 35%); }
250
250
  .rename-dialog { width: min(520px, calc(100vw - 32px)); padding: 0; border: 0; border-radius: 12px; color: var(--ink); background: var(--paper); box-shadow: 0 12px 40px rgb(23 39 68 / 16%); }
251
251
  .rename-dialog::backdrop { background: rgb(16 33 63 / 35%); }
252
+ body.project-delete-open { overflow: hidden; }
253
+ .action.project-delete-trigger { background: white; color: var(--danger); border: 1px solid #e6b5af; }
254
+ .action.project-delete-trigger:hover:not(:disabled) { background: #fff3f1; }
255
+ .project-delete-dialog { width: min(640px, calc(100vw - 32px)); max-width: none; max-height: calc(100dvh - 32px); padding: 0; border: 1px solid var(--line); border-radius: 16px; color: var(--ink); background: var(--paper); box-shadow: 0 24px 80px rgb(16 33 63 / 24%); }
256
+ .project-delete-dialog::backdrop { background: rgb(16 33 63 / 42%); }
257
+ .project-delete-shell { display: flex; flex-direction: column; max-height: calc(100dvh - 34px); }
258
+ .project-delete-head { display: flex; align-items: flex-start; gap: 16px; padding: 24px 24px 16px; }
259
+ .project-delete-head > div { flex: 1; min-width: 0; }
260
+ .project-delete-head .drawer-close { flex: 0 0 auto; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 7px; background: transparent; color: var(--muted); font-size: 24px; line-height: 1; }
261
+ .project-delete-head .drawer-close:hover { background: var(--wash); }
262
+ .project-delete-head .eyebrow { color: var(--danger); }
263
+ .project-delete-head h3 { margin: 0; font-size: 21px; line-height: 1.5; overflow-wrap: anywhere; }
264
+ .project-delete-body { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 24px 20px; font-size: 14px; line-height: 1.65; }
265
+ .project-delete-warning { padding: 12px 14px; border-radius: 8px; color: #87251c; background: #fff3f1; }
266
+ .project-delete-body h4 { margin: 18px 0 10px; font-size: 14px; }
267
+ .project-delete-body .hint { color: var(--muted); font-size: 12px; line-height: 1.65; }
268
+ .project-delete-summary { display: grid; gap: 8px; margin: 0 0 12px; }
269
+ .project-delete-summary > div { display: flex; justify-content: space-between; gap: 16px; }
270
+ .project-delete-summary dt { color: var(--muted); }
271
+ .project-delete-summary dd { margin: 0; text-align: right; overflow-wrap: anywhere; }
272
+ .project-delete-preserved { display: grid; gap: 4px; margin-top: 16px; padding: 12px 14px; border-radius: 8px; background: var(--wash); }
273
+ .project-delete-preserved code { font-size: 12px; overflow-wrap: anywhere; }
274
+ .project-delete-worktree-option { margin-top: 18px; padding: 14px; border: 1px solid var(--line); border-radius: 10px; }
275
+ .project-delete-choice { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; font-weight: 600; }
276
+ .project-delete-choice input { flex: 0 0 auto; width: 18px; height: 18px; margin: 3px 0 0; accent-color: var(--danger); }
277
+ .project-delete-worktree-option .hint { margin: 6px 0 0 28px; }
278
+ #project-delete-paths { max-height: 160px; overflow-y: auto; margin: 12px 0 0 28px; padding-left: 18px; font-family: monospace; font-size: 12px; overflow-wrap: anywhere; }
279
+ .project-delete-outcome { margin: 16px 0 0; }
280
+ #project-delete-note { margin: 12px 0 0; min-height: 0; font-size: 13px; }
281
+ #project-delete-note:empty { display: none; }
282
+ .project-delete-footer { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 24px; border-top: 1px solid var(--line); }
283
+ .project-delete-footer button { min-height: 42px; padding: 10px 14px; }
284
+ .project-delete-footer .drawer-cancel { border: 1px solid var(--line); border-radius: 8px; color: var(--ink); background: white; }
285
+ .project-delete-dialog button:focus-visible, .project-delete-choice input:focus-visible { outline: 3px solid #8cb4ff; outline-offset: 3px; }
286
+ .project-delete-dialog [hidden] { display: none; }
287
+ @media (max-width: 480px) {
288
+ .project-delete-dialog { width: calc(100vw - 16px); max-height: calc(100dvh - 16px); border-radius: 12px; }
289
+ .project-delete-shell { max-height: calc(100dvh - 18px); }
290
+ .project-delete-head { padding: 18px 16px 12px; }
291
+ .project-delete-body { padding: 0 16px 16px; }
292
+ .project-delete-footer { padding: 12px 16px; flex-wrap: wrap; }
293
+ .project-delete-footer button { flex: 1 1 auto; }
294
+ }
252
295
  #schedule-editor { height: 100%; display: flex; flex-direction: column; border: 0; border-radius: 0; padding: 0; margin: 0; }
253
296
  .schedule-editor-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 22px 24px; border-bottom: 1px solid var(--line); }
254
297
  .schedule-editor-head h3 { margin: 0; font-size: 22px; }
@@ -454,9 +497,31 @@ body.schedule-detail-open { overflow: hidden; }
454
497
  .session-access-footer .actions { flex: 0 0 auto; gap: 8px; margin-left: auto; }
455
498
  .session-access-footer button { min-width: 96px; min-height: 40px; border: 1px solid var(--blue); padding: 9px 14px; font-size: var(--control-font-size); line-height: var(--control-line-height); font-weight: 500; }
456
499
  .session-access-footer .refresh { border-color: var(--line); background: var(--paper); color: var(--ink); }
500
+ .question-notifications-form { max-width: 800px; padding: 20px; }
501
+ #question-notifications-fields { min-width: 0; margin: 0; border: 0; padding: 0; }
502
+ .question-notifications-form .question-notifications-option { display: flex; align-items: center; justify-content: space-between; gap: 24px; cursor: pointer; }
503
+ .question-notifications-copy { display: grid; gap: 6px; min-width: 0; line-height: 1.6; }
504
+ .question-notifications-title { color: var(--ink); font-size: 15px; font-weight: 600; }
505
+ .question-notifications-switch { position: relative; display: flex; align-items: center; flex: 0 0 44px; height: 44px; }
506
+ .question-notifications-switch input { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
507
+ .question-notifications-track { position: relative; width: 44px; height: 26px; border: 1px solid var(--muted); border-radius: 999px; background: var(--muted); }
508
+ .question-notifications-track::before { content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: var(--paper); box-shadow: 0 1px 3px rgb(23 39 68 / 18%); }
509
+ .question-notifications-switch input:checked + .question-notifications-track { border-color: var(--blue); background: var(--blue); }
510
+ .question-notifications-switch input:checked + .question-notifications-track::before { transform: translateX(18px); }
511
+ .question-notifications-switch input:focus-visible + .question-notifications-track { outline: 3px solid #8cb4ff; outline-offset: 3px; }
512
+ .question-notifications-switch input:disabled { cursor: default; }
513
+ #question-notifications-fields:disabled .question-notifications-option { cursor: default; opacity: .6; }
514
+ .question-notifications-help { margin: 16px 0 0; padding: 12px 14px; border-radius: 8px; background: var(--wash); color: var(--muted); font-size: 12px; line-height: 1.6; }
515
+ @media (forced-colors: active) {
516
+ .question-notifications-track::before { background: CanvasText; }
517
+ }
457
518
  @media (max-width: 650px) {
458
519
  .session-access-rule { padding: 16px; }
459
520
  .session-access-footer button { min-height: 44px; }
521
+ .question-notifications-form { padding: 16px; }
522
+ .question-notifications-form .question-notifications-option { gap: 16px; }
523
+ .question-notifications-form .session-access-footer .actions { width: 100%; }
524
+ .question-notifications-form .session-access-footer button { flex: 1; min-width: 0; }
460
525
  }
461
526
  .identity-panel { max-width: 480px; border: 1px solid var(--line); border-radius: 14px; margin-bottom: 24px; padding: 20px; color: var(--ink); }
462
527
  .identity-panel h3 { margin: 0; }
@@ -472,5 +537,19 @@ body.schedule-detail-open { overflow: hidden; }
472
537
 
473
538
  .session-layout { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin: 12px 0; }
474
539
  .session-layout label { display: flex; align-items: center; gap: 8px; }
475
- .session-project-group th { background: var(--wash); font-weight: 600; }
476
- .session-answer-content { white-space: pre-wrap; overflow-wrap: anywhere; font-family: inherit; line-height: 1.65; }
540
+ .session-layout .hint { flex-basis: 100%; margin: 0; color: var(--muted); font-size: 12px; line-height: 1.6; }
541
+ .session-group-actions { display: flex; gap: 4px; }
542
+ .session-group-actions[hidden], .session-group-type[hidden] { display: none; }
543
+ .session-group-actions button { min-height: 35px; border: 0; border-radius: 6px; padding: 7px 10px; background: transparent; color: var(--blue); font-size: 13px; }
544
+ .session-group-actions button:hover:not(:disabled) { background: var(--blue-soft); }
545
+ .session-group-row > th { position: static; padding: 0; background: var(--wash); text-transform: none; letter-spacing: normal; }
546
+ .session-group-toggle { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px; border: 0; padding: 10px 12px; background: transparent; color: var(--ink); text-align: left; font-size: 13px; }
547
+ .session-group-toggle:hover:not(:disabled) { background: var(--blue-soft); }
548
+ .session-group-toggle:focus-visible { outline-offset: -3px; }
549
+ .session-group-chevron { flex: 0 0 8px; width: 8px; height: 8px; margin: 0 3px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); }
550
+ .session-group-toggle[aria-expanded="true"] .session-group-chevron { transform: rotate(45deg) translate(-2px, -2px); }
551
+ .session-group-title { max-width: min(520px, calc(100vw - 230px)); overflow-wrap: anywhere; font-weight: 600; line-height: 1.5; }
552
+ .session-group-type, .session-group-count { flex: none; color: var(--muted); font-size: 12px; font-weight: 400; white-space: nowrap; }
553
+ @media (max-width: 650px) {
554
+ .session-group-actions button { min-height: 44px; }
555
+ }