netizen-cli 0.13.3__tar.gz → 0.14.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.
- {netizen_cli-0.13.3/netizen_cli.egg-info → netizen_cli-0.14.0}/PKG-INFO +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/README.md +3 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/__init__.py +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/presentation.py +11 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/admin.css +5 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/admin.js +161 -43
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/index.html +45 -13
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/worktrees.js +12 -12
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/web.py +29 -15
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/bindings.py +30 -15
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/controls.py +64 -21
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/defaults.py +3 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/reply.py +113 -47
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/scheduled.py +21 -21
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/workspace.py +17 -17
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel_app.py +14 -9
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/codex_runtime.py +78 -83
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/database_migrations.py +2 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/defaults/service.py +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/defaults/store.py +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/domain.py +7 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/management/chat_labels.py +152 -69
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/management/service.py +36 -28
- netizen_cli-0.14.0/netizen_cli/migrations/v18.py +132 -0
- netizen_cli-0.14.0/netizen_cli/progress_card_settings.py +42 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/runtime/contracts.py +4 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/schedules/service.py +7 -7
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/schedules/store.py +6 -6
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/sdk_gap_adapter.py +14 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/session_settings.py +12 -2
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/turn_activity.py +49 -27
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/turn_plan_observer.py +4 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/worktrees/policy.py +3 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/worktrees/service.py +14 -14
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/worktrees/store.py +15 -15
- {netizen_cli-0.13.3 → netizen_cli-0.14.0/netizen_cli.egg-info}/PKG-INFO +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli.egg-info/SOURCES.txt +5 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/pyproject.toml +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/admin.md +24 -19
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/concepts.md +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/feedback-and-files.md +42 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/fork-side-goal.md +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/native-capabilities.md +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/scheduled-tasks.md +28 -26
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/session-collaboration.md +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/sessions.md +33 -31
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/user-guide.md +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cards.py +8 -5
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_channel_app.py +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cli_data.py +6 -6
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_codex_runtime.py +257 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cron_chat_targets.py +2 -2
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_database_migrations.py +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_defaults_cards.py +6 -6
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_defaults_channel.py +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_migration_schema_validation.py +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_persistent_fork_channel.py +4 -1
- netizen_cli-0.14.0/tests/test_progress_card_entrypoints.py +182 -0
- netizen_cli-0.14.0/tests/test_progress_card_presentation.py +273 -0
- netizen_cli-0.14.0/tests/test_progress_card_settings_migration.py +177 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_cards.py +8 -8
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_service.py +4 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_workspace_cards.py +2 -2
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_workspace_migration.py +15 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedules_storage.py +4 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_sdk_gap_adapter.py +25 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_session_collaboration_app.py +7 -2
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_session_defaults_migration.py +15 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_session_settings.py +48 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_turn_activity.py +57 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_turn_plan_observer.py +23 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_worktree_new.py +3 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_worktree_storage.py +16 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/MANIFEST.in +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/_build.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/config.example.yaml +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/__main__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/account_rate_limits.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/auth.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/credentials.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/errors.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/feishu.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/login.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/port_config.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/queries.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/chat-picker.css +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/chat-picker.js +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/identity.js +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/login.html +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/login.js +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/static/session-access.js +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/transport.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/admin/users.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/builtin_skills.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/callbacks.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/chat_target.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/fork.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/model_info.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/pagination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/questions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/session_ids.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/status.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cards/usage.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/completion_mentions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/input_preparation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/messages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/ports.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/question_inputs.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/reactions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/reply_presenter.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/session_pages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/channel/topics.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/chat_avatars.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/chat_targets.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cli.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cli_data.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cli_packages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cli_services.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cli_setup.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cli_update.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cli_update_restore.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/cli_update_worker.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/completion_mention.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/defaults/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/defaults/models.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/deployment/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/deployment/restart_worker.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/deployment/update_executor.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/deployment/update_protocol.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/error_messages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/experience.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/feishu_app_onboarding.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/feishu_app_permissions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/feishu_links.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/git_status.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/image_inputs.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/instance.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/lark_app.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/main.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/management/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/management/blocking_io.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/management/chat_directory.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/management/coordination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/management/updates.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/markdown_images.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/mcp_transport.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/message_content.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/message_history.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/message_preparation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/message_projection.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/migrations/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/migrations/schema.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/migrations/v14.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/migrations/v15.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/migrations/v16.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/migrations/v17.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/model_settings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/package_resources.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/pagination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/partial_answers.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/projects.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/prompt_projection.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/quoted_context.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/result_images.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/runtime/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/runtime/name_writes.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/runtime/thread_naming.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/schedules/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/schedules/mcp.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/schedules/models.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/schedules/scheduler.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/service_launcher.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/session_inventory.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/sessions/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/sessions/delegation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/sessions/errors.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/sessions/mcp.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/sessions/policy.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/sessions/presentation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/sessions/schema.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/sessions/service.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/settings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/skill_references.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/task_text.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/terminal_cleanup.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/thread_history.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/turn_files.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/turn_patch_children.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/user_questions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/worktrees/errors.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/worktrees/git.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/worktrees/models.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli/worktrees/settings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli.egg-info/dependency_links.txt +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli.egg-info/entry_points.txt +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli.egg-info/requires.txt +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/netizen_cli.egg-info/top_level.txt +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/setup.cfg +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-lark/SKILL.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/SKILL.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/commands.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/faq.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/messages.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/skills/netizen-user-guide/references/status-and-control.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_account_rate_limits.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_admin_update_executor_probe.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_binding_scheduled_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_bindings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_channel_fixtures.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_channel_input_preparation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_chat_avatars.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_chat_target_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_check_sdk.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cli.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cli_distribution.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cli_integration.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cli_packages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cli_packaging.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cli_services.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cli_setup.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_cli_update.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_codex_sdk_capabilities.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_codex_sdk_upgrade_0161.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_codex_sdk_upgrade_0163.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_completion_mention_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_completion_mentions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_completion_topic_delivery.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_defaults_runtime.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_defaults_worktree_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_deployment.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_documentation_links.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_domain_experience.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_error_messages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_feishu_app_onboarding.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_feishu_app_permissions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_file_pagination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_fork_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_git_status.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_goal_reply_separation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_image_inputs.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_lark_app.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_lark_sdk_contract.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_main.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_markdown_images.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_message_content.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_message_history.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_message_material_inputs.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_message_preparation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_model_info_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_model_settings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_name_writes.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_pagination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_partial_answer_delivery.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_partial_answers.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_persistent_fork_bindings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_persistent_fork_runtime.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_child_files.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_feishu_completion_mention.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_feishu_partial_answers.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_feishu_turn_file_card.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_persistent_fork.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_python_sdk.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_scheduled_tasks.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_sdk_completion_race.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_sdk_response_recovery.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_skill_execution.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_probe_thread_naming.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_project_delete_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_project_delete_runtime.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_project_deletion_storage.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_prompt_projection.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_question_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_question_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_question_target_parity.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_quoted_context.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_release_script.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_repository_hygiene.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_result_images.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_resume_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_retired_deployment.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_runtime_resume_activation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_runtime_thread_naming.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_card_retry.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_mcp.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_run_now.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_scope_matrix.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_workspace_service.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_schedule_workspace_storage.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_scheduled_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_scheduled_runtime.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_scheduled_worktrees.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_scheduler.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_scheduler_presenter.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_service_launcher.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_session_card_pages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_session_defaults.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_session_external_runtime.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_session_id_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_session_policy.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_session_tools.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_settings_projects.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_status_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_status_commands.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_task_text.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_terminal_cleanup.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_thread_history.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_thread_naming.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_turn_files.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_turn_patch_children.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_turn_patch_statistics.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_update_executor.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_usage_card.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_usage_control.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_user_guide_skill.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_user_questions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_worktree_channel_cwd.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_worktree_git.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_worktree_runtime_cwd.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_worktree_service.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_worktree_settings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.0}/tests/test_worktree_tools_integration.py +0 -0
|
@@ -116,10 +116,10 @@ Agent/脚本使用 `netizen update --json`:stdout 只输出最终 JSON,进
|
|
|
116
116
|
群聊和群话题中的每条请求都需要重新 **@机器人**,包括命令。`/new` 只通过卡片创建会话,
|
|
117
117
|
不接受参数。普通任务执行中发来的新消息用于调整当前任务,不会排队成下一个任务。
|
|
118
118
|
|
|
119
|
-
Git 项目可在 `/new`
|
|
119
|
+
Git 项目可在 `/new` 中加载 worktree 选项,选择已有受管 worktree 或新建 worktree;默认
|
|
120
120
|
仍使用项目目录。新建只检出提交内容,不复制本地改动或执行环境初始化。
|
|
121
|
-
配置、状态查询与删除在 [Admin
|
|
122
|
-
|
|
121
|
+
配置、状态查询与删除在 [Admin worktree](skills/netizen-user-guide/references/admin.md#worktree-配置与管理)
|
|
122
|
+
中完成;不同会话可以共享同一 worktree。`/fork` 不提供新建或选择 worktree 的入口。
|
|
123
123
|
|
|
124
124
|
安装遇到问题可从[部署文档](docs/deployment.md)继续;已能对话时,常见疑问见
|
|
125
125
|
[使用 FAQ](skills/netizen-user-guide/references/faq.md#常见问题)。
|
|
@@ -23,6 +23,17 @@ def _chat_open_url(chat: ChatLabel) -> str:
|
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def _chat_label_json(chat: ChatLabel) -> dict[str, object]:
|
|
27
|
+
return {
|
|
28
|
+
"chatId": chat.chat_id,
|
|
29
|
+
"chatLabel": chat.display_name,
|
|
30
|
+
"chatLabelResolved": chat.resolved,
|
|
31
|
+
"chatMode": chat.chat_mode,
|
|
32
|
+
"chatType": chat.chat_type,
|
|
33
|
+
"chatOpenUrl": _chat_open_url(chat),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
26
37
|
def _schedule_plan_json(plan: dict[str, Any], chat: ChatLabel) -> dict[str, Any]:
|
|
27
38
|
rule = plan.get("schedule")
|
|
28
39
|
local_at = None
|
|
@@ -380,6 +380,11 @@ body.schedule-detail-open { overflow: hidden; }
|
|
|
380
380
|
.defaults-feedback { display: flex; flex-wrap: wrap; gap: 18px; }
|
|
381
381
|
.defaults-feedback label { display: flex; align-items: center; gap: 7px; }
|
|
382
382
|
.drawer-form .defaults-feedback input { width: 16px; height: 16px; margin: 0; accent-color: var(--blue); }
|
|
383
|
+
.progress-settings { margin-top: 18px; padding: 16px; border: 1px solid var(--line); border-radius: 8px; }
|
|
384
|
+
.progress-settings > .defaults-feedback { margin-top: 16px; }
|
|
385
|
+
.progress-settings > .schedule-form-grid { margin-top: 10px; }
|
|
386
|
+
.progress-settings > .session-settings-help { margin-bottom: 0; }
|
|
387
|
+
.progress-settings-error { color: var(--danger); font-size: 13px; line-height: 1.6; }
|
|
383
388
|
#defaults-note.error { color: var(--danger); }
|
|
384
389
|
#defaults-workspace-help.error, #schedule-editor #schedule-workspace-help.error { color: var(--danger); }
|
|
385
390
|
#session-settings-editor[hidden], #session-settings-editor [hidden] { display: none; }
|
|
@@ -55,6 +55,7 @@ async function api(path, options = {}) {
|
|
|
55
55
|
function expireAdminSession() {
|
|
56
56
|
if (state.authExpired) return;
|
|
57
57
|
state.authExpired = true;
|
|
58
|
+
invalidateSessionListRequest();
|
|
58
59
|
stopUpdatePolling();
|
|
59
60
|
window.NetizenSelect?.close();
|
|
60
61
|
// Release these modal drawers so the page's login link remains reachable.
|
|
@@ -609,7 +610,7 @@ function confirmProjectDelete(preview) {
|
|
|
609
610
|
+ "\n定时计划将被删除;后续会话清理失败也不会恢复计划。"
|
|
610
611
|
+ "\n\n原生会话、派生子会话、Codex App/CLI 历史和本地会话登记将永久删除,无法恢复。"
|
|
611
612
|
+ "\n全部会话删除确认成功后,才会删除 Project 登记;部分失败时会保留 Project 和剩余会话。"
|
|
612
|
-
+ `\n关联受管
|
|
613
|
+
+ `\n关联受管 worktree:${preview.worktreeCount || 0},${preview.deleteWorktrees ? "同时安全删除;失败项保留,不强制丢弃成果" : "保留目录,可在 worktree 页面处理;不会自动关联到同名新 Project"}。`
|
|
613
614
|
+ (preview.deleteWorktrees && preview.worktrees?.length ? `\n将删除的 checkout 根目录:\n${preview.worktrees.map((item) => `${item.id} · ${item.root}`).join("\n")}` : "")
|
|
614
615
|
+ `\n\n磁盘代码目录保留:${preview.project.cwd}`,
|
|
615
616
|
);
|
|
@@ -665,10 +666,10 @@ async function deleteProject(project, deleteWorktrees = false) {
|
|
|
665
666
|
if (result.remainingScheduledRunCount) {
|
|
666
667
|
details.push(`仍有 ${result.remainingScheduledRunCount} 条定时执行的交接或清理未确认。`);
|
|
667
668
|
}
|
|
668
|
-
if (result.deletedWorktreeCount) message += `\n已删除 ${result.deletedWorktreeCount} 个受管
|
|
669
|
+
if (result.deletedWorktreeCount) message += `\n已删除 ${result.deletedWorktreeCount} 个受管 worktree。`;
|
|
669
670
|
if (result.remainingWorktreeCount) {
|
|
670
|
-
if (result.deleteWorktrees) details.push(`仍有 ${result.remainingWorktreeCount} 个受管
|
|
671
|
-
else message += `\n已按选择保留 ${result.remainingWorktreeCount} 个受管
|
|
671
|
+
if (result.deleteWorktrees) details.push(`仍有 ${result.remainingWorktreeCount} 个受管 worktree 未安全删除,请在 worktree 页面检查。`);
|
|
672
|
+
else message += `\n已按选择保留 ${result.remainingWorktreeCount} 个受管 worktree,可在 worktree 页面处理。`;
|
|
672
673
|
}
|
|
673
674
|
return result;
|
|
674
675
|
} catch (error) {
|
|
@@ -727,7 +728,7 @@ async function loadProjects(cursor = undefined) {
|
|
|
727
728
|
cascadeLabel.className = "cascade-choice";
|
|
728
729
|
const cascade = document.createElement("input");
|
|
729
730
|
cascade.type = "checkbox";
|
|
730
|
-
cascadeLabel.append(cascade, document.createTextNode("同时删除关联受管
|
|
731
|
+
cascadeLabel.append(cascade, document.createTextNode("同时删除关联受管 worktree"));
|
|
731
732
|
actions.append(cascadeLabel);
|
|
732
733
|
actions.append(actionButton(
|
|
733
734
|
"删除 Project 及关联 Sessions", () => deleteProject(project, cascade.checked), true,
|
|
@@ -1824,24 +1825,33 @@ function locationFallback(session) {
|
|
|
1824
1825
|
|
|
1825
1826
|
function sessionLocationCell(row, session, { showIdentity = true } = {}) {
|
|
1826
1827
|
const td = document.createElement("td");
|
|
1828
|
+
td.className = "session-location";
|
|
1827
1829
|
const link = document.createElement("a");
|
|
1828
1830
|
link.className = "chat-link";
|
|
1829
|
-
link.href = session.topicOpenUrl || session.chatOpenUrl;
|
|
1830
1831
|
link.target = "_blank";
|
|
1831
1832
|
link.rel = "noopener noreferrer";
|
|
1832
|
-
link.textContent = session.chatLabelResolved
|
|
1833
|
-
? session.chatLabel
|
|
1834
|
-
: showIdentity ? locationFallback(session) : `${chatModeLabel(session.chatMode, session.scopeKind)}(名称暂不可用)`;
|
|
1835
|
-
link.title = session.topicOpenUrl
|
|
1836
|
-
? "打开飞书话题"
|
|
1837
|
-
: "打开飞书会话";
|
|
1838
1833
|
const mode = document.createElement("div");
|
|
1839
1834
|
mode.className = "meta-line";
|
|
1840
1835
|
mode.append(badge(chatModeLabel(session.chatMode, session.scopeKind)));
|
|
1841
1836
|
td.append(link, mode);
|
|
1837
|
+
updateSessionLocationCell(td, session, { showIdentity });
|
|
1842
1838
|
row.append(td);
|
|
1843
1839
|
}
|
|
1844
1840
|
|
|
1841
|
+
function updateSessionLocationCell(td, session, { showIdentity = true, loading = false } = {}) {
|
|
1842
|
+
const link = td.querySelector(".chat-link");
|
|
1843
|
+
link.href = session.topicOpenUrl || session.chatOpenUrl;
|
|
1844
|
+
link.textContent = session.chatLabelResolved
|
|
1845
|
+
? session.chatLabel
|
|
1846
|
+
: loading ? `${chatModeLabel(session.chatMode, session.scopeKind)}(名称加载中)`
|
|
1847
|
+
: showIdentity ? locationFallback(session) : `${chatModeLabel(session.chatMode, session.scopeKind)}(名称暂不可用)`;
|
|
1848
|
+
link.title = session.topicOpenUrl
|
|
1849
|
+
? "打开飞书话题"
|
|
1850
|
+
: "打开飞书会话";
|
|
1851
|
+
td.querySelector(".badge").textContent = chatModeLabel(session.chatMode, session.scopeKind);
|
|
1852
|
+
td.setAttribute("aria-busy", String(loading));
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1845
1855
|
function sessionIdentityCell(row, session) {
|
|
1846
1856
|
const td = document.createElement("td");
|
|
1847
1857
|
const title = document.createElement("strong");
|
|
@@ -2039,12 +2049,58 @@ function resetSessionFilters(kind = "session") {
|
|
|
2039
2049
|
return refresh("sessions", page);
|
|
2040
2050
|
}
|
|
2041
2051
|
|
|
2052
|
+
let pendingSessionChatLabels = null;
|
|
2053
|
+
|
|
2042
2054
|
function invalidateSessionListRequest() {
|
|
2043
2055
|
state.sessionListRequest = (state.sessionListRequest || 0) + 1;
|
|
2056
|
+
// A failed replacement read can leave these same rows on screen. Their old
|
|
2057
|
+
// enrichment must stop showing a loading placeholder when it is invalidated.
|
|
2058
|
+
pendingSessionChatLabels?.();
|
|
2059
|
+
pendingSessionChatLabels = null;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
async function loadSessionChatLabels(kind, data, page, request) {
|
|
2063
|
+
const name = kind === "side" ? "sides" : "sessions";
|
|
2064
|
+
const isCurrent = () => !state.authExpired && request === state.sessionListRequest
|
|
2065
|
+
&& state.tab === "sessions" && state.sessionTab === (kind === "side" ? "temporary" : "ordinary")
|
|
2066
|
+
&& state[name] === data && state[`${kind}Page`] === page;
|
|
2067
|
+
if (!isCurrent()) return;
|
|
2068
|
+
const body = document.querySelector(`#${name}-body`);
|
|
2069
|
+
const targets = data.items.flatMap((item, index) => item.chatLabelResolved || !item.chatId
|
|
2070
|
+
? [] : [{ item, cell: body.children[index].querySelector(".session-location") }]);
|
|
2071
|
+
if (!targets.length) return;
|
|
2072
|
+
const showIdentity = kind !== "side";
|
|
2073
|
+
const finish = () => {
|
|
2074
|
+
for (const { item, cell } of targets) updateSessionLocationCell(cell, item, { showIdentity });
|
|
2075
|
+
};
|
|
2076
|
+
pendingSessionChatLabels = finish;
|
|
2077
|
+
for (const { item, cell } of targets) updateSessionLocationCell(cell, item, { showIdentity, loading: true });
|
|
2078
|
+
try {
|
|
2079
|
+
const query = new URLSearchParams({ chatIds: [...new Set(targets.map(({ item }) => item.chatId))].join(",") });
|
|
2080
|
+
const labels = await api(`/api/v1/chat-labels?${query}`);
|
|
2081
|
+
if (!isCurrent()) return;
|
|
2082
|
+
const byChat = new Map(labels.items.map((label) => [label.chatId, label]));
|
|
2083
|
+
for (const { item } of targets) {
|
|
2084
|
+
const label = byChat.get(item.chatId);
|
|
2085
|
+
if (!label) continue;
|
|
2086
|
+
// Enrichment changes display facts only; retain exact identities, topic
|
|
2087
|
+
// links, runtime and action grants from the successful list response.
|
|
2088
|
+
for (const field of ["chatLabel", "chatLabelResolved", "chatMode", "chatType", "chatOpenUrl"]) {
|
|
2089
|
+
if (Object.hasOwn(label, field)) item[field] = label[field];
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
} catch {
|
|
2093
|
+
// Name failures are local to the location cells. Authentication expiry is
|
|
2094
|
+
// already handled by api(), and list status/freshness stay unchanged.
|
|
2095
|
+
} finally {
|
|
2096
|
+
if (isCurrent()) finish();
|
|
2097
|
+
if (pendingSessionChatLabels === finish) pendingSessionChatLabels = null;
|
|
2098
|
+
}
|
|
2044
2099
|
}
|
|
2045
2100
|
|
|
2046
2101
|
async function loadSessionPage(kind, page, render) {
|
|
2047
|
-
|
|
2102
|
+
invalidateSessionListRequest();
|
|
2103
|
+
const request = state.sessionListRequest;
|
|
2048
2104
|
const isCurrent = () => request === state.sessionListRequest;
|
|
2049
2105
|
const name = kind === "side" ? "sides" : "sessions";
|
|
2050
2106
|
setStatus("正在读取服务端事实…");
|
|
@@ -2075,6 +2131,7 @@ async function loadSessionPage(kind, page, render) {
|
|
|
2075
2131
|
}
|
|
2076
2132
|
syncPageUrl();
|
|
2077
2133
|
setStatus("已更新。");
|
|
2134
|
+
void loadSessionChatLabels(kind, data, state[`${kind}Page`], request);
|
|
2078
2135
|
return true;
|
|
2079
2136
|
} catch (error) {
|
|
2080
2137
|
if (isCurrent()) setStatus(error.message + (state[name] ? " 当前仍显示上次成功读取的结果。" : ""), true);
|
|
@@ -2278,7 +2335,8 @@ function renderSessionSettingsEditor() {
|
|
|
2278
2335
|
}
|
|
2279
2336
|
sessionSettingsInput("note").textContent = notes.filter(Boolean).join(" ");
|
|
2280
2337
|
sessionSettingsInput("note").classList.toggle("error", Boolean(editor.error));
|
|
2281
|
-
sessionSettingsInput("save").disabled = editor.loading || editor.saving || !editor.action
|
|
2338
|
+
sessionSettingsInput("save").disabled = editor.loading || editor.saving || !editor.action
|
|
2339
|
+
|| Boolean(progressCardSettingsError(editor.settings));
|
|
2282
2340
|
sessionSettingsInput("save").textContent = editor.saving ? "保存中…" : "保存";
|
|
2283
2341
|
sessionSettingsInput("cancel").disabled = editor.saving;
|
|
2284
2342
|
sessionSettingsInput("close").disabled = editor.saving;
|
|
@@ -2366,7 +2424,7 @@ function changeSessionSettings(field) {
|
|
|
2366
2424
|
async function saveSessionSettings(event) {
|
|
2367
2425
|
event.preventDefault();
|
|
2368
2426
|
const editor = sessionSettingsEditor;
|
|
2369
|
-
if (!editor || editor.loading || editor.saving || !editor.action) return;
|
|
2427
|
+
if (!editor || editor.loading || editor.saving || !editor.action || progressCardSettingsError(editor.settings)) return;
|
|
2370
2428
|
const action = editor.action;
|
|
2371
2429
|
editor.action = null;
|
|
2372
2430
|
editor.session.actions.configure = null;
|
|
@@ -2533,9 +2591,9 @@ function workspacePolicyAvailable(workspace, options, project) {
|
|
|
2533
2591
|
|
|
2534
2592
|
function workspacePolicySummary(workspace, { scheduled = false } = {}) {
|
|
2535
2593
|
if (!workspace) return "沿用原会话的实际工作目录";
|
|
2536
|
-
if (workspace.mode === "existing") return
|
|
2537
|
-
if (workspace.mode === "new") return `${scheduled ? "每次执行" : "每个新会话"}
|
|
2538
|
-
return "
|
|
2594
|
+
if (workspace.mode === "existing") return `使用已有 worktree:${workspace.worktree_id}`;
|
|
2595
|
+
if (workspace.mode === "new") return `${scheduled ? "每次执行" : "每个新会话"}新建 worktree · ${workspace.ref || "创建时 Project HEAD"}`;
|
|
2596
|
+
return "项目目录(不使用 worktree)";
|
|
2539
2597
|
}
|
|
2540
2598
|
|
|
2541
2599
|
function renderWorkspacePolicy(input, editor, { project, loading = false, scheduled = false } = {}) {
|
|
@@ -2549,8 +2607,8 @@ function renderWorkspacePolicy(input, editor, { project, loading = false, schedu
|
|
|
2549
2607
|
}
|
|
2550
2608
|
input("worktree-field").hidden = workspace.mode !== "existing";
|
|
2551
2609
|
input("workspace-ref-field").hidden = workspace.mode !== "new";
|
|
2552
|
-
scheduleSelectOptions(input("worktree"), [["", "选择受管
|
|
2553
|
-
...items.map((item) => [item.id,
|
|
2610
|
+
scheduleSelectOptions(input("worktree"), [["", "选择受管 worktree"],
|
|
2611
|
+
...items.map((item) => [item.id, `已有 worktree · ${item.branch || "detached"} · ${item.cwd}`])],
|
|
2554
2612
|
workspace.worktree_id || "");
|
|
2555
2613
|
input("worktree").required = workspace.mode === "existing";
|
|
2556
2614
|
input("workspace-ref").value = workspace.ref || "";
|
|
@@ -2563,21 +2621,21 @@ function renderWorkspacePolicy(input, editor, { project, loading = false, schedu
|
|
|
2563
2621
|
input("workspace-refs").append(option);
|
|
2564
2622
|
}
|
|
2565
2623
|
const notes = [];
|
|
2566
|
-
if (loading) notes.push("
|
|
2624
|
+
if (loading) notes.push("正在读取 worktree 选项…");
|
|
2567
2625
|
if (editor.workspaceError) notes.push(workspaceErrorMessage(editor.workspaceError));
|
|
2568
2626
|
else if (options?.isGit === false) notes.push("该 Project 不是 Git 仓库,只支持项目目录。");
|
|
2569
|
-
else if (!project) notes.push("先选择 Project
|
|
2627
|
+
else if (!project) notes.push("先选择 Project,再选择 worktree 使用方式。");
|
|
2570
2628
|
if (workspace.mode === "existing") {
|
|
2571
|
-
notes.push(scheduled ? "各次执行共享所选
|
|
2572
|
-
: "新会话共享所选
|
|
2629
|
+
notes.push(scheduled ? "各次执行共享所选 worktree 的文件和分支;资源不可用时保留计划并跳过执行。"
|
|
2630
|
+
: "新会话共享所选 worktree 的文件和分支;删除或失效后保留此配置,自动创建会话时明确报错。");
|
|
2573
2631
|
if (!loading && !workspacePolicyAvailable(workspace, options, project)) {
|
|
2574
|
-
notes.push("所选
|
|
2632
|
+
notes.push("所选 worktree 当前不可用,请重新选择;不会切回项目目录。");
|
|
2575
2633
|
}
|
|
2576
2634
|
} else if (workspace.mode === "new") {
|
|
2577
2635
|
notes.push(scheduled
|
|
2578
|
-
? "
|
|
2579
|
-
: "
|
|
2580
|
-
if (!loading && !available) notes.push("当前无法使用新建
|
|
2636
|
+
? "每次执行新建 detached worktree;该次会话的后续消息复用。留空使用执行时 Project 的 HEAD,预览和保存不创建目录。"
|
|
2637
|
+
: "每个自动创建的新会话新建 detached worktree;后续消息复用。留空使用创建时 Project 的 HEAD,保存配置不创建目录。");
|
|
2638
|
+
if (!loading && !available) notes.push("当前无法使用新建 worktree 方式,请检查 Project。");
|
|
2581
2639
|
} else notes.push(scheduled ? "每次执行创建的会话使用 Project 的项目目录。" : "新会话使用 Project 的项目目录。");
|
|
2582
2640
|
input("workspace-help").textContent = notes.join(" ");
|
|
2583
2641
|
input("workspace-help").classList.toggle("error", !loading && !workspacePolicyAvailable(workspace, options, project));
|
|
@@ -2646,7 +2704,8 @@ function renderDefaultSettings() {
|
|
|
2646
2704
|
if (editor.contextAvailable === false) notes.push("单聊不支持补齐未读上下文,请使用当前消息。");
|
|
2647
2705
|
defaultsInput("note").textContent = notes.filter(Boolean).join(" ");
|
|
2648
2706
|
defaultsInput("note").classList.toggle("error", Boolean(editor.error));
|
|
2649
|
-
defaultsInput("save").disabled = defaultsBusy || editor.loading || !editor.action || !defaultWorkspaceAvailable()
|
|
2707
|
+
defaultsInput("save").disabled = defaultsBusy || editor.loading || !editor.action || !defaultWorkspaceAvailable()
|
|
2708
|
+
|| Boolean(progressCardSettingsError(editor.settings));
|
|
2650
2709
|
defaultsInput("save").textContent = defaultsBusy ? "保存中…" : "保存";
|
|
2651
2710
|
defaultsInput("editor").setAttribute("aria-busy", String(defaultsBusy || editor.loading));
|
|
2652
2711
|
}
|
|
@@ -2864,7 +2923,8 @@ async function defaultMutation(mode, action, extra = {}) {
|
|
|
2864
2923
|
async function saveDefault(event) {
|
|
2865
2924
|
event.preventDefault();
|
|
2866
2925
|
const editor = defaultsEditor;
|
|
2867
|
-
if (!editor || editor.loading || !editor.action || defaultsBusy || !defaultWorkspaceAvailable()
|
|
2926
|
+
if (!editor || editor.loading || !editor.action || defaultsBusy || !defaultWorkspaceAvailable()
|
|
2927
|
+
|| progressCardSettingsError(editor.settings)) return;
|
|
2868
2928
|
if (editor.kind === "chat") {
|
|
2869
2929
|
editor.loading = true;
|
|
2870
2930
|
renderDefaultSettings();
|
|
@@ -3027,7 +3087,8 @@ function sessionSettingsFingerprint(settings) {
|
|
|
3027
3087
|
const turn = settings.turn_settings;
|
|
3028
3088
|
return JSON.stringify([turn ? [turn.model_id, turn.effort_id, turn.service_tier_id] : null,
|
|
3029
3089
|
settings.message_context_mode, settings.reaction_pulse_enabled,
|
|
3030
|
-
settings.progress_card_enabled, settings.completion_mention_enabled
|
|
3090
|
+
settings.progress_card_enabled, settings.completion_mention_enabled,
|
|
3091
|
+
progressCardFields.map((field) => progressCardSettings(settings)[field.replaceAll("-", "_")])]);
|
|
3031
3092
|
}
|
|
3032
3093
|
|
|
3033
3094
|
function confirmDiscardChanges(changed) {
|
|
@@ -3093,10 +3154,10 @@ function scheduleRunStatus(status) {
|
|
|
3093
3154
|
not_started: "尚未执行", expired: "已过期,未执行", missed: "已错过",
|
|
3094
3155
|
skipped_busy: "上次仍在执行,本次跳过", blocked_unknown: "上次结果待确认,本次跳过",
|
|
3095
3156
|
project_disabled: "Project 已停用,本次未执行", project_unavailable: "Project 不可用,本次未执行",
|
|
3096
|
-
workspace_unavailable: "
|
|
3097
|
-
workspace_creation_failed: "
|
|
3098
|
-
workspace_creation_unknown: "
|
|
3099
|
-
workspace_handoff_failed: "
|
|
3157
|
+
workspace_unavailable: "worktree 不可用,本次未执行",
|
|
3158
|
+
workspace_creation_failed: "worktree 创建失败,本次未执行",
|
|
3159
|
+
workspace_creation_unknown: "worktree 创建结果待确认,本次未执行",
|
|
3160
|
+
workspace_handoff_failed: "worktree 已保留,会话交接失败",
|
|
3100
3161
|
released: "调度已收尾", recovery_no_start: "服务恢复,本次未启动",
|
|
3101
3162
|
publishing_unknown: "话题投递待确认", deleted: "执行会话已删除",
|
|
3102
3163
|
initial_start_rejected: "启动被拒绝", publishing_failed: "话题发布失败",
|
|
@@ -3113,7 +3174,7 @@ function scheduleTriggerSource(source) {
|
|
|
3113
3174
|
|
|
3114
3175
|
function scheduleWorktreeReceipt(run, { details = true } = {}) {
|
|
3115
3176
|
if (!run?.worktree_id) return "";
|
|
3116
|
-
const labels = [`
|
|
3177
|
+
const labels = [`worktree:${run.worktree_id}`];
|
|
3117
3178
|
const receipt = run.worktree;
|
|
3118
3179
|
if (details && receipt) {
|
|
3119
3180
|
if (receipt.cwd) labels.push(`工作目录:${receipt.cwd}`);
|
|
@@ -3139,7 +3200,7 @@ function scheduleBlockedLabel(plan) {
|
|
|
3139
3200
|
project_unavailable: "Project 不可用", target_inactive: "原会话已切走或归档,自动暂停",
|
|
3140
3201
|
target_missing: "原会话不可用", target_mismatch: "原会话位置不匹配" }[plan.blocked_reason] || "";
|
|
3141
3202
|
const workspace = workspaceErrorMessage(plan.workspace_error)
|
|
3142
|
-
|| ([plan.blocked_reason, plan.suspended_reason].includes("workspace_unavailable") ? "
|
|
3203
|
+
|| ([plan.blocked_reason, plan.suspended_reason].includes("workspace_unavailable") ? "worktree 不可用" : "");
|
|
3143
3204
|
return [primary, workspace].filter(Boolean).join(" · ");
|
|
3144
3205
|
}
|
|
3145
3206
|
|
|
@@ -3153,7 +3214,7 @@ function scheduleInheritedWorkspace(plan) {
|
|
|
3153
3214
|
const labels = [workspace.working_cwd
|
|
3154
3215
|
? `${workspace.native_cwd_unresolved ? "已登记" : "已选"}工作目录:${workspace.working_cwd}`
|
|
3155
3216
|
: "工作目录尚未登记"];
|
|
3156
|
-
if (workspace.worktree_id) labels.push(`
|
|
3217
|
+
if (workspace.worktree_id) labels.push(`worktree:${workspace.worktree_id}`);
|
|
3157
3218
|
labels.push(workspace.native_cwd_unresolved
|
|
3158
3219
|
? "实际目录由原会话确定,本次未查询原生目录。" : "执行时沿用原会话的工作目录。");
|
|
3159
3220
|
return labels.join(" · ");
|
|
@@ -3273,8 +3334,8 @@ function validateScheduleFields({ saving = false } = {}) {
|
|
|
3273
3334
|
setScheduleFieldError("weekdays", "请至少选择一天。");
|
|
3274
3335
|
}
|
|
3275
3336
|
if (saving && !scheduleWorkspaceCanSave()) {
|
|
3276
|
-
setScheduleFieldError("workspace", scheduleEditor.workspaceLoading ? "
|
|
3277
|
-
: workspaceErrorMessage(scheduleEditor.workspaceError) || "
|
|
3337
|
+
setScheduleFieldError("workspace", scheduleEditor.workspaceLoading ? "worktree 选项仍在读取,请稍后保存。"
|
|
3338
|
+
: workspaceErrorMessage(scheduleEditor.workspaceError) || "请选择可用的 worktree 使用方式。");
|
|
3278
3339
|
}
|
|
3279
3340
|
if (scheduleFieldErrors.size) {
|
|
3280
3341
|
if (scheduleEditor?.action) showScheduleFormError("请检查标红的表单项。");
|
|
@@ -3489,7 +3550,54 @@ function resetScheduleEndOffset() {
|
|
|
3489
3550
|
|
|
3490
3551
|
function defaultScheduleSessionSettings() {
|
|
3491
3552
|
return { turn_settings: null, reaction_pulse_enabled: false, progress_card_enabled: true, completion_mention_enabled: true,
|
|
3492
|
-
message_context_mode: "current-only"
|
|
3553
|
+
message_context_mode: "current-only", progress_card_settings: {
|
|
3554
|
+
show_commentary: true, show_operations: true, show_plan: true,
|
|
3555
|
+
commentary_limit: 4, operation_limit: 8, commentary_max_chars: 160, operation_max_chars: 120,
|
|
3556
|
+
organization: "content",
|
|
3557
|
+
} };
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3560
|
+
const progressCardFields = ["show-commentary", "show-operations", "show-plan", "commentary-limit",
|
|
3561
|
+
"operation-limit", "commentary-max-chars", "operation-max-chars", "organization"];
|
|
3562
|
+
|
|
3563
|
+
function progressCardSettings(settings) {
|
|
3564
|
+
return settings.progress_card_settings || defaultScheduleSessionSettings().progress_card_settings;
|
|
3565
|
+
}
|
|
3566
|
+
|
|
3567
|
+
function progressCardSettingsError(settings) {
|
|
3568
|
+
const progress = progressCardSettings(settings);
|
|
3569
|
+
for (const [key, label, maximum] of [
|
|
3570
|
+
["commentary_limit", "进展条数", 8], ["operation_limit", "操作条数", 16],
|
|
3571
|
+
["commentary_max_chars", "进展摘要长度", 320], ["operation_max_chars", "操作摘要长度", 240],
|
|
3572
|
+
]) {
|
|
3573
|
+
if (!Number.isInteger(progress[key]) || progress[key] < 1 || progress[key] > maximum) {
|
|
3574
|
+
return `${label}必须是 1 到 ${maximum} 之间的整数。`;
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
return "";
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
function renderProgressCardSettings(input, settings) {
|
|
3581
|
+
const container = input("progress-settings");
|
|
3582
|
+
if (!container) return;
|
|
3583
|
+
const progress = progressCardSettings(settings);
|
|
3584
|
+
container.hidden = !settings.progress_card_enabled;
|
|
3585
|
+
for (const node of container.querySelectorAll("input, select")) {
|
|
3586
|
+
const field = node.id.split("-progress-").at(-1);
|
|
3587
|
+
const key = field.replaceAll("-", "_");
|
|
3588
|
+
if (field.startsWith("show-")) node.checked = progress[key];
|
|
3589
|
+
else node.value = progress[key];
|
|
3590
|
+
node.disabled = !settings.progress_card_enabled
|
|
3591
|
+
|| (field.startsWith("commentary-") && !progress.show_commentary)
|
|
3592
|
+
|| (field.startsWith("operation-") && !progress.show_operations);
|
|
3593
|
+
}
|
|
3594
|
+
for (const [kind, shown] of [["commentary", progress.show_commentary], ["operation", progress.show_operations]]) {
|
|
3595
|
+
input(`progress-${kind}-capacity`).hidden = !shown;
|
|
3596
|
+
}
|
|
3597
|
+
const error = progressCardSettingsError(settings);
|
|
3598
|
+
const note = input("progress-error");
|
|
3599
|
+
note.textContent = error;
|
|
3600
|
+
note.hidden = !error;
|
|
3493
3601
|
}
|
|
3494
3602
|
|
|
3495
3603
|
function scheduleSessionSummary(settings) {
|
|
@@ -3535,6 +3643,7 @@ function renderSessionSettingsFields(input, settings, models, contextAvailable)
|
|
|
3535
3643
|
input("reactions").checked = settings.reaction_pulse_enabled;
|
|
3536
3644
|
input("progress").checked = settings.progress_card_enabled;
|
|
3537
3645
|
input("completion-mention").checked = settings.completion_mention_enabled;
|
|
3646
|
+
renderProgressCardSettings(input, settings);
|
|
3538
3647
|
return model;
|
|
3539
3648
|
}
|
|
3540
3649
|
|
|
@@ -3552,6 +3661,13 @@ function changeSessionSettingsField(input, settings, models, field, baseTurn = n
|
|
|
3552
3661
|
else if (field === "reactions") settings.reaction_pulse_enabled = input("reactions").checked;
|
|
3553
3662
|
else if (field === "progress") settings.progress_card_enabled = input("progress").checked;
|
|
3554
3663
|
else if (field === "completion-mention") settings.completion_mention_enabled = input("completion-mention").checked;
|
|
3664
|
+
else if (field.startsWith("progress-") && progressCardFields.includes(field.slice(9))) {
|
|
3665
|
+
const key = field.slice(9).replaceAll("-", "_");
|
|
3666
|
+
const node = input(field);
|
|
3667
|
+
const value = key.startsWith("show_") ? node.checked
|
|
3668
|
+
: key === "organization" || node.value === "" ? node.value : Number(node.value);
|
|
3669
|
+
settings.progress_card_settings = { ...progressCardSettings(settings), [key]: value };
|
|
3670
|
+
}
|
|
3555
3671
|
}
|
|
3556
3672
|
|
|
3557
3673
|
function renderScheduleSessionSettings() {
|
|
@@ -4652,7 +4768,8 @@ sessionSettingsInput("drawer").addEventListener("cancel", (event) => {
|
|
|
4652
4768
|
closeSessionSettingsEditor();
|
|
4653
4769
|
});
|
|
4654
4770
|
sessionSettingsInput("editor").addEventListener("submit", saveSessionSettings);
|
|
4655
|
-
for (const field of ["model", "effort", "tier", "context", "reactions", "progress", "completion-mention"
|
|
4771
|
+
for (const field of ["model", "effort", "tier", "context", "reactions", "progress", "completion-mention",
|
|
4772
|
+
...progressCardFields.map((name) => `progress-${name}`)]) {
|
|
4656
4773
|
sessionSettingsInput(field).addEventListener("change", () => changeSessionSettings(field));
|
|
4657
4774
|
}
|
|
4658
4775
|
defaultsInput("new").addEventListener("click", () => openDefaultEditor(defaultsTab));
|
|
@@ -4679,7 +4796,8 @@ for (const field of ["workspace", "worktree"]) {
|
|
|
4679
4796
|
defaultsInput(field).addEventListener("change", () => changeDefaultWorkspace(field));
|
|
4680
4797
|
}
|
|
4681
4798
|
defaultsInput("workspace-ref").addEventListener("input", () => changeDefaultWorkspace("workspace-ref"));
|
|
4682
|
-
for (const field of ["model", "effort", "tier", "context", "reactions", "progress", "completion-mention"
|
|
4799
|
+
for (const field of ["model", "effort", "tier", "context", "reactions", "progress", "completion-mention",
|
|
4800
|
+
...progressCardFields.map((name) => `progress-${name}`)]) {
|
|
4683
4801
|
defaultsInput(field).addEventListener("change", () => changeDefaultSettings(field));
|
|
4684
4802
|
}
|
|
4685
4803
|
for (const [name, delta] of [["previous", -50], ["next", 50]]) {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
<nav class="tabs" aria-label="管理模块">
|
|
27
27
|
<a class="tab active" data-tab="projects" href="/projects" aria-current="page">Projects</a>
|
|
28
|
-
<a class="tab" data-tab="worktrees" href="/worktrees">
|
|
28
|
+
<a class="tab" data-tab="worktrees" href="/worktrees">worktree</a>
|
|
29
29
|
<a class="tab" data-tab="sessions" href="/sessions/ordinary">Sessions</a>
|
|
30
30
|
<a class="tab" data-tab="schedules" href="/schedules">定时任务</a>
|
|
31
31
|
<a class="tab" data-tab="defaults" href="/defaults">默认会话配置</a>
|
|
@@ -79,16 +79,16 @@
|
|
|
79
79
|
</dialog>
|
|
80
80
|
|
|
81
81
|
<section id="worktrees" class="panel" aria-labelledby="worktrees-heading" hidden>
|
|
82
|
-
<div class="section-head"><div><p class="eyebrow">
|
|
83
|
-
<p class="hint"
|
|
82
|
+
<div class="section-head"><div><p class="eyebrow">managed worktree</p><h2 id="worktrees-heading">worktree</h2></div><div class="actions"><button id="worktree-new" class="action">新建 worktree</button><button id="worktree-configure" class="refresh">创建配置</button><button class="refresh" data-refresh="worktrees">刷新</button></div></div>
|
|
83
|
+
<p class="hint">仅管理本实例创建的 worktree。多个会话可共享文件和分支;列表按需查询,不扫描未提交内容,也不能证明没有外部客户端使用。</p>
|
|
84
84
|
<p id="worktree-result" class="status" role="status" aria-live="polite"></p>
|
|
85
85
|
<div class="table-wrap"><table><thead><tr><th>Project / 标识</th><th>工作目录</th><th>当前状态</th><th>分支 / HEAD</th><th>关联会话</th><th>操作</th></tr></thead><tbody id="worktrees-body"></tbody></table></div>
|
|
86
|
-
<nav class="pagination" aria-label="
|
|
86
|
+
<nav class="pagination" aria-label="worktree 分页"><button id="worktrees-previous" class="next" disabled>上一页</button><span id="worktrees-page" aria-live="polite">第 1 页</span><button id="worktrees-next" class="next" disabled>下一页</button></nav>
|
|
87
87
|
</section>
|
|
88
88
|
|
|
89
89
|
<dialog id="worktree-create-drawer" class="editor-drawer" aria-labelledby="worktree-create-title">
|
|
90
90
|
<form id="worktree-create" class="card-form drawer-form workspace-form" hidden>
|
|
91
|
-
<div class="drawer-head"><div><p class="eyebrow">
|
|
91
|
+
<div class="drawer-head"><div><p class="eyebrow">worktree</p><h3 id="worktree-create-title">新建 worktree</h3></div><button id="worktree-create-close" class="drawer-close" type="button" aria-label="关闭新建 worktree 表单">×</button></div>
|
|
92
92
|
<div class="drawer-body">
|
|
93
93
|
<div class="workspace-fields">
|
|
94
94
|
<label>Project<select id="worktree-project" required><option value="">选择 Project</option></select></label>
|
|
@@ -100,19 +100,19 @@
|
|
|
100
100
|
<p id="worktree-create-note" class="hint">只检出已提交内容,不复制未提交、未跟踪或忽略文件,不执行环境初始化。不创建会话。</p>
|
|
101
101
|
<h4>当前创建配置</h4>
|
|
102
102
|
<p id="worktree-create-config" class="target-summary hint"></p>
|
|
103
|
-
<p class="hint">使用本实例已保存的配置;可在
|
|
103
|
+
<p class="hint">使用本实例已保存的配置;可在 worktree 页的“创建配置”中修改。</p>
|
|
104
104
|
<p id="worktree-create-status" class="status" role="status" aria-live="polite"></p>
|
|
105
105
|
<button id="worktree-create-check" class="drawer-cancel" type="button" hidden>刷新列表核对</button>
|
|
106
106
|
</div>
|
|
107
|
-
<div class="drawer-footer"><button id="worktree-create-cancel" class="drawer-cancel" type="button">取消</button><button id="worktree-create-submit" type="submit" disabled>创建
|
|
107
|
+
<div class="drawer-footer"><button id="worktree-create-cancel" class="drawer-cancel" type="button">取消</button><button id="worktree-create-submit" type="submit" disabled>创建 worktree</button></div>
|
|
108
108
|
</form>
|
|
109
109
|
</dialog>
|
|
110
110
|
|
|
111
111
|
<dialog id="worktree-settings-drawer" class="editor-drawer" aria-labelledby="worktree-settings-title">
|
|
112
112
|
<form id="worktree-settings" class="card-form drawer-form workspace-form" hidden>
|
|
113
|
-
<div class="drawer-head"><div><p class="eyebrow">
|
|
113
|
+
<div class="drawer-head"><div><p class="eyebrow">worktree settings</p><h3 id="worktree-settings-title">worktree 创建配置</h3></div><button id="worktree-settings-close" class="drawer-close" type="button" aria-label="关闭 worktree 创建配置">×</button></div>
|
|
114
114
|
<div class="drawer-body">
|
|
115
|
-
<p class="hint">用于本实例后续创建,包括 Admin、飞书和 Agent
|
|
115
|
+
<p class="hint">用于本实例后续创建,包括 Admin、飞书和 Agent 入口。已有 worktree 仍按原路径管理;不修改 Codex App 配置。</p>
|
|
116
116
|
<div class="workspace-fields">
|
|
117
117
|
<label>新建根目录(留空使用实例默认目录)<input id="worktree-root" maxlength="4096" aria-describedby="worktree-effective-root"></label>
|
|
118
118
|
<p id="worktree-effective-root" class="hint"></p>
|
|
@@ -221,6 +221,22 @@
|
|
|
221
221
|
<label><input id="session-settings-progress" type="checkbox">进度卡片</label>
|
|
222
222
|
<label><input id="session-settings-completion-mention" type="checkbox">结束时 @ 提醒</label>
|
|
223
223
|
</div>
|
|
224
|
+
<div id="session-settings-progress-settings" class="progress-settings" hidden>
|
|
225
|
+
<label>过程卡组织方式<select id="session-settings-progress-organization"><option value="content">按内容</option><option value="time">按时间</option></select></label>
|
|
226
|
+
<p class="session-settings-help">按时间交错显示进展与操作,任务清单固定在底部。执行状态和异常提示始终保留。</p>
|
|
227
|
+
<div class="defaults-feedback"><label><input id="session-settings-progress-show-commentary" type="checkbox">最近进展</label></div>
|
|
228
|
+
<div id="session-settings-progress-commentary-capacity" class="schedule-form-grid">
|
|
229
|
+
<label>进展条数(1–8)<input id="session-settings-progress-commentary-limit" type="number" min="1" max="8" step="1" required></label>
|
|
230
|
+
<label>进展摘要长度(1–320 字符)<input id="session-settings-progress-commentary-max-chars" type="number" min="1" max="320" step="1" required></label>
|
|
231
|
+
</div>
|
|
232
|
+
<div class="defaults-feedback"><label><input id="session-settings-progress-show-operations" type="checkbox">最近操作</label></div>
|
|
233
|
+
<div id="session-settings-progress-operation-capacity" class="schedule-form-grid">
|
|
234
|
+
<label>操作条数(1–16)<input id="session-settings-progress-operation-limit" type="number" min="1" max="16" step="1" required></label>
|
|
235
|
+
<label>操作摘要长度(1–240 字符)<input id="session-settings-progress-operation-max-chars" type="number" min="1" max="240" step="1" required></label>
|
|
236
|
+
</div>
|
|
237
|
+
<div class="defaults-feedback"><label><input id="session-settings-progress-show-plan" type="checkbox">任务清单</label></div>
|
|
238
|
+
</div>
|
|
239
|
+
<p id="session-settings-progress-error" class="progress-settings-error" role="status" hidden></p>
|
|
224
240
|
</fieldset>
|
|
225
241
|
<p id="session-settings-note" class="session-settings-help" role="status" aria-live="polite"></p>
|
|
226
242
|
</div>
|
|
@@ -271,8 +287,8 @@
|
|
|
271
287
|
<h4>会话配置</h4>
|
|
272
288
|
<div class="schedule-form-grid">
|
|
273
289
|
<label>Project<select id="defaults-project" required><option value="">选择 Project</option></select></label>
|
|
274
|
-
<label
|
|
275
|
-
<label id="defaults-worktree-field" hidden>受管
|
|
290
|
+
<label>worktree 使用方式<select id="defaults-workspace"><option value="project">项目目录(不使用 worktree)</option><option value="existing">使用已有 worktree</option><option value="new">每个新会话新建 worktree</option></select></label>
|
|
291
|
+
<label id="defaults-worktree-field" hidden>受管 worktree<select id="defaults-worktree"></select></label>
|
|
276
292
|
<label id="defaults-workspace-ref-field" hidden>起点提交 / 分支<input id="defaults-workspace-ref" list="defaults-workspace-refs" maxlength="256" placeholder="留空使用创建时 Project 的 HEAD"><datalist id="defaults-workspace-refs"></datalist></label>
|
|
277
293
|
</div>
|
|
278
294
|
<p id="defaults-workspace-help" class="defaults-field-help" role="status"></p>
|
|
@@ -288,6 +304,22 @@
|
|
|
288
304
|
<label><input id="defaults-progress" type="checkbox">进度卡片</label>
|
|
289
305
|
<label><input id="defaults-completion-mention" type="checkbox">结束时 @ 提醒</label>
|
|
290
306
|
</div>
|
|
307
|
+
<div id="defaults-progress-settings" class="progress-settings" hidden>
|
|
308
|
+
<label>过程卡组织方式<select id="defaults-progress-organization"><option value="content">按内容</option><option value="time">按时间</option></select></label>
|
|
309
|
+
<p class="session-settings-help">按时间交错显示进展与操作,任务清单固定在底部。执行状态和异常提示始终保留。</p>
|
|
310
|
+
<div class="defaults-feedback"><label><input id="defaults-progress-show-commentary" type="checkbox">最近进展</label></div>
|
|
311
|
+
<div id="defaults-progress-commentary-capacity" class="schedule-form-grid">
|
|
312
|
+
<label>进展条数(1–8)<input id="defaults-progress-commentary-limit" type="number" min="1" max="8" step="1" required></label>
|
|
313
|
+
<label>进展摘要长度(1–320 字符)<input id="defaults-progress-commentary-max-chars" type="number" min="1" max="320" step="1" required></label>
|
|
314
|
+
</div>
|
|
315
|
+
<div class="defaults-feedback"><label><input id="defaults-progress-show-operations" type="checkbox">最近操作</label></div>
|
|
316
|
+
<div id="defaults-progress-operation-capacity" class="schedule-form-grid">
|
|
317
|
+
<label>操作条数(1–16)<input id="defaults-progress-operation-limit" type="number" min="1" max="16" step="1" required></label>
|
|
318
|
+
<label>操作摘要长度(1–240 字符)<input id="defaults-progress-operation-max-chars" type="number" min="1" max="240" step="1" required></label>
|
|
319
|
+
</div>
|
|
320
|
+
<div class="defaults-feedback"><label><input id="defaults-progress-show-plan" type="checkbox">任务清单</label></div>
|
|
321
|
+
</div>
|
|
322
|
+
<p id="defaults-progress-error" class="progress-settings-error" role="status" hidden></p>
|
|
291
323
|
</fieldset>
|
|
292
324
|
<p id="defaults-note" class="defaults-field-help" role="status"></p>
|
|
293
325
|
</div>
|
|
@@ -380,8 +412,8 @@
|
|
|
380
412
|
</div>
|
|
381
413
|
<label id="schedule-project-field">Project<select id="schedule-project" required><option value="">选择 Project</option></select></label>
|
|
382
414
|
<div id="schedule-workspace-fields" class="schedule-section-fields">
|
|
383
|
-
<label
|
|
384
|
-
<label id="schedule-worktree-field" hidden>受管
|
|
415
|
+
<label>worktree 使用方式<select id="schedule-workspace"><option value="project">项目目录(不使用 worktree)</option><option value="existing">使用已有 worktree</option><option value="new">每次执行新建 worktree</option></select></label>
|
|
416
|
+
<label id="schedule-worktree-field" hidden>受管 worktree<select id="schedule-worktree"></select></label>
|
|
385
417
|
<label id="schedule-workspace-ref-field" hidden>起点提交 / 分支<input id="schedule-workspace-ref" list="schedule-workspace-refs" maxlength="256" placeholder="留空使用执行时 Project 的 HEAD"><datalist id="schedule-workspace-refs"></datalist></label>
|
|
386
418
|
<p id="schedule-workspace-help" class="schedule-field-help" role="status"></p>
|
|
387
419
|
</div>
|