netizen-cli 0.12.2__tar.gz → 0.13.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 (308) hide show
  1. {netizen_cli-0.12.2/netizen_cli.egg-info → netizen_cli-0.13.1}/PKG-INFO +1 -1
  2. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/README.md +8 -3
  3. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/config.example.yaml +8 -1
  4. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/__init__.py +1 -1
  5. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/port_config.py +22 -0
  6. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/static/admin.css +50 -9
  7. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/static/admin.js +307 -48
  8. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/static/identity.js +18 -5
  9. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/static/index.html +117 -46
  10. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/static/session-access.js +6 -1
  11. netizen_cli-0.13.1/netizen_cli/admin/static/worktrees.js +365 -0
  12. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/web.py +163 -6
  13. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/bindings.py +104 -6
  14. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/controls.py +251 -31
  15. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel_app.py +158 -64
  16. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/codex_runtime.py +291 -21
  17. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/database_migrations.py +3 -3
  18. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/domain.py +4 -0
  19. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/main.py +10 -1
  20. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/management/service.py +95 -1
  21. netizen_cli-0.13.1/netizen_cli/migrations/v15.py +110 -0
  22. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/runtime/contracts.py +3 -0
  23. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/sessions/mcp.py +7 -5
  24. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/sessions/policy.py +7 -13
  25. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/sessions/presentation.py +1 -1
  26. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/sessions/schema.py +23 -2
  27. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/sessions/service.py +63 -8
  28. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/settings.py +7 -0
  29. netizen_cli-0.13.1/netizen_cli/worktrees/errors.py +11 -0
  30. netizen_cli-0.13.1/netizen_cli/worktrees/git.py +569 -0
  31. netizen_cli-0.13.1/netizen_cli/worktrees/models.py +56 -0
  32. netizen_cli-0.13.1/netizen_cli/worktrees/service.py +516 -0
  33. netizen_cli-0.13.1/netizen_cli/worktrees/settings.py +93 -0
  34. netizen_cli-0.13.1/netizen_cli/worktrees/store.py +371 -0
  35. {netizen_cli-0.12.2 → netizen_cli-0.13.1/netizen_cli.egg-info}/PKG-INFO +1 -1
  36. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli.egg-info/SOURCES.txt +17 -1
  37. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/pyproject.toml +1 -1
  38. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/admin.md +50 -6
  39. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/commands.md +2 -2
  40. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/concepts.md +4 -3
  41. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/feedback-and-files.md +2 -2
  42. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/fork-side-goal.md +3 -2
  43. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/native-capabilities.md +4 -0
  44. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/session-collaboration.md +15 -0
  45. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/sessions.md +31 -0
  46. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/user-guide.md +2 -1
  47. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_bindings.py +1 -0
  48. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cards.py +81 -10
  49. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_channel_app.py +21 -6
  50. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cli_data.py +52 -36
  51. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_codex_runtime.py +13 -5
  52. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_completion_mentions.py +3 -3
  53. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_database_migrations.py +9 -5
  54. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_deployment.py +2 -1
  55. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_goal_reply_separation.py +3 -1
  56. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_migration_schema_validation.py +4 -2
  57. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_partial_answer_delivery.py +1 -0
  58. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_scheduled_tasks.py +9 -1
  59. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_scheduled_channel.py +4 -0
  60. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_session_external_runtime.py +48 -2
  61. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_session_tools.py +145 -0
  62. netizen_cli-0.13.1/tests/test_worktree_channel_cwd.py +308 -0
  63. netizen_cli-0.13.1/tests/test_worktree_git.py +444 -0
  64. netizen_cli-0.13.1/tests/test_worktree_new.py +396 -0
  65. netizen_cli-0.13.1/tests/test_worktree_runtime_cwd.py +724 -0
  66. netizen_cli-0.13.1/tests/test_worktree_service.py +493 -0
  67. netizen_cli-0.13.1/tests/test_worktree_settings.py +127 -0
  68. netizen_cli-0.13.1/tests/test_worktree_storage.py +436 -0
  69. netizen_cli-0.13.1/tests/test_worktree_tools_integration.py +165 -0
  70. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/MANIFEST.in +0 -0
  71. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/_build.py +0 -0
  72. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/__main__.py +0 -0
  73. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/account_rate_limits.py +0 -0
  74. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/__init__.py +0 -0
  75. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/auth.py +0 -0
  76. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/credentials.py +0 -0
  77. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/errors.py +0 -0
  78. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/feishu.py +0 -0
  79. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/login.py +0 -0
  80. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/presentation.py +0 -0
  81. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/queries.py +0 -0
  82. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/static/chat-picker.css +0 -0
  83. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/static/chat-picker.js +0 -0
  84. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/static/login.html +0 -0
  85. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/static/login.js +0 -0
  86. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/transport.py +0 -0
  87. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/admin/users.py +0 -0
  88. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/builtin_skills.py +0 -0
  89. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/__init__.py +0 -0
  90. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/callbacks.py +0 -0
  91. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/chat_target.py +0 -0
  92. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/defaults.py +0 -0
  93. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/fork.py +0 -0
  94. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/model_info.py +0 -0
  95. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/pagination.py +0 -0
  96. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/questions.py +0 -0
  97. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/reply.py +0 -0
  98. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/scheduled.py +0 -0
  99. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/session_ids.py +0 -0
  100. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/status.py +0 -0
  101. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cards/usage.py +0 -0
  102. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/__init__.py +0 -0
  103. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/completion_mentions.py +0 -0
  104. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/input_preparation.py +0 -0
  105. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/messages.py +0 -0
  106. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/ports.py +0 -0
  107. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/question_inputs.py +0 -0
  108. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/reactions.py +0 -0
  109. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/reply_presenter.py +0 -0
  110. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/session_pages.py +0 -0
  111. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/channel/topics.py +0 -0
  112. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/chat_avatars.py +0 -0
  113. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/chat_targets.py +0 -0
  114. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cli.py +0 -0
  115. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cli_data.py +0 -0
  116. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cli_packages.py +0 -0
  117. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cli_services.py +0 -0
  118. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cli_setup.py +0 -0
  119. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cli_update.py +0 -0
  120. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cli_update_restore.py +0 -0
  121. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/cli_update_worker.py +0 -0
  122. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/completion_mention.py +0 -0
  123. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/defaults/__init__.py +0 -0
  124. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/defaults/models.py +0 -0
  125. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/defaults/service.py +0 -0
  126. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/defaults/store.py +0 -0
  127. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/deployment/__init__.py +0 -0
  128. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/deployment/restart_worker.py +0 -0
  129. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/deployment/update_executor.py +0 -0
  130. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/deployment/update_protocol.py +0 -0
  131. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/error_messages.py +0 -0
  132. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/experience.py +0 -0
  133. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/feishu_app_onboarding.py +0 -0
  134. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/feishu_app_permissions.py +0 -0
  135. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/feishu_links.py +0 -0
  136. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/git_status.py +0 -0
  137. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/image_inputs.py +0 -0
  138. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/instance.py +0 -0
  139. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/lark_app.py +0 -0
  140. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/management/__init__.py +0 -0
  141. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/management/blocking_io.py +0 -0
  142. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/management/chat_directory.py +0 -0
  143. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/management/chat_labels.py +0 -0
  144. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/management/coordination.py +0 -0
  145. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/management/updates.py +0 -0
  146. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/markdown_images.py +0 -0
  147. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/mcp_transport.py +0 -0
  148. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/message_content.py +0 -0
  149. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/message_history.py +0 -0
  150. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/message_preparation.py +0 -0
  151. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/message_projection.py +0 -0
  152. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/migrations/__init__.py +0 -0
  153. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/migrations/schema.py +0 -0
  154. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/migrations/v14.py +0 -0
  155. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/model_settings.py +0 -0
  156. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/package_resources.py +0 -0
  157. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/pagination.py +0 -0
  158. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/partial_answers.py +0 -0
  159. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/projects.py +0 -0
  160. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/prompt_projection.py +0 -0
  161. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/quoted_context.py +0 -0
  162. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/result_images.py +0 -0
  163. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/runtime/__init__.py +0 -0
  164. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/runtime/name_writes.py +0 -0
  165. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/runtime/thread_naming.py +0 -0
  166. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/schedules/__init__.py +0 -0
  167. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/schedules/mcp.py +0 -0
  168. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/schedules/models.py +0 -0
  169. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/schedules/scheduler.py +0 -0
  170. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/schedules/service.py +0 -0
  171. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/schedules/store.py +0 -0
  172. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/sdk_gap_adapter.py +0 -0
  173. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/service_launcher.py +0 -0
  174. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/session_inventory.py +0 -0
  175. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/session_settings.py +0 -0
  176. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/sessions/__init__.py +0 -0
  177. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/sessions/delegation.py +0 -0
  178. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/sessions/errors.py +0 -0
  179. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/skill_references.py +0 -0
  180. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/task_text.py +0 -0
  181. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/terminal_cleanup.py +0 -0
  182. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/thread_history.py +0 -0
  183. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/turn_activity.py +0 -0
  184. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/turn_files.py +0 -0
  185. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/turn_patch_children.py +0 -0
  186. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/turn_plan_observer.py +0 -0
  187. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli/user_questions.py +0 -0
  188. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli.egg-info/dependency_links.txt +0 -0
  189. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli.egg-info/entry_points.txt +0 -0
  190. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli.egg-info/requires.txt +0 -0
  191. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/netizen_cli.egg-info/top_level.txt +0 -0
  192. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/setup.cfg +0 -0
  193. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-lark/SKILL.md +0 -0
  194. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/SKILL.md +0 -0
  195. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/faq.md +0 -0
  196. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/messages.md +0 -0
  197. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/scheduled-tasks.md +0 -0
  198. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/skills/netizen-user-guide/references/status-and-control.md +0 -0
  199. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_account_rate_limits.py +0 -0
  200. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_admin_update_executor_probe.py +0 -0
  201. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_binding_scheduled_channel.py +0 -0
  202. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_channel_fixtures.py +0 -0
  203. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_channel_input_preparation.py +0 -0
  204. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_chat_avatars.py +0 -0
  205. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_chat_target_cards.py +0 -0
  206. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_check_sdk.py +0 -0
  207. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cli.py +0 -0
  208. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cli_distribution.py +0 -0
  209. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cli_integration.py +0 -0
  210. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cli_packages.py +0 -0
  211. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cli_packaging.py +0 -0
  212. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cli_services.py +0 -0
  213. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cli_setup.py +0 -0
  214. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cli_update.py +0 -0
  215. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_codex_sdk_capabilities.py +0 -0
  216. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_codex_sdk_upgrade_0161.py +0 -0
  217. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_codex_sdk_upgrade_0163.py +0 -0
  218. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_completion_mention_cards.py +0 -0
  219. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_completion_topic_delivery.py +0 -0
  220. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_cron_chat_targets.py +0 -0
  221. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_defaults_cards.py +0 -0
  222. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_defaults_channel.py +0 -0
  223. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_defaults_runtime.py +0 -0
  224. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_documentation_links.py +0 -0
  225. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_domain_experience.py +0 -0
  226. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_error_messages.py +0 -0
  227. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_feishu_app_onboarding.py +0 -0
  228. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_feishu_app_permissions.py +0 -0
  229. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_file_pagination.py +0 -0
  230. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_fork_cards.py +0 -0
  231. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_git_status.py +0 -0
  232. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_image_inputs.py +0 -0
  233. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_lark_app.py +0 -0
  234. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_lark_sdk_contract.py +0 -0
  235. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_main.py +0 -0
  236. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_markdown_images.py +0 -0
  237. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_message_content.py +0 -0
  238. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_message_history.py +0 -0
  239. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_message_material_inputs.py +0 -0
  240. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_message_preparation.py +0 -0
  241. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_model_info_cards.py +0 -0
  242. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_model_settings.py +0 -0
  243. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_name_writes.py +0 -0
  244. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_pagination.py +0 -0
  245. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_partial_answers.py +0 -0
  246. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_persistent_fork_bindings.py +0 -0
  247. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_persistent_fork_channel.py +0 -0
  248. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_persistent_fork_runtime.py +0 -0
  249. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_child_files.py +0 -0
  250. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_feishu_completion_mention.py +0 -0
  251. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_feishu_partial_answers.py +0 -0
  252. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_feishu_turn_file_card.py +0 -0
  253. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_persistent_fork.py +0 -0
  254. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_python_sdk.py +0 -0
  255. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_sdk_completion_race.py +0 -0
  256. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_sdk_response_recovery.py +0 -0
  257. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_skill_execution.py +0 -0
  258. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_probe_thread_naming.py +0 -0
  259. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_project_delete_channel.py +0 -0
  260. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_project_delete_runtime.py +0 -0
  261. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_project_deletion_storage.py +0 -0
  262. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_prompt_projection.py +0 -0
  263. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_question_cards.py +0 -0
  264. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_question_channel.py +0 -0
  265. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_question_target_parity.py +0 -0
  266. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_quoted_context.py +0 -0
  267. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_release_script.py +0 -0
  268. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_repository_hygiene.py +0 -0
  269. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_result_images.py +0 -0
  270. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_resume_channel.py +0 -0
  271. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_retired_deployment.py +0 -0
  272. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_runtime_resume_activation.py +0 -0
  273. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_runtime_thread_naming.py +0 -0
  274. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_schedule_card_retry.py +0 -0
  275. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_schedule_cards.py +0 -0
  276. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_schedule_mcp.py +0 -0
  277. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_schedule_run_now.py +0 -0
  278. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_schedule_scope_matrix.py +0 -0
  279. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_schedule_service.py +0 -0
  280. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_scheduled_runtime.py +0 -0
  281. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_scheduler.py +0 -0
  282. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_scheduler_presenter.py +0 -0
  283. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_schedules_storage.py +0 -0
  284. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_sdk_gap_adapter.py +0 -0
  285. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_service_launcher.py +0 -0
  286. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_session_card_pages.py +0 -0
  287. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_session_collaboration_app.py +0 -0
  288. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_session_defaults.py +0 -0
  289. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_session_id_cards.py +0 -0
  290. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_session_policy.py +0 -0
  291. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_session_settings.py +0 -0
  292. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_settings_projects.py +0 -0
  293. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_status_cards.py +0 -0
  294. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_status_commands.py +0 -0
  295. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_task_text.py +0 -0
  296. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_terminal_cleanup.py +0 -0
  297. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_thread_history.py +0 -0
  298. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_thread_naming.py +0 -0
  299. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_turn_activity.py +0 -0
  300. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_turn_files.py +0 -0
  301. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_turn_patch_children.py +0 -0
  302. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_turn_patch_statistics.py +0 -0
  303. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_turn_plan_observer.py +0 -0
  304. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_update_executor.py +0 -0
  305. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_usage_card.py +0 -0
  306. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_usage_control.py +0 -0
  307. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/tests/test_user_guide_skill.py +0 -0
  308. {netizen_cli-0.12.2 → netizen_cli-0.13.1}/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.2
3
+ Version: 0.13.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
@@ -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.2"
3
+ __version__ = "0.13.1"
@@ -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,
@@ -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; }
@@ -213,7 +220,7 @@ button:focus-visible, input:focus-visible, select:focus-visible { outline: 3px s
213
220
  .time-range-fields { grid-template-columns: 1fr; }
214
221
  }
215
222
  .schedule-help { margin-top: 18px; color: var(--muted); }
216
- body.schedule-drawer-open, body.defaults-drawer-open, body.session-settings-drawer-open { overflow: hidden; }
223
+ body.schedule-drawer-open, body.defaults-drawer-open, body.session-settings-drawer-open, body.workspace-drawer-open { overflow: hidden; }
217
224
  .editor-drawer { position: fixed; inset: 0 0 0 auto; margin: 0; padding: 0; width: min(720px, 100vw); max-width: 100vw; height: 100dvh; max-height: 100dvh; border: 0; color: var(--ink); background: var(--paper); box-shadow: -12px 0 40px rgb(23 39 68 / 16%); }
218
225
  .editor-drawer::backdrop { background: rgb(16 33 63 / 35%); }
219
226
  #schedule-editor { height: 100%; display: flex; flex-direction: column; border: 0; border-radius: 0; padding: 0; margin: 0; }
@@ -322,6 +329,19 @@ body.schedule-detail-open { overflow: hidden; }
322
329
  .drawer-footer { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 24px; border-top: 1px solid var(--line); }
323
330
  .drawer-form .drawer-cancel { color: var(--ink); background: white; border: 1px solid var(--line); }
324
331
  .drawer-form input { margin: 0; }
332
+ .workspace-form[hidden], .workspace-form [hidden] { display: none; }
333
+ .workspace-fields { display: grid; gap: 18px; }
334
+ .workspace-fields .hint { margin: -10px 0 0; }
335
+ .workspace-field-label { margin: 0 0 8px; color: var(--muted); font-size: 13px; }
336
+ .workspace-modes { display: flex; flex-wrap: wrap; gap: 4px; padding: 4px; border-radius: 9px; background: var(--wash); }
337
+ .workspace-form .workspace-modes button { flex: 1; background: transparent; color: var(--muted); }
338
+ .workspace-form .workspace-modes button[aria-pressed="true"] { background: var(--paper); color: var(--blue); box-shadow: 0 1px 4px rgb(23 39 68 / 12%); font-weight: 600; }
339
+ .workspace-form .workspace-modes button:focus-visible { outline: 3px solid #8cb4ff; outline-offset: 2px; }
340
+ .workspace-form .drawer-body > .hint { margin-top: 12px; }
341
+ .workspace-form .status { margin-top: 24px; white-space: pre-line; overflow-wrap: anywhere; }
342
+ .workspace-form .cascade-choice input { width: 16px; height: 16px; margin: 0; flex: 0 0 auto; }
343
+ .workspace-form .target-summary, #worktree-effective-root { overflow-wrap: anywhere; }
344
+ #projects .section-head, #worktrees .section-head { flex-wrap: wrap; }
325
345
  #defaults [hidden], #defaults-editor[hidden], #defaults-editor [hidden] { display: none; }
326
346
  .defaults-help, .defaults-order-help, .defaults-field-help { color: var(--muted); font-size: 13px; line-height: 1.6; }
327
347
  .defaults-help { margin: 12px 0 24px; }
@@ -375,15 +395,36 @@ body.schedule-detail-open { overflow: hidden; }
375
395
  .person-avatar[hidden], .person-placeholder[hidden] { display: none; }
376
396
  .auth-expired { display: flex; align-items: center; justify-content: center; gap: 18px; padding: 18px; background: #fff2df; color: #7b4400; }
377
397
  .auth-expired[hidden], .person[hidden], .identity-panel[hidden], .identity-panel [hidden], .login-card [hidden] { display: none; }
378
- .system-tabs { width: fit-content; margin: 22px 0; }
398
+ .system-tabs { overflow-x: auto; }
399
+ .system-tabs .session-tab { flex: 0 0 auto; min-height: 44px; }
400
+ .system-tab-panel { padding-top: 20px; }
401
+ .tab-unsaved { display: inline-block; margin-left: 6px; padding: 2px 6px; border-radius: 4px; background: #fff3d6; color: #875800; font-size: 12px; font-weight: 400; }
402
+ .tab-unsaved[hidden] { display: none; }
379
403
  .admin-users { padding: 0; margin: 0; list-style: none; }
380
404
  .admin-users > li { display: flex; justify-content: space-between; align-items: center; gap: 16px; border-top: 1px solid var(--line); padding: 16px 0; }
381
- .session-access { margin-top: 32px; padding-top: 18px; border-top: 1px solid var(--line); }
382
- .session-access-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 24px; }
383
- .session-access-grid h4 { margin: 0 0 8px; }
384
- .session-access-grid p { min-height: 48px; color: var(--muted); line-height: 1.6; }
385
- .session-access-grid textarea { width: 100%; resize: vertical; font-family: monospace; }
386
- .session-access-grid [hidden] { display: none; }
405
+ .session-access-form { border: 0; padding: 0; }
406
+ #session-access-fields { min-width: 0; margin: 0; border: 0; padding: 0; }
407
+ .session-access-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); align-items: start; gap: 16px; }
408
+ .session-access-rule { min-width: 0; border: 1px solid var(--line); border-radius: 10px; padding: 20px; }
409
+ .session-access-rule h4 { margin: 0; font-size: 16px; }
410
+ .session-access-description { margin: 6px 0 20px; color: var(--muted); font-size: 13px; line-height: 1.6; }
411
+ .session-access-targets { display: grid; gap: 16px; margin-top: 16px; }
412
+ .session-access-rule-note { margin: 16px 0 0; color: var(--muted); font-size: 12px; line-height: 1.6; }
413
+ .session-access-rule textarea { width: 100%; resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; line-height: 1.6; }
414
+ .session-access-rule .chat-picker-popup { width: 100%; max-width: 100%; }
415
+ .session-access-rule [hidden] { display: none; }
416
+ .session-access-help { margin-top: 16px; padding: 14px 16px; border-radius: 8px; background: var(--wash); color: var(--muted); font-size: 13px; line-height: 1.6; }
417
+ .session-access-help h4 { margin: 0 0 6px; color: var(--ink); font-size: inherit; font-weight: 600; }
418
+ .session-access-help p { margin: 4px 0 0; }
419
+ .session-access-footer { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }
420
+ .session-access-footer .defaults-field-help { flex: 1 1 240px; margin: 0; }
421
+ .session-access-footer .actions { flex: 0 0 auto; gap: 8px; margin-left: auto; }
422
+ .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; }
423
+ .session-access-footer .refresh { border-color: var(--line); background: var(--paper); color: var(--ink); }
424
+ @media (max-width: 650px) {
425
+ .session-access-rule { padding: 16px; }
426
+ .session-access-footer button { min-height: 44px; }
427
+ }
387
428
  .identity-panel { max-width: 480px; border: 1px solid var(--line); border-radius: 14px; margin-bottom: 24px; padding: 20px; color: var(--ink); }
388
429
  .identity-panel h3 { margin: 0; }
389
430
  .identity-panel > p { margin: 20px 0; }