netizen-cli 0.12.1__tar.gz → 0.13.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. {netizen_cli-0.12.1/netizen_cli.egg-info → netizen_cli-0.13.0}/PKG-INFO +2 -2
  2. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/README.md +8 -3
  3. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/config.example.yaml +8 -1
  4. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/__init__.py +1 -1
  5. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/port_config.py +22 -0
  6. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/queries.py +42 -37
  7. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/static/admin.css +8 -1
  8. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/static/admin.js +197 -65
  9. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/static/index.html +41 -4
  10. netizen_cli-0.13.0/netizen_cli/admin/static/worktrees.js +227 -0
  11. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/web.py +188 -22
  12. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/bindings.py +193 -15
  13. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/callbacks.py +1 -0
  14. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/controls.py +357 -114
  15. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/reply.py +10 -4
  16. netizen_cli-0.13.0/netizen_cli/channel/reply_presenter.py +867 -0
  17. netizen_cli-0.13.0/netizen_cli/channel/session_pages.py +102 -0
  18. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/channel_app.py +615 -1445
  19. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/codex_runtime.py +787 -120
  20. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/database_migrations.py +3 -3
  21. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/domain.py +5 -0
  22. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/main.py +12 -1
  23. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/management/__init__.py +2 -2
  24. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/management/service.py +220 -365
  25. netizen_cli-0.13.0/netizen_cli/migrations/v15.py +110 -0
  26. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/runtime/contracts.py +19 -0
  27. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/sdk_gap_adapter.py +58 -5
  28. netizen_cli-0.13.0/netizen_cli/session_inventory.py +142 -0
  29. netizen_cli-0.13.0/netizen_cli/sessions/delegation.py +29 -0
  30. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/sessions/mcp.py +7 -5
  31. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/sessions/policy.py +7 -13
  32. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/sessions/presentation.py +28 -10
  33. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/sessions/schema.py +26 -5
  34. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/sessions/service.py +212 -81
  35. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/settings.py +7 -0
  36. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/terminal_cleanup.py +2 -2
  37. netizen_cli-0.13.0/netizen_cli/thread_history.py +142 -0
  38. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/turn_plan_observer.py +2 -2
  39. netizen_cli-0.13.0/netizen_cli/worktrees/errors.py +11 -0
  40. netizen_cli-0.13.0/netizen_cli/worktrees/git.py +569 -0
  41. netizen_cli-0.13.0/netizen_cli/worktrees/models.py +56 -0
  42. netizen_cli-0.13.0/netizen_cli/worktrees/service.py +516 -0
  43. netizen_cli-0.13.0/netizen_cli/worktrees/settings.py +93 -0
  44. netizen_cli-0.13.0/netizen_cli/worktrees/store.py +371 -0
  45. {netizen_cli-0.12.1 → netizen_cli-0.13.0/netizen_cli.egg-info}/PKG-INFO +2 -2
  46. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli.egg-info/SOURCES.txt +26 -1
  47. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli.egg-info/requires.txt +1 -1
  48. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/pyproject.toml +2 -2
  49. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/admin.md +54 -16
  50. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/commands.md +2 -2
  51. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/concepts.md +4 -3
  52. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/faq.md +2 -2
  53. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/feedback-and-files.md +15 -16
  54. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/fork-side-goal.md +21 -16
  55. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/messages.md +2 -1
  56. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/native-capabilities.md +4 -0
  57. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/session-collaboration.md +15 -0
  58. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/sessions.md +45 -6
  59. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/user-guide.md +2 -1
  60. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_bindings.py +153 -0
  61. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cards.py +113 -53
  62. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_channel_app.py +213 -2054
  63. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cli_data.py +52 -36
  64. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_codex_runtime.py +1312 -59
  65. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_codex_sdk_capabilities.py +1 -1
  66. netizen_cli-0.13.0/tests/test_codex_sdk_upgrade_0163.py +78 -0
  67. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_completion_mention_cards.py +43 -70
  68. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_completion_mentions.py +152 -199
  69. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_database_migrations.py +9 -5
  70. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_deployment.py +3 -2
  71. netizen_cli-0.13.0/tests/test_goal_reply_separation.py +270 -0
  72. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_main.py +3 -0
  73. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_migration_schema_validation.py +4 -2
  74. netizen_cli-0.13.0/tests/test_partial_answer_delivery.py +717 -0
  75. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_scheduled_tasks.py +9 -1
  76. netizen_cli-0.13.0/tests/test_probe_sdk_response_recovery.py +75 -0
  77. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_question_channel.py +5 -7
  78. netizen_cli-0.13.0/tests/test_resume_channel.py +177 -0
  79. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_scheduled_channel.py +64 -4
  80. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_scheduler_presenter.py +46 -15
  81. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_sdk_gap_adapter.py +73 -1
  82. netizen_cli-0.13.0/tests/test_session_card_pages.py +182 -0
  83. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_session_collaboration_app.py +35 -10
  84. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_session_external_runtime.py +48 -2
  85. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_session_id_cards.py +87 -6
  86. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_session_tools.py +358 -15
  87. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_terminal_cleanup.py +2 -2
  88. netizen_cli-0.13.0/tests/test_thread_history.py +186 -0
  89. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_turn_plan_observer.py +1 -1
  90. netizen_cli-0.13.0/tests/test_worktree_channel_cwd.py +308 -0
  91. netizen_cli-0.13.0/tests/test_worktree_git.py +444 -0
  92. netizen_cli-0.13.0/tests/test_worktree_new.py +293 -0
  93. netizen_cli-0.13.0/tests/test_worktree_runtime_cwd.py +724 -0
  94. netizen_cli-0.13.0/tests/test_worktree_service.py +493 -0
  95. netizen_cli-0.13.0/tests/test_worktree_settings.py +127 -0
  96. netizen_cli-0.13.0/tests/test_worktree_storage.py +436 -0
  97. netizen_cli-0.13.0/tests/test_worktree_tools_integration.py +165 -0
  98. netizen_cli-0.12.1/netizen_cli/channel/reply_presenter.py +0 -1655
  99. netizen_cli-0.12.1/tests/test_partial_answer_delivery.py +0 -487
  100. netizen_cli-0.12.1/tests/test_resume_channel.py +0 -91
  101. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/MANIFEST.in +0 -0
  102. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/_build.py +0 -0
  103. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/__main__.py +0 -0
  104. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/account_rate_limits.py +0 -0
  105. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/__init__.py +0 -0
  106. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/auth.py +0 -0
  107. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/credentials.py +0 -0
  108. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/errors.py +0 -0
  109. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/feishu.py +0 -0
  110. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/login.py +0 -0
  111. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/presentation.py +0 -0
  112. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/static/chat-picker.css +0 -0
  113. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/static/chat-picker.js +0 -0
  114. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/static/identity.js +0 -0
  115. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/static/login.html +0 -0
  116. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/static/login.js +0 -0
  117. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/static/session-access.js +0 -0
  118. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/transport.py +0 -0
  119. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/admin/users.py +0 -0
  120. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/builtin_skills.py +0 -0
  121. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/__init__.py +0 -0
  122. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/chat_target.py +0 -0
  123. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/defaults.py +0 -0
  124. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/fork.py +0 -0
  125. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/model_info.py +0 -0
  126. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/pagination.py +0 -0
  127. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/questions.py +0 -0
  128. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/scheduled.py +0 -0
  129. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/session_ids.py +0 -0
  130. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/status.py +0 -0
  131. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cards/usage.py +0 -0
  132. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/channel/__init__.py +0 -0
  133. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/channel/completion_mentions.py +0 -0
  134. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/channel/input_preparation.py +0 -0
  135. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/channel/messages.py +0 -0
  136. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/channel/ports.py +0 -0
  137. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/channel/question_inputs.py +0 -0
  138. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/channel/reactions.py +0 -0
  139. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/channel/topics.py +0 -0
  140. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/chat_avatars.py +0 -0
  141. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/chat_targets.py +0 -0
  142. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cli.py +0 -0
  143. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cli_data.py +0 -0
  144. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cli_packages.py +0 -0
  145. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cli_services.py +0 -0
  146. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cli_setup.py +0 -0
  147. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cli_update.py +0 -0
  148. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cli_update_restore.py +0 -0
  149. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/cli_update_worker.py +0 -0
  150. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/completion_mention.py +0 -0
  151. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/defaults/__init__.py +0 -0
  152. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/defaults/models.py +0 -0
  153. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/defaults/service.py +0 -0
  154. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/defaults/store.py +0 -0
  155. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/deployment/__init__.py +0 -0
  156. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/deployment/restart_worker.py +0 -0
  157. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/deployment/update_executor.py +0 -0
  158. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/deployment/update_protocol.py +0 -0
  159. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/error_messages.py +0 -0
  160. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/experience.py +0 -0
  161. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/feishu_app_onboarding.py +0 -0
  162. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/feishu_app_permissions.py +0 -0
  163. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/feishu_links.py +0 -0
  164. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/git_status.py +0 -0
  165. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/image_inputs.py +0 -0
  166. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/instance.py +0 -0
  167. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/lark_app.py +0 -0
  168. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/management/blocking_io.py +0 -0
  169. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/management/chat_directory.py +0 -0
  170. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/management/chat_labels.py +0 -0
  171. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/management/coordination.py +0 -0
  172. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/management/updates.py +0 -0
  173. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/markdown_images.py +0 -0
  174. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/mcp_transport.py +0 -0
  175. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/message_content.py +0 -0
  176. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/message_history.py +0 -0
  177. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/message_preparation.py +0 -0
  178. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/message_projection.py +0 -0
  179. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/migrations/__init__.py +0 -0
  180. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/migrations/schema.py +0 -0
  181. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/migrations/v14.py +0 -0
  182. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/model_settings.py +0 -0
  183. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/package_resources.py +0 -0
  184. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/pagination.py +0 -0
  185. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/partial_answers.py +0 -0
  186. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/projects.py +0 -0
  187. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/prompt_projection.py +0 -0
  188. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/quoted_context.py +0 -0
  189. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/result_images.py +0 -0
  190. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/runtime/__init__.py +0 -0
  191. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/runtime/name_writes.py +0 -0
  192. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/runtime/thread_naming.py +0 -0
  193. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/schedules/__init__.py +0 -0
  194. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/schedules/mcp.py +0 -0
  195. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/schedules/models.py +0 -0
  196. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/schedules/scheduler.py +0 -0
  197. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/schedules/service.py +0 -0
  198. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/schedules/store.py +0 -0
  199. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/service_launcher.py +0 -0
  200. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/session_settings.py +0 -0
  201. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/sessions/__init__.py +0 -0
  202. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/sessions/errors.py +0 -0
  203. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/skill_references.py +0 -0
  204. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/task_text.py +0 -0
  205. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/turn_activity.py +0 -0
  206. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/turn_files.py +0 -0
  207. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/turn_patch_children.py +0 -0
  208. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli/user_questions.py +0 -0
  209. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli.egg-info/dependency_links.txt +0 -0
  210. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli.egg-info/entry_points.txt +0 -0
  211. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/netizen_cli.egg-info/top_level.txt +0 -0
  212. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/setup.cfg +0 -0
  213. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-lark/SKILL.md +0 -0
  214. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/SKILL.md +0 -0
  215. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/scheduled-tasks.md +0 -0
  216. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/skills/netizen-user-guide/references/status-and-control.md +0 -0
  217. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_account_rate_limits.py +0 -0
  218. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_admin_update_executor_probe.py +0 -0
  219. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_binding_scheduled_channel.py +0 -0
  220. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_channel_fixtures.py +0 -0
  221. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_channel_input_preparation.py +0 -0
  222. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_chat_avatars.py +0 -0
  223. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_chat_target_cards.py +0 -0
  224. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_check_sdk.py +0 -0
  225. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cli.py +0 -0
  226. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cli_distribution.py +0 -0
  227. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cli_integration.py +0 -0
  228. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cli_packages.py +0 -0
  229. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cli_packaging.py +0 -0
  230. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cli_services.py +0 -0
  231. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cli_setup.py +0 -0
  232. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cli_update.py +0 -0
  233. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_codex_sdk_upgrade_0161.py +0 -0
  234. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_completion_topic_delivery.py +0 -0
  235. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_cron_chat_targets.py +0 -0
  236. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_defaults_cards.py +0 -0
  237. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_defaults_channel.py +0 -0
  238. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_defaults_runtime.py +0 -0
  239. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_documentation_links.py +0 -0
  240. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_domain_experience.py +0 -0
  241. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_error_messages.py +0 -0
  242. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_feishu_app_onboarding.py +0 -0
  243. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_feishu_app_permissions.py +0 -0
  244. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_file_pagination.py +0 -0
  245. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_fork_cards.py +0 -0
  246. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_git_status.py +0 -0
  247. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_image_inputs.py +0 -0
  248. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_lark_app.py +0 -0
  249. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_lark_sdk_contract.py +0 -0
  250. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_markdown_images.py +0 -0
  251. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_message_content.py +0 -0
  252. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_message_history.py +0 -0
  253. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_message_material_inputs.py +0 -0
  254. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_message_preparation.py +0 -0
  255. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_model_info_cards.py +0 -0
  256. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_model_settings.py +0 -0
  257. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_name_writes.py +0 -0
  258. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_pagination.py +0 -0
  259. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_partial_answers.py +0 -0
  260. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_persistent_fork_bindings.py +0 -0
  261. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_persistent_fork_channel.py +0 -0
  262. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_persistent_fork_runtime.py +0 -0
  263. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_child_files.py +0 -0
  264. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_feishu_completion_mention.py +0 -0
  265. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_feishu_partial_answers.py +0 -0
  266. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_feishu_turn_file_card.py +0 -0
  267. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_persistent_fork.py +0 -0
  268. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_python_sdk.py +0 -0
  269. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_sdk_completion_race.py +0 -0
  270. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_skill_execution.py +0 -0
  271. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_probe_thread_naming.py +0 -0
  272. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_project_delete_channel.py +0 -0
  273. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_project_delete_runtime.py +0 -0
  274. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_project_deletion_storage.py +0 -0
  275. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_prompt_projection.py +0 -0
  276. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_question_cards.py +0 -0
  277. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_question_target_parity.py +0 -0
  278. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_quoted_context.py +0 -0
  279. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_release_script.py +0 -0
  280. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_repository_hygiene.py +0 -0
  281. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_result_images.py +0 -0
  282. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_retired_deployment.py +0 -0
  283. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_runtime_resume_activation.py +0 -0
  284. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_runtime_thread_naming.py +0 -0
  285. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_schedule_card_retry.py +0 -0
  286. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_schedule_cards.py +0 -0
  287. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_schedule_mcp.py +0 -0
  288. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_schedule_run_now.py +0 -0
  289. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_schedule_scope_matrix.py +0 -0
  290. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_schedule_service.py +0 -0
  291. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_scheduled_runtime.py +0 -0
  292. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_scheduler.py +0 -0
  293. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_schedules_storage.py +0 -0
  294. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_service_launcher.py +0 -0
  295. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_session_defaults.py +0 -0
  296. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_session_policy.py +0 -0
  297. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_session_settings.py +0 -0
  298. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_settings_projects.py +0 -0
  299. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_status_cards.py +0 -0
  300. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_status_commands.py +0 -0
  301. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_task_text.py +0 -0
  302. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_thread_naming.py +0 -0
  303. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_turn_activity.py +0 -0
  304. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_turn_files.py +0 -0
  305. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_turn_patch_children.py +0 -0
  306. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_turn_patch_statistics.py +0 -0
  307. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_update_executor.py +0 -0
  308. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_usage_card.py +0 -0
  309. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_usage_control.py +0 -0
  310. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_user_guide_skill.py +0 -0
  311. {netizen_cli-0.12.1 → netizen_cli-0.13.0}/tests/test_user_questions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netizen-cli
3
- Version: 0.12.1
3
+ Version: 0.13.0
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
@@ -11,7 +11,7 @@ Requires-Dist: markdown-it-py==4.0.0
11
11
  Requires-Dist: mdformat==1.0.0
12
12
  Requires-Dist: mdformat-gfm==1.0.0
13
13
  Requires-Dist: mcp==2.2.0
14
- Requires-Dist: openai-codex==0.162.1
14
+ Requires-Dist: openai-codex==0.163.0
15
15
  Requires-Dist: pydantic==2.13.4
16
16
  Requires-Dist: PyYAML==6.0.3
17
17
  Requires-Dist: qrcode==8.2
@@ -103,7 +103,7 @@ Agent/脚本使用 `netizen update --json`:stdout 只输出最终 JSON,进
103
103
  ### 3. 在飞书开始第一次对话
104
104
 
105
105
  1. 打开机器人单聊;如需在群里使用,先将机器人加入目标群。
106
- 2. 发送 `/settings`,创建或登记一个项目并启用。项目就是 Codex 实际工作的目录。
106
+ 2. 发送 `/settings`,创建或登记一个项目并启用。项目登记一个默认工作目录。
107
107
  3. 发送 `/new`,在卡片中选择项目。模型配置可选择“继承 Codex”;过程卡默认开启,可按需关闭。
108
108
  4. 直接发送任务,例如:**“梳理这个项目的结构,并生成一份入门说明。”**
109
109
  5. 收到回复后继续交流;如果出现“本轮文件”,点击“发送”取回需要的文件。
@@ -116,6 +116,11 @@ Agent/脚本使用 `netizen update --json`:stdout 只输出最终 JSON,进
116
116
  群聊和群话题中的每条请求都需要重新 **@机器人**,包括命令。`/new` 只通过卡片创建会话,
117
117
  不接受参数。普通任务执行中发来的新消息用于调整当前任务,不会排队成下一个任务。
118
118
 
119
+ Git 项目可在 `/new` 中加载项目目录选项,选择已有受管 worktree 或新建 worktree;默认
120
+ 仍使用项目目录。新建只检出提交内容,不复制本地改动或执行环境初始化。
121
+ 配置、状态查询与删除在 [Admin Worktrees](skills/netizen-user-guide/references/admin.md#worktree-配置与管理)
122
+ 中完成;不同会话可以共享同一工作区。`/fork` 不提供新建或选择 worktree 的入口。
123
+
119
124
  安装遇到问题可从[部署文档](docs/deployment.md)继续;已能对话时,常见疑问见
120
125
  [使用 FAQ](skills/netizen-user-guide/references/faq.md#常见问题)。
121
126
 
@@ -126,7 +131,7 @@ Agent/脚本使用 `netizen update --json`:stdout 只输出最终 JSON,进
126
131
  | 想做什么 | 入口 |
127
132
  | --- | --- |
128
133
  | 创建或登记项目工作目录 | `/settings` |
129
- | 新建会话,选择项目 | `/new` |
134
+ | 新建会话,选择项目及受管 worktree | `/new` |
130
135
  | 查看、保存或删除当前聊天的会话默认配置 | `/defaults` |
131
136
  | 查看并切换已有会话 | `/sessions` |
132
137
  | 从当前空闲会话另建持久分支话题 | `/fork` |
@@ -149,7 +154,7 @@ Agent/脚本使用 `netizen update --json`:stdout 只输出最终 JSON,进
149
154
  /side 这个方案还有哪些边界情况需要考虑?
150
155
  ```
151
156
 
152
- Side 会在同一聊天中新建话题,可继续多轮讨论。它与原会话共享项目目录,空闲两小时或
157
+ Side 会在同一聊天中新建话题,可继续多轮讨论。它与原会话共享实际工作目录,空闲两小时或
153
158
  服务重启后过期;`/side close` 主动结束话题会话。Side 中不支持 Goal。
154
159
 
155
160
  **每天回顾项目进展。** 在已经选择项目的普通会话中发送:
@@ -9,9 +9,16 @@ instance:
9
9
  # User and chat availability are configured in the Feishu app console. Netizen
10
10
  # does not maintain a second allowlist.
11
11
  projects:
12
- # All native Codex Threads under this alias share the exact same cwd.
12
+ # Default cwd. /new can explicitly select a managed Worktree of this Project.
13
13
  test: /home/your-user/projects/test
14
14
 
15
+ # Instance-owned Git worktrees; Admin can change these settings for future creates.
16
+ # Omitted root uses <instance-root>/worktrees; existing checkouts are not moved.
17
+ # No Codex App global configuration or private managed index is modified.
18
+ worktrees:
19
+ # root: /home/your-user/.netizen/worktrees
20
+ fetchBeforeCreate: false
21
+
15
22
  channel:
16
23
  securityMode: audit
17
24
 
@@ -1,3 +1,3 @@
1
1
  """Netizen: a thin Feishu Channel for native Codex Threads."""
2
2
 
3
- __version__ = "0.12.1"
3
+ __version__ = "0.13.0"
@@ -6,6 +6,7 @@ import contextlib
6
6
  import os
7
7
  import stat
8
8
  import tempfile
9
+ import threading
9
10
  from dataclasses import dataclass, field
10
11
  from pathlib import Path
11
12
 
@@ -45,6 +46,27 @@ class ConfigFileSnapshot:
45
46
  )
46
47
 
47
48
 
49
+ class ConfigFileEditor:
50
+ """Serialize instance-owned section edits against one exact file snapshot.
51
+
52
+ Settings services share this object so their successful writes do not make
53
+ each other stale. External edits still conflict with the complete snapshot;
54
+ they are never silently merged or made effective in the running service.
55
+ """
56
+
57
+ def __init__(self, snapshot: ConfigFileSnapshot) -> None:
58
+ self._snapshot = snapshot
59
+ self._lock = threading.RLock()
60
+
61
+ def update_section(self, name: str, value: object) -> None:
62
+ with self._lock:
63
+ loaded = yaml.safe_load(self._snapshot.content)
64
+ if not isinstance(loaded, dict):
65
+ raise AdminPortConfigurationError("configuration root must be a mapping")
66
+ loaded[name] = value
67
+ self._snapshot = write_configuration(self._snapshot, loaded)
68
+
69
+
48
70
  def _identity(metadata: os.stat_result) -> tuple[int, ...]:
49
71
  return (
50
72
  metadata.st_dev, metadata.st_ino, metadata.st_mode, metadata.st_size,
@@ -12,7 +12,7 @@ from datetime import UTC, datetime
12
12
  from .errors import AdminWebError
13
13
  from ..bindings import BindingCursor, SideTopicCursor
14
14
  from ..domain import ScopeKind
15
- from ..management import SessionInventoryState, SessionUpdatedCursor
15
+ from ..management import SessionInventoryState, SessionNativeCursor
16
16
 
17
17
 
18
18
  _MAX_TEXT_BYTES = 4_096
@@ -113,22 +113,34 @@ def _text_set_query(
113
113
  def _created_range_query(
114
114
  values: Mapping[str, list[str]],
115
115
  ) -> tuple[str | None, str | None]:
116
- created_from = _optional_created_time_query(values, "createdFrom")
117
- created_before = _optional_created_time_query(values, "createdBefore")
116
+ return _time_range_query(values, "created", "创建")
117
+
118
+
119
+ def _updated_range_query(
120
+ values: Mapping[str, list[str]],
121
+ ) -> tuple[str | None, str | None]:
122
+ return _time_range_query(values, "updated", "更新")
123
+
124
+
125
+ def _time_range_query(
126
+ values: Mapping[str, list[str]], prefix: str, label: str,
127
+ ) -> tuple[str | None, str | None]:
128
+ lower = _optional_time_query(values, f"{prefix}From")
129
+ upper = _optional_time_query(values, f"{prefix}Before")
118
130
  if (
119
- created_from is not None
120
- and created_before is not None
121
- and created_from >= created_before
131
+ lower is not None
132
+ and upper is not None
133
+ and lower >= upper
122
134
  ):
123
135
  raise AdminWebError(
124
136
  400,
125
137
  "invalid_time_range",
126
- "创建时间的开始时间必须早于结束时间。",
138
+ f"{label}时间的开始时间必须早于结束时间。",
127
139
  )
128
- return created_from, created_before
140
+ return lower, upper
129
141
 
130
142
 
131
- def _optional_created_time_query(
143
+ def _optional_time_query(
132
144
  values: Mapping[str, list[str]],
133
145
  name: str,
134
146
  ) -> str | None:
@@ -190,27 +202,17 @@ def _current_query(values: Mapping[str, list[str]]) -> bool | None:
190
202
  return raw[0] == "true" if len(raw) == 1 else None
191
203
 
192
204
 
193
- def _session_inventory_states(
205
+ def _session_inventory_state(
194
206
  values: Mapping[str, list[str]],
195
- ) -> tuple[SessionInventoryState, ...] | None:
196
- raw = _text_set_query(values, "inventoryState")
197
- if raw is None:
198
- return (
199
- SessionInventoryState.ACTIVE,
200
- SessionInventoryState.LAZY,
201
- SessionInventoryState.UNKNOWN,
202
- )
203
- if raw == ("all",):
204
- return None
205
- try:
206
- states = tuple(SessionInventoryState(value) for value in raw)
207
- except ValueError:
207
+ ) -> SessionInventoryState:
208
+ raw = _optional_one(values, "inventoryState") or "active"
209
+ if raw not in {"active", "archived", "lazy"}:
208
210
  raise AdminWebError(
209
211
  400,
210
212
  "invalid_inventory_state",
211
213
  "会话状态无效。",
212
- ) from None
213
- return None if set(states) == set(SessionInventoryState) else states
214
+ )
215
+ return SessionInventoryState(raw)
214
216
 
215
217
 
216
218
  def _id_query(values: Mapping[str, list[str]], name: str) -> tuple[str, ...]:
@@ -308,13 +310,14 @@ def _decode_binding_cursor(
308
310
 
309
311
 
310
312
  def _encode_session_cursor(
311
- cursor: BindingCursor | SessionUpdatedCursor | None,
313
+ cursor: BindingCursor | SessionNativeCursor | None,
312
314
  fingerprint: str,
313
315
  ) -> str | None:
314
- if not isinstance(cursor, SessionUpdatedCursor):
316
+ if not isinstance(cursor, SessionNativeCursor):
315
317
  return _encode_binding_cursor(cursor, fingerprint)
318
+ marker = "start" if cursor.cursor is None else "next"
316
319
  return _encode_cursor(
317
- "session-updated", (str(cursor.updated_at) if cursor.updated_at is not None else "unknown", cursor.binding_id), fingerprint,
320
+ "session-native", (marker, cursor.cursor if cursor.cursor is not None else "start", str(cursor.offset)), fingerprint,
318
321
  )
319
322
 
320
323
 
@@ -322,19 +325,21 @@ def _decode_session_cursor(
322
325
  encoded: str | None,
323
326
  fingerprint: str,
324
327
  *,
325
- sort_by: str,
326
- ) -> BindingCursor | SessionUpdatedCursor | None:
327
- if sort_by == "created_at":
328
+ inventory_state: SessionInventoryState,
329
+ ) -> BindingCursor | SessionNativeCursor | None:
330
+ if inventory_state is SessionInventoryState.LAZY:
328
331
  return _decode_binding_cursor(encoded, fingerprint)
329
- values = _decode_cursor(encoded, kind="session-updated", length=2, fingerprint=fingerprint)
332
+ values = _decode_cursor(encoded, kind="session-native", length=3, fingerprint=fingerprint)
330
333
  if values is None:
331
334
  return None
332
- raw_time, binding_id = values
333
- if raw_time == "unknown":
334
- return SessionUpdatedCursor(None, binding_id)
335
- if not re.fullmatch(r"0|[1-9][0-9]{0,15}", raw_time):
335
+ marker, raw_cursor, raw_offset = values
336
+ if (
337
+ marker not in {"start", "next"}
338
+ or marker == "start" and raw_cursor != "start"
339
+ or re.fullmatch(r"0|[1-9][0-9]?", raw_offset) is None
340
+ ):
336
341
  raise AdminWebError(400, "invalid_cursor", "分页游标无效。")
337
- return SessionUpdatedCursor(int(raw_time), binding_id)
342
+ return SessionNativeCursor(None if marker == "start" else raw_cursor, int(raw_offset))
338
343
 
339
344
 
340
345
  def _encode_side_cursor(
@@ -101,7 +101,8 @@ input, select, textarea { min-width: 0; border: 1px solid #bac3d0; border-radius
101
101
  .time-range-calendar-icon { position: relative; width: 15px; height: 14px; flex: 0 0 auto; border: 1.5px solid currentColor; border-radius: 3px; color: var(--muted); }
102
102
  .time-range-calendar-icon::before { content: ""; position: absolute; left: -1.5px; right: -1.5px; top: 3px; border-top: 1.5px solid currentColor; }
103
103
  .time-range-calendar-icon::after { content: ""; position: absolute; width: 2px; height: 2px; left: 3px; top: 7px; border-radius: 50%; background: currentColor; box-shadow: 4px 0 currentColor, 8px 0 currentColor; }
104
- .time-range-summary { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
104
+ .time-range-summary { min-width: 0; flex: 1; white-space: pre-line; overflow-wrap: anywhere; }
105
+ .time-range-dates { color: var(--muted); font-size: 11px; }
105
106
  .time-range-chevron { flex: 0 0 auto; color: var(--muted); font-size: 16px; line-height: 1; }
106
107
  .time-range-quick-clear { position: absolute; z-index: 1; top: 50%; right: 30px; width: 24px; height: 24px; transform: translateY(-50%); border: 0; border-radius: 50%; padding: 0; background: transparent; color: var(--muted); font-size: 18px; line-height: 22px; }
107
108
  .time-range-quick-clear:hover { background: #edf1f6; color: var(--ink); }
@@ -160,6 +161,12 @@ tr:last-child td { border-bottom: 0; }
160
161
  .badge.on { background: #e5f6ed; color: #136c3c; }
161
162
  .badge.warn { background: #fff2df; color: #925400; }
162
163
  .actions { display: flex; flex-wrap: wrap; gap: 5px; }
164
+ .cascade-choice, .card-form label.cascade-choice { display: flex; align-items: center; gap: 6px; font-size: 12px; }
165
+ .cascade-choice input, .card-form .cascade-choice input { width: auto; margin: 0; }
166
+ #worktrees-body td { white-space: pre-line; overflow-wrap: anywhere; }
167
+ #worktrees-body td:last-child { min-width: 170px; }
168
+ #worktrees-body .action { margin-top: 8px; }
169
+ #worktree-result { white-space: pre-line; }
163
170
  .project-delete-result { margin: 16px 0; padding: 14px 16px; border: 1px solid var(--line); border-radius: 9px; background: var(--wash); font-size: 13px; line-height: 1.6; }
164
171
  .project-delete-result.error { border-color: #e3b8b4; color: var(--danger); }
165
172
  .project-delete-result p { margin: 0; white-space: pre-line; }