netizen-cli 0.13.3__tar.gz → 0.14.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.
- {netizen_cli-0.13.3/netizen_cli.egg-info → netizen_cli-0.14.1}/PKG-INFO +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/README.md +3 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/__init__.py +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/presentation.py +11 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/admin.css +8 -2
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/admin.js +184 -49
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/index.html +77 -13
- netizen_cli-0.14.1/netizen_cli/admin/static/progress-card.js +118 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/worktrees.js +12 -12
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/web.py +81 -17
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/bindings.py +34 -15
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/controls.py +69 -21
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/defaults.py +3 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/reply.py +113 -47
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/scheduled.py +21 -21
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/workspace.py +17 -17
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel_app.py +13 -9
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/codex_runtime.py +97 -90
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/database_migrations.py +4 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/defaults/service.py +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/defaults/store.py +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/domain.py +7 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/main.py +6 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/management/chat_labels.py +152 -69
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/management/service.py +61 -28
- netizen_cli-0.14.1/netizen_cli/migrations/v18.py +132 -0
- netizen_cli-0.14.1/netizen_cli/migrations/v19.py +94 -0
- netizen_cli-0.14.1/netizen_cli/progress_card_config.py +45 -0
- netizen_cli-0.14.1/netizen_cli/progress_card_settings.py +42 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/runtime/contracts.py +4 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/schedules/service.py +7 -7
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/schedules/store.py +6 -6
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/sdk_gap_adapter.py +14 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/session_settings.py +17 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/sessions/policy.py +12 -14
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/settings.py +8 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/turn_activity.py +49 -27
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/turn_plan_observer.py +4 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/worktrees/policy.py +3 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/worktrees/service.py +15 -15
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/worktrees/settings.py +16 -16
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/worktrees/store.py +15 -15
- {netizen_cli-0.13.3 → netizen_cli-0.14.1/netizen_cli.egg-info}/PKG-INFO +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli.egg-info/SOURCES.txt +11 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/pyproject.toml +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/admin.md +42 -21
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/concepts.md +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/feedback-and-files.md +49 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/fork-side-goal.md +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/native-capabilities.md +1 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/scheduled-tasks.md +28 -26
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/session-collaboration.md +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/sessions.md +37 -31
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/user-guide.md +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_binding_scheduled_channel.py +6 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cards.py +8 -5
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_channel_app.py +7 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cli_data.py +6 -6
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_codex_runtime.py +427 -7
- netizen_cli-0.14.1/tests/test_configuration_publication.py +132 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cron_chat_targets.py +2 -2
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_database_migrations.py +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_defaults_cards.py +11 -8
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_defaults_channel.py +4 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_migration_schema_validation.py +1 -1
- netizen_cli-0.14.1/tests/test_optional_progress_card_settings_migration.py +140 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_persistent_fork_channel.py +4 -1
- netizen_cli-0.14.1/tests/test_progress_card_config.py +107 -0
- netizen_cli-0.14.1/tests/test_progress_card_entrypoints.py +213 -0
- netizen_cli-0.14.1/tests/test_progress_card_presentation.py +273 -0
- netizen_cli-0.14.1/tests/test_progress_card_settings_migration.py +177 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_cards.py +8 -8
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_service.py +4 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_workspace_cards.py +2 -2
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_workspace_migration.py +15 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_scheduled_runtime.py +12 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedules_storage.py +4 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_sdk_gap_adapter.py +25 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_session_collaboration_app.py +7 -2
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_session_defaults_migration.py +15 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_session_external_runtime.py +13 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_session_settings.py +55 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_turn_activity.py +57 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_turn_plan_observer.py +23 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_worktree_new.py +3 -3
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_worktree_service.py +25 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_worktree_storage.py +16 -1
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_worktree_tools_integration.py +6 -4
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/MANIFEST.in +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/_build.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/config.example.yaml +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/__main__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/account_rate_limits.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/auth.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/credentials.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/errors.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/feishu.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/login.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/port_config.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/queries.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/chat-picker.css +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/chat-picker.js +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/identity.js +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/login.html +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/login.js +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/static/session-access.js +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/transport.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/admin/users.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/builtin_skills.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/callbacks.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/chat_target.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/fork.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/model_info.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/pagination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/questions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/session_ids.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/status.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cards/usage.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/completion_mentions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/input_preparation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/messages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/ports.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/question_inputs.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/reactions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/reply_presenter.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/session_pages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/channel/topics.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/chat_avatars.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/chat_targets.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cli.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cli_data.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cli_packages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cli_services.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cli_setup.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cli_update.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cli_update_restore.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/cli_update_worker.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/completion_mention.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/defaults/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/defaults/models.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/deployment/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/deployment/restart_worker.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/deployment/update_executor.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/deployment/update_protocol.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/error_messages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/experience.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/feishu_app_onboarding.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/feishu_app_permissions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/feishu_links.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/git_status.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/image_inputs.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/instance.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/lark_app.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/management/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/management/blocking_io.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/management/chat_directory.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/management/coordination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/management/updates.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/markdown_images.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/mcp_transport.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/message_content.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/message_history.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/message_preparation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/message_projection.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/migrations/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/migrations/schema.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/migrations/v14.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/migrations/v15.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/migrations/v16.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/migrations/v17.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/model_settings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/package_resources.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/pagination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/partial_answers.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/projects.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/prompt_projection.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/quoted_context.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/result_images.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/runtime/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/runtime/name_writes.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/runtime/thread_naming.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/schedules/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/schedules/mcp.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/schedules/models.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/schedules/scheduler.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/service_launcher.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/session_inventory.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/sessions/__init__.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/sessions/delegation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/sessions/errors.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/sessions/mcp.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/sessions/presentation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/sessions/schema.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/sessions/service.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/skill_references.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/task_text.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/terminal_cleanup.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/thread_history.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/turn_files.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/turn_patch_children.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/user_questions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/worktrees/errors.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/worktrees/git.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli/worktrees/models.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli.egg-info/dependency_links.txt +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli.egg-info/entry_points.txt +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli.egg-info/requires.txt +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/netizen_cli.egg-info/top_level.txt +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/setup.cfg +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-lark/SKILL.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/SKILL.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/commands.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/faq.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/messages.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/skills/netizen-user-guide/references/status-and-control.md +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_account_rate_limits.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_admin_update_executor_probe.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_bindings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_channel_fixtures.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_channel_input_preparation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_chat_avatars.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_chat_target_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_check_sdk.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cli.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cli_distribution.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cli_integration.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cli_packages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cli_packaging.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cli_services.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cli_setup.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_cli_update.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_codex_sdk_capabilities.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_codex_sdk_upgrade_0161.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_codex_sdk_upgrade_0163.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_completion_mention_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_completion_mentions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_completion_topic_delivery.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_defaults_runtime.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_defaults_worktree_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_deployment.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_documentation_links.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_domain_experience.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_error_messages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_feishu_app_onboarding.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_feishu_app_permissions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_file_pagination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_fork_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_git_status.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_goal_reply_separation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_image_inputs.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_lark_app.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_lark_sdk_contract.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_main.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_markdown_images.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_message_content.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_message_history.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_message_material_inputs.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_message_preparation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_model_info_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_model_settings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_name_writes.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_pagination.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_partial_answer_delivery.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_partial_answers.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_persistent_fork_bindings.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_persistent_fork_runtime.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_child_files.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_feishu_completion_mention.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_feishu_partial_answers.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_feishu_turn_file_card.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_persistent_fork.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_python_sdk.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_scheduled_tasks.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_sdk_completion_race.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_sdk_response_recovery.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_skill_execution.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_probe_thread_naming.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_project_delete_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_project_delete_runtime.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_project_deletion_storage.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_prompt_projection.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_question_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_question_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_question_target_parity.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_quoted_context.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_release_script.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_repository_hygiene.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_result_images.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_resume_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_retired_deployment.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_runtime_resume_activation.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_runtime_thread_naming.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_card_retry.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_mcp.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_run_now.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_scope_matrix.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_workspace_service.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_schedule_workspace_storage.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_scheduled_channel.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_scheduled_worktrees.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_scheduler.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_scheduler_presenter.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_service_launcher.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_session_card_pages.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_session_defaults.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_session_id_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_session_policy.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_session_tools.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_settings_projects.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_status_cards.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_status_commands.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_task_text.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_terminal_cleanup.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_thread_history.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_thread_naming.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_turn_files.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_turn_patch_children.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_turn_patch_statistics.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_update_executor.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_usage_card.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_usage_control.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_user_guide_skill.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_user_questions.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_worktree_channel_cwd.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_worktree_git.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_worktree_runtime_cwd.py +0 -0
- {netizen_cli-0.13.3 → netizen_cli-0.14.1}/tests/test_worktree_settings.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; }
|
|
@@ -424,8 +429,9 @@ body.schedule-detail-open { overflow: hidden; }
|
|
|
424
429
|
.tab-unsaved[hidden] { display: none; }
|
|
425
430
|
.admin-users { padding: 0; margin: 0; list-style: none; }
|
|
426
431
|
.admin-users > li { display: flex; justify-content: space-between; align-items: center; gap: 16px; border-top: 1px solid var(--line); padding: 16px 0; }
|
|
427
|
-
.session-access-form { border: 0; padding: 0; }
|
|
428
|
-
|
|
432
|
+
.session-access-form, .global-card-form { border: 0; padding: 0; }
|
|
433
|
+
.global-card-form { max-width: 800px; }
|
|
434
|
+
#session-access-fields, #global-card-fields { min-width: 0; margin: 0; border: 0; padding: 0; }
|
|
429
435
|
.session-access-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); align-items: start; gap: 16px; }
|
|
430
436
|
.session-access-rule { min-width: 0; border: 1px solid var(--line); border-radius: 10px; padding: 20px; }
|
|
431
437
|
.session-access-rule h4 { margin: 0; font-size: 16px; }
|
|
@@ -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.
|
|
@@ -69,6 +70,7 @@ function expireAdminSession() {
|
|
|
69
70
|
if (notice) notice.hidden = false;
|
|
70
71
|
window.NetizenIdentity?.expire();
|
|
71
72
|
window.NetizenSessionAccess?.expire();
|
|
73
|
+
window.NetizenProgressCard?.expire();
|
|
72
74
|
window.NetizenWorktrees?.expire();
|
|
73
75
|
setStatus("登录已过期,请重新登录。", true);
|
|
74
76
|
}
|
|
@@ -609,7 +611,7 @@ function confirmProjectDelete(preview) {
|
|
|
609
611
|
+ "\n定时计划将被删除;后续会话清理失败也不会恢复计划。"
|
|
610
612
|
+ "\n\n原生会话、派生子会话、Codex App/CLI 历史和本地会话登记将永久删除,无法恢复。"
|
|
611
613
|
+ "\n全部会话删除确认成功后,才会删除 Project 登记;部分失败时会保留 Project 和剩余会话。"
|
|
612
|
-
+ `\n关联受管
|
|
614
|
+
+ `\n关联受管 worktree:${preview.worktreeCount || 0},${preview.deleteWorktrees ? "同时安全删除;失败项保留,不强制丢弃成果" : "保留目录,可在 worktree 页面处理;不会自动关联到同名新 Project"}。`
|
|
613
615
|
+ (preview.deleteWorktrees && preview.worktrees?.length ? `\n将删除的 checkout 根目录:\n${preview.worktrees.map((item) => `${item.id} · ${item.root}`).join("\n")}` : "")
|
|
614
616
|
+ `\n\n磁盘代码目录保留:${preview.project.cwd}`,
|
|
615
617
|
);
|
|
@@ -665,10 +667,10 @@ async function deleteProject(project, deleteWorktrees = false) {
|
|
|
665
667
|
if (result.remainingScheduledRunCount) {
|
|
666
668
|
details.push(`仍有 ${result.remainingScheduledRunCount} 条定时执行的交接或清理未确认。`);
|
|
667
669
|
}
|
|
668
|
-
if (result.deletedWorktreeCount) message += `\n已删除 ${result.deletedWorktreeCount} 个受管
|
|
670
|
+
if (result.deletedWorktreeCount) message += `\n已删除 ${result.deletedWorktreeCount} 个受管 worktree。`;
|
|
669
671
|
if (result.remainingWorktreeCount) {
|
|
670
|
-
if (result.deleteWorktrees) details.push(`仍有 ${result.remainingWorktreeCount} 个受管
|
|
671
|
-
else message += `\n已按选择保留 ${result.remainingWorktreeCount} 个受管
|
|
672
|
+
if (result.deleteWorktrees) details.push(`仍有 ${result.remainingWorktreeCount} 个受管 worktree 未安全删除,请在 worktree 页面检查。`);
|
|
673
|
+
else message += `\n已按选择保留 ${result.remainingWorktreeCount} 个受管 worktree,可在 worktree 页面处理。`;
|
|
672
674
|
}
|
|
673
675
|
return result;
|
|
674
676
|
} catch (error) {
|
|
@@ -727,7 +729,7 @@ async function loadProjects(cursor = undefined) {
|
|
|
727
729
|
cascadeLabel.className = "cascade-choice";
|
|
728
730
|
const cascade = document.createElement("input");
|
|
729
731
|
cascade.type = "checkbox";
|
|
730
|
-
cascadeLabel.append(cascade, document.createTextNode("同时删除关联受管
|
|
732
|
+
cascadeLabel.append(cascade, document.createTextNode("同时删除关联受管 worktree"));
|
|
731
733
|
actions.append(cascadeLabel);
|
|
732
734
|
actions.append(actionButton(
|
|
733
735
|
"删除 Project 及关联 Sessions", () => deleteProject(project, cascade.checked), true,
|
|
@@ -1824,24 +1826,33 @@ function locationFallback(session) {
|
|
|
1824
1826
|
|
|
1825
1827
|
function sessionLocationCell(row, session, { showIdentity = true } = {}) {
|
|
1826
1828
|
const td = document.createElement("td");
|
|
1829
|
+
td.className = "session-location";
|
|
1827
1830
|
const link = document.createElement("a");
|
|
1828
1831
|
link.className = "chat-link";
|
|
1829
|
-
link.href = session.topicOpenUrl || session.chatOpenUrl;
|
|
1830
1832
|
link.target = "_blank";
|
|
1831
1833
|
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
1834
|
const mode = document.createElement("div");
|
|
1839
1835
|
mode.className = "meta-line";
|
|
1840
1836
|
mode.append(badge(chatModeLabel(session.chatMode, session.scopeKind)));
|
|
1841
1837
|
td.append(link, mode);
|
|
1838
|
+
updateSessionLocationCell(td, session, { showIdentity });
|
|
1842
1839
|
row.append(td);
|
|
1843
1840
|
}
|
|
1844
1841
|
|
|
1842
|
+
function updateSessionLocationCell(td, session, { showIdentity = true, loading = false } = {}) {
|
|
1843
|
+
const link = td.querySelector(".chat-link");
|
|
1844
|
+
link.href = session.topicOpenUrl || session.chatOpenUrl;
|
|
1845
|
+
link.textContent = session.chatLabelResolved
|
|
1846
|
+
? session.chatLabel
|
|
1847
|
+
: loading ? `${chatModeLabel(session.chatMode, session.scopeKind)}(名称加载中)`
|
|
1848
|
+
: showIdentity ? locationFallback(session) : `${chatModeLabel(session.chatMode, session.scopeKind)}(名称暂不可用)`;
|
|
1849
|
+
link.title = session.topicOpenUrl
|
|
1850
|
+
? "打开飞书话题"
|
|
1851
|
+
: "打开飞书会话";
|
|
1852
|
+
td.querySelector(".badge").textContent = chatModeLabel(session.chatMode, session.scopeKind);
|
|
1853
|
+
td.setAttribute("aria-busy", String(loading));
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1845
1856
|
function sessionIdentityCell(row, session) {
|
|
1846
1857
|
const td = document.createElement("td");
|
|
1847
1858
|
const title = document.createElement("strong");
|
|
@@ -2039,12 +2050,58 @@ function resetSessionFilters(kind = "session") {
|
|
|
2039
2050
|
return refresh("sessions", page);
|
|
2040
2051
|
}
|
|
2041
2052
|
|
|
2053
|
+
let pendingSessionChatLabels = null;
|
|
2054
|
+
|
|
2042
2055
|
function invalidateSessionListRequest() {
|
|
2043
2056
|
state.sessionListRequest = (state.sessionListRequest || 0) + 1;
|
|
2057
|
+
// A failed replacement read can leave these same rows on screen. Their old
|
|
2058
|
+
// enrichment must stop showing a loading placeholder when it is invalidated.
|
|
2059
|
+
pendingSessionChatLabels?.();
|
|
2060
|
+
pendingSessionChatLabels = null;
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
async function loadSessionChatLabels(kind, data, page, request) {
|
|
2064
|
+
const name = kind === "side" ? "sides" : "sessions";
|
|
2065
|
+
const isCurrent = () => !state.authExpired && request === state.sessionListRequest
|
|
2066
|
+
&& state.tab === "sessions" && state.sessionTab === (kind === "side" ? "temporary" : "ordinary")
|
|
2067
|
+
&& state[name] === data && state[`${kind}Page`] === page;
|
|
2068
|
+
if (!isCurrent()) return;
|
|
2069
|
+
const body = document.querySelector(`#${name}-body`);
|
|
2070
|
+
const targets = data.items.flatMap((item, index) => item.chatLabelResolved || !item.chatId
|
|
2071
|
+
? [] : [{ item, cell: body.children[index].querySelector(".session-location") }]);
|
|
2072
|
+
if (!targets.length) return;
|
|
2073
|
+
const showIdentity = kind !== "side";
|
|
2074
|
+
const finish = () => {
|
|
2075
|
+
for (const { item, cell } of targets) updateSessionLocationCell(cell, item, { showIdentity });
|
|
2076
|
+
};
|
|
2077
|
+
pendingSessionChatLabels = finish;
|
|
2078
|
+
for (const { item, cell } of targets) updateSessionLocationCell(cell, item, { showIdentity, loading: true });
|
|
2079
|
+
try {
|
|
2080
|
+
const query = new URLSearchParams({ chatIds: [...new Set(targets.map(({ item }) => item.chatId))].join(",") });
|
|
2081
|
+
const labels = await api(`/api/v1/chat-labels?${query}`);
|
|
2082
|
+
if (!isCurrent()) return;
|
|
2083
|
+
const byChat = new Map(labels.items.map((label) => [label.chatId, label]));
|
|
2084
|
+
for (const { item } of targets) {
|
|
2085
|
+
const label = byChat.get(item.chatId);
|
|
2086
|
+
if (!label) continue;
|
|
2087
|
+
// Enrichment changes display facts only; retain exact identities, topic
|
|
2088
|
+
// links, runtime and action grants from the successful list response.
|
|
2089
|
+
for (const field of ["chatLabel", "chatLabelResolved", "chatMode", "chatType", "chatOpenUrl"]) {
|
|
2090
|
+
if (Object.hasOwn(label, field)) item[field] = label[field];
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
} catch {
|
|
2094
|
+
// Name failures are local to the location cells. Authentication expiry is
|
|
2095
|
+
// already handled by api(), and list status/freshness stay unchanged.
|
|
2096
|
+
} finally {
|
|
2097
|
+
if (isCurrent()) finish();
|
|
2098
|
+
if (pendingSessionChatLabels === finish) pendingSessionChatLabels = null;
|
|
2099
|
+
}
|
|
2044
2100
|
}
|
|
2045
2101
|
|
|
2046
2102
|
async function loadSessionPage(kind, page, render) {
|
|
2047
|
-
|
|
2103
|
+
invalidateSessionListRequest();
|
|
2104
|
+
const request = state.sessionListRequest;
|
|
2048
2105
|
const isCurrent = () => request === state.sessionListRequest;
|
|
2049
2106
|
const name = kind === "side" ? "sides" : "sessions";
|
|
2050
2107
|
setStatus("正在读取服务端事实…");
|
|
@@ -2075,6 +2132,7 @@ async function loadSessionPage(kind, page, render) {
|
|
|
2075
2132
|
}
|
|
2076
2133
|
syncPageUrl();
|
|
2077
2134
|
setStatus("已更新。");
|
|
2135
|
+
void loadSessionChatLabels(kind, data, state[`${kind}Page`], request);
|
|
2078
2136
|
return true;
|
|
2079
2137
|
} catch (error) {
|
|
2080
2138
|
if (isCurrent()) setStatus(error.message + (state[name] ? " 当前仍显示上次成功读取的结果。" : ""), true);
|
|
@@ -2278,7 +2336,8 @@ function renderSessionSettingsEditor() {
|
|
|
2278
2336
|
}
|
|
2279
2337
|
sessionSettingsInput("note").textContent = notes.filter(Boolean).join(" ");
|
|
2280
2338
|
sessionSettingsInput("note").classList.toggle("error", Boolean(editor.error));
|
|
2281
|
-
sessionSettingsInput("save").disabled = editor.loading || editor.saving || !editor.action
|
|
2339
|
+
sessionSettingsInput("save").disabled = editor.loading || editor.saving || !editor.action
|
|
2340
|
+
|| Boolean(progressCardSettingsError(editor.settings));
|
|
2282
2341
|
sessionSettingsInput("save").textContent = editor.saving ? "保存中…" : "保存";
|
|
2283
2342
|
sessionSettingsInput("cancel").disabled = editor.saving;
|
|
2284
2343
|
sessionSettingsInput("close").disabled = editor.saving;
|
|
@@ -2291,6 +2350,7 @@ async function loadSessionSettingsOptions() {
|
|
|
2291
2350
|
const serial = ++editor.optionsSerial;
|
|
2292
2351
|
editor.loading = true;
|
|
2293
2352
|
renderSessionSettingsEditor();
|
|
2353
|
+
const progressRead = editor.settings.progress_card_settings === null ? window.NetizenProgressCard.read() : null;
|
|
2294
2354
|
try {
|
|
2295
2355
|
const data = await api("/api/v1/sessions/options");
|
|
2296
2356
|
if (sessionSettingsEditor !== editor || serial !== editor.optionsSerial) return;
|
|
@@ -2301,6 +2361,7 @@ async function loadSessionSettingsOptions() {
|
|
|
2301
2361
|
editor.models = [];
|
|
2302
2362
|
editor.catalogError = `${error.message} 模型目录暂未读取,原选择保持不变。`;
|
|
2303
2363
|
} finally {
|
|
2364
|
+
await progressRead;
|
|
2304
2365
|
if (sessionSettingsEditor === editor && serial === editor.optionsSerial) {
|
|
2305
2366
|
editor.loading = false;
|
|
2306
2367
|
renderSessionSettingsEditor();
|
|
@@ -2366,7 +2427,7 @@ function changeSessionSettings(field) {
|
|
|
2366
2427
|
async function saveSessionSettings(event) {
|
|
2367
2428
|
event.preventDefault();
|
|
2368
2429
|
const editor = sessionSettingsEditor;
|
|
2369
|
-
if (!editor || editor.loading || editor.saving || !editor.action) return;
|
|
2430
|
+
if (!editor || editor.loading || editor.saving || !editor.action || progressCardSettingsError(editor.settings)) return;
|
|
2370
2431
|
const action = editor.action;
|
|
2371
2432
|
editor.action = null;
|
|
2372
2433
|
editor.session.actions.configure = null;
|
|
@@ -2533,9 +2594,9 @@ function workspacePolicyAvailable(workspace, options, project) {
|
|
|
2533
2594
|
|
|
2534
2595
|
function workspacePolicySummary(workspace, { scheduled = false } = {}) {
|
|
2535
2596
|
if (!workspace) return "沿用原会话的实际工作目录";
|
|
2536
|
-
if (workspace.mode === "existing") return
|
|
2537
|
-
if (workspace.mode === "new") return `${scheduled ? "每次执行" : "每个新会话"}
|
|
2538
|
-
return "
|
|
2597
|
+
if (workspace.mode === "existing") return `使用已有 worktree:${workspace.worktree_id}`;
|
|
2598
|
+
if (workspace.mode === "new") return `${scheduled ? "每次执行" : "每个新会话"}新建 worktree · ${workspace.ref || "创建时 Project HEAD"}`;
|
|
2599
|
+
return "项目目录(不使用 worktree)";
|
|
2539
2600
|
}
|
|
2540
2601
|
|
|
2541
2602
|
function renderWorkspacePolicy(input, editor, { project, loading = false, scheduled = false } = {}) {
|
|
@@ -2549,8 +2610,8 @@ function renderWorkspacePolicy(input, editor, { project, loading = false, schedu
|
|
|
2549
2610
|
}
|
|
2550
2611
|
input("worktree-field").hidden = workspace.mode !== "existing";
|
|
2551
2612
|
input("workspace-ref-field").hidden = workspace.mode !== "new";
|
|
2552
|
-
scheduleSelectOptions(input("worktree"), [["", "选择受管
|
|
2553
|
-
...items.map((item) => [item.id,
|
|
2613
|
+
scheduleSelectOptions(input("worktree"), [["", "选择受管 worktree"],
|
|
2614
|
+
...items.map((item) => [item.id, `已有 worktree · ${item.branch || "detached"} · ${item.cwd}`])],
|
|
2554
2615
|
workspace.worktree_id || "");
|
|
2555
2616
|
input("worktree").required = workspace.mode === "existing";
|
|
2556
2617
|
input("workspace-ref").value = workspace.ref || "";
|
|
@@ -2563,21 +2624,21 @@ function renderWorkspacePolicy(input, editor, { project, loading = false, schedu
|
|
|
2563
2624
|
input("workspace-refs").append(option);
|
|
2564
2625
|
}
|
|
2565
2626
|
const notes = [];
|
|
2566
|
-
if (loading) notes.push("
|
|
2627
|
+
if (loading) notes.push("正在读取 worktree 选项…");
|
|
2567
2628
|
if (editor.workspaceError) notes.push(workspaceErrorMessage(editor.workspaceError));
|
|
2568
2629
|
else if (options?.isGit === false) notes.push("该 Project 不是 Git 仓库,只支持项目目录。");
|
|
2569
|
-
else if (!project) notes.push("先选择 Project
|
|
2630
|
+
else if (!project) notes.push("先选择 Project,再选择 worktree 使用方式。");
|
|
2570
2631
|
if (workspace.mode === "existing") {
|
|
2571
|
-
notes.push(scheduled ? "各次执行共享所选
|
|
2572
|
-
: "新会话共享所选
|
|
2632
|
+
notes.push(scheduled ? "各次执行共享所选 worktree 的文件和分支;资源不可用时保留计划并跳过执行。"
|
|
2633
|
+
: "新会话共享所选 worktree 的文件和分支;删除或失效后保留此配置,自动创建会话时明确报错。");
|
|
2573
2634
|
if (!loading && !workspacePolicyAvailable(workspace, options, project)) {
|
|
2574
|
-
notes.push("所选
|
|
2635
|
+
notes.push("所选 worktree 当前不可用,请重新选择;不会切回项目目录。");
|
|
2575
2636
|
}
|
|
2576
2637
|
} else if (workspace.mode === "new") {
|
|
2577
2638
|
notes.push(scheduled
|
|
2578
|
-
? "
|
|
2579
|
-
: "
|
|
2580
|
-
if (!loading && !available) notes.push("当前无法使用新建
|
|
2639
|
+
? "每次执行新建 detached worktree;该次会话的后续消息复用。留空使用执行时 Project 的 HEAD,预览和保存不创建目录。"
|
|
2640
|
+
: "每个自动创建的新会话新建 detached worktree;后续消息复用。留空使用创建时 Project 的 HEAD,保存配置不创建目录。");
|
|
2641
|
+
if (!loading && !available) notes.push("当前无法使用新建 worktree 方式,请检查 Project。");
|
|
2581
2642
|
} else notes.push(scheduled ? "每次执行创建的会话使用 Project 的项目目录。" : "新会话使用 Project 的项目目录。");
|
|
2582
2643
|
input("workspace-help").textContent = notes.join(" ");
|
|
2583
2644
|
input("workspace-help").classList.toggle("error", !loading && !workspacePolicyAvailable(workspace, options, project));
|
|
@@ -2646,7 +2707,8 @@ function renderDefaultSettings() {
|
|
|
2646
2707
|
if (editor.contextAvailable === false) notes.push("单聊不支持补齐未读上下文,请使用当前消息。");
|
|
2647
2708
|
defaultsInput("note").textContent = notes.filter(Boolean).join(" ");
|
|
2648
2709
|
defaultsInput("note").classList.toggle("error", Boolean(editor.error));
|
|
2649
|
-
defaultsInput("save").disabled = defaultsBusy || editor.loading || !editor.action || !defaultWorkspaceAvailable()
|
|
2710
|
+
defaultsInput("save").disabled = defaultsBusy || editor.loading || !editor.action || !defaultWorkspaceAvailable()
|
|
2711
|
+
|| Boolean(progressCardSettingsError(editor.settings));
|
|
2650
2712
|
defaultsInput("save").textContent = defaultsBusy ? "保存中…" : "保存";
|
|
2651
2713
|
defaultsInput("editor").setAttribute("aria-busy", String(defaultsBusy || editor.loading));
|
|
2652
2714
|
}
|
|
@@ -2709,6 +2771,7 @@ async function loadDefaultOptions(resolveChat = false) {
|
|
|
2709
2771
|
editor.workspaceOptions = null;
|
|
2710
2772
|
editor.workspaceError = "";
|
|
2711
2773
|
renderDefaultSettings();
|
|
2774
|
+
let progressRead = editor.settings.progress_card_settings === null ? window.NetizenProgressCard.read() : null;
|
|
2712
2775
|
try {
|
|
2713
2776
|
let view = null;
|
|
2714
2777
|
if (resolveChat && chatId) {
|
|
@@ -2751,6 +2814,11 @@ async function loadDefaultOptions(resolveChat = false) {
|
|
|
2751
2814
|
editor.error = `${error.message} 请重新打开表单后操作。`;
|
|
2752
2815
|
if (resolveChat) editor.action = null;
|
|
2753
2816
|
} finally {
|
|
2817
|
+
if (defaultsEditor === editor && serial === editor.serial
|
|
2818
|
+
&& editor.settings.progress_card_settings === null && !progressRead) {
|
|
2819
|
+
progressRead = window.NetizenProgressCard.read();
|
|
2820
|
+
}
|
|
2821
|
+
await progressRead;
|
|
2754
2822
|
if (defaultsEditor === editor && serial === editor.serial) {
|
|
2755
2823
|
// Initial catalog/defaults hydration is not a user edit. Later target
|
|
2756
2824
|
// resolution must not erase the original values used for discard checks.
|
|
@@ -2864,7 +2932,8 @@ async function defaultMutation(mode, action, extra = {}) {
|
|
|
2864
2932
|
async function saveDefault(event) {
|
|
2865
2933
|
event.preventDefault();
|
|
2866
2934
|
const editor = defaultsEditor;
|
|
2867
|
-
if (!editor || editor.loading || !editor.action || defaultsBusy || !defaultWorkspaceAvailable()
|
|
2935
|
+
if (!editor || editor.loading || !editor.action || defaultsBusy || !defaultWorkspaceAvailable()
|
|
2936
|
+
|| progressCardSettingsError(editor.settings)) return;
|
|
2868
2937
|
if (editor.kind === "chat") {
|
|
2869
2938
|
editor.loading = true;
|
|
2870
2939
|
renderDefaultSettings();
|
|
@@ -3027,7 +3096,9 @@ function sessionSettingsFingerprint(settings) {
|
|
|
3027
3096
|
const turn = settings.turn_settings;
|
|
3028
3097
|
return JSON.stringify([turn ? [turn.model_id, turn.effort_id, turn.service_tier_id] : null,
|
|
3029
3098
|
settings.message_context_mode, settings.reaction_pulse_enabled,
|
|
3030
|
-
settings.progress_card_enabled, settings.completion_mention_enabled
|
|
3099
|
+
settings.progress_card_enabled, settings.completion_mention_enabled,
|
|
3100
|
+
settings.progress_card_settings === null ? null
|
|
3101
|
+
: progressCardFields.map((field) => settings.progress_card_settings[field.replaceAll("-", "_")])]);
|
|
3031
3102
|
}
|
|
3032
3103
|
|
|
3033
3104
|
function confirmDiscardChanges(changed) {
|
|
@@ -3037,6 +3108,7 @@ function confirmDiscardChanges(changed) {
|
|
|
3037
3108
|
function hasUnsavedEditors() {
|
|
3038
3109
|
return projectEditorHasChanges() || sessionSettingsHasChanges() || defaultEditorHasChanges() || scheduleEditorHasChanges()
|
|
3039
3110
|
|| Boolean(pendingScheduleDraft?.dirty) || Boolean(window.NetizenSessionAccess?.dirty())
|
|
3111
|
+
|| Boolean(window.NetizenProgressCard?.dirty())
|
|
3040
3112
|
|| Boolean(window.NetizenWorktrees?.dirty());
|
|
3041
3113
|
}
|
|
3042
3114
|
|
|
@@ -3044,7 +3116,8 @@ function hasUnsavedEditors() {
|
|
|
3044
3116
|
// existing fail-closed boundary; this helper never cancels or repeats a POST.
|
|
3045
3117
|
function confirmDiscardEditors() {
|
|
3046
3118
|
if (projectEditor?.saving || sessionSettingsEditor?.saving || defaultsBusy || (scheduleEditor && scheduleInput("fields").disabled)
|
|
3047
|
-
|| window.NetizenSessionAccess?.busy() || window.
|
|
3119
|
+
|| window.NetizenSessionAccess?.busy() || window.NetizenProgressCard?.busy()
|
|
3120
|
+
|| window.NetizenWorktrees?.busy()) return false;
|
|
3048
3121
|
if (!confirmDiscardChanges(hasUnsavedEditors())) return false;
|
|
3049
3122
|
closeProjectEditor({ confirmed: true });
|
|
3050
3123
|
closeSessionSettingsEditor({ confirmed: true });
|
|
@@ -3052,6 +3125,7 @@ function confirmDiscardEditors() {
|
|
|
3052
3125
|
if (scheduleEditor) closeScheduleEditor({ confirmed: true });
|
|
3053
3126
|
cancelScheduleSelection({ confirmed: true });
|
|
3054
3127
|
window.NetizenSessionAccess?.discard();
|
|
3128
|
+
window.NetizenProgressCard?.discard();
|
|
3055
3129
|
window.NetizenWorktrees?.discard();
|
|
3056
3130
|
return true;
|
|
3057
3131
|
}
|
|
@@ -3093,10 +3167,10 @@ function scheduleRunStatus(status) {
|
|
|
3093
3167
|
not_started: "尚未执行", expired: "已过期,未执行", missed: "已错过",
|
|
3094
3168
|
skipped_busy: "上次仍在执行,本次跳过", blocked_unknown: "上次结果待确认,本次跳过",
|
|
3095
3169
|
project_disabled: "Project 已停用,本次未执行", project_unavailable: "Project 不可用,本次未执行",
|
|
3096
|
-
workspace_unavailable: "
|
|
3097
|
-
workspace_creation_failed: "
|
|
3098
|
-
workspace_creation_unknown: "
|
|
3099
|
-
workspace_handoff_failed: "
|
|
3170
|
+
workspace_unavailable: "worktree 不可用,本次未执行",
|
|
3171
|
+
workspace_creation_failed: "worktree 创建失败,本次未执行",
|
|
3172
|
+
workspace_creation_unknown: "worktree 创建结果待确认,本次未执行",
|
|
3173
|
+
workspace_handoff_failed: "worktree 已保留,会话交接失败",
|
|
3100
3174
|
released: "调度已收尾", recovery_no_start: "服务恢复,本次未启动",
|
|
3101
3175
|
publishing_unknown: "话题投递待确认", deleted: "执行会话已删除",
|
|
3102
3176
|
initial_start_rejected: "启动被拒绝", publishing_failed: "话题发布失败",
|
|
@@ -3113,7 +3187,7 @@ function scheduleTriggerSource(source) {
|
|
|
3113
3187
|
|
|
3114
3188
|
function scheduleWorktreeReceipt(run, { details = true } = {}) {
|
|
3115
3189
|
if (!run?.worktree_id) return "";
|
|
3116
|
-
const labels = [`
|
|
3190
|
+
const labels = [`worktree:${run.worktree_id}`];
|
|
3117
3191
|
const receipt = run.worktree;
|
|
3118
3192
|
if (details && receipt) {
|
|
3119
3193
|
if (receipt.cwd) labels.push(`工作目录:${receipt.cwd}`);
|
|
@@ -3139,7 +3213,7 @@ function scheduleBlockedLabel(plan) {
|
|
|
3139
3213
|
project_unavailable: "Project 不可用", target_inactive: "原会话已切走或归档,自动暂停",
|
|
3140
3214
|
target_missing: "原会话不可用", target_mismatch: "原会话位置不匹配" }[plan.blocked_reason] || "";
|
|
3141
3215
|
const workspace = workspaceErrorMessage(plan.workspace_error)
|
|
3142
|
-
|| ([plan.blocked_reason, plan.suspended_reason].includes("workspace_unavailable") ? "
|
|
3216
|
+
|| ([plan.blocked_reason, plan.suspended_reason].includes("workspace_unavailable") ? "worktree 不可用" : "");
|
|
3143
3217
|
return [primary, workspace].filter(Boolean).join(" · ");
|
|
3144
3218
|
}
|
|
3145
3219
|
|
|
@@ -3153,7 +3227,7 @@ function scheduleInheritedWorkspace(plan) {
|
|
|
3153
3227
|
const labels = [workspace.working_cwd
|
|
3154
3228
|
? `${workspace.native_cwd_unresolved ? "已登记" : "已选"}工作目录:${workspace.working_cwd}`
|
|
3155
3229
|
: "工作目录尚未登记"];
|
|
3156
|
-
if (workspace.worktree_id) labels.push(`
|
|
3230
|
+
if (workspace.worktree_id) labels.push(`worktree:${workspace.worktree_id}`);
|
|
3157
3231
|
labels.push(workspace.native_cwd_unresolved
|
|
3158
3232
|
? "实际目录由原会话确定,本次未查询原生目录。" : "执行时沿用原会话的工作目录。");
|
|
3159
3233
|
return labels.join(" · ");
|
|
@@ -3273,8 +3347,8 @@ function validateScheduleFields({ saving = false } = {}) {
|
|
|
3273
3347
|
setScheduleFieldError("weekdays", "请至少选择一天。");
|
|
3274
3348
|
}
|
|
3275
3349
|
if (saving && !scheduleWorkspaceCanSave()) {
|
|
3276
|
-
setScheduleFieldError("workspace", scheduleEditor.workspaceLoading ? "
|
|
3277
|
-
: workspaceErrorMessage(scheduleEditor.workspaceError) || "
|
|
3350
|
+
setScheduleFieldError("workspace", scheduleEditor.workspaceLoading ? "worktree 选项仍在读取,请稍后保存。"
|
|
3351
|
+
: workspaceErrorMessage(scheduleEditor.workspaceError) || "请选择可用的 worktree 使用方式。");
|
|
3278
3352
|
}
|
|
3279
3353
|
if (scheduleFieldErrors.size) {
|
|
3280
3354
|
if (scheduleEditor?.action) showScheduleFormError("请检查标红的表单项。");
|
|
@@ -3489,7 +3563,53 @@ function resetScheduleEndOffset() {
|
|
|
3489
3563
|
|
|
3490
3564
|
function defaultScheduleSessionSettings() {
|
|
3491
3565
|
return { turn_settings: null, reaction_pulse_enabled: false, progress_card_enabled: true, completion_mention_enabled: true,
|
|
3492
|
-
message_context_mode: "current-only" };
|
|
3566
|
+
message_context_mode: "current-only", progress_card_settings: null };
|
|
3567
|
+
}
|
|
3568
|
+
|
|
3569
|
+
const progressCardFields = ["show-commentary", "show-operations", "show-plan", "commentary-limit",
|
|
3570
|
+
"operation-limit", "commentary-max-chars", "operation-max-chars", "organization"];
|
|
3571
|
+
|
|
3572
|
+
function progressCardSettings(settings) {
|
|
3573
|
+
return settings.progress_card_settings || window.NetizenProgressCard?.current();
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
function progressCardSettingsError(settings) {
|
|
3577
|
+
const progress = progressCardSettings(settings);
|
|
3578
|
+
if (!progress) return "";
|
|
3579
|
+
for (const [key, label, maximum] of [
|
|
3580
|
+
["commentary_limit", "进展条数", 8], ["operation_limit", "操作条数", 16],
|
|
3581
|
+
["commentary_max_chars", "进展摘要长度", 320], ["operation_max_chars", "操作摘要长度", 240],
|
|
3582
|
+
]) {
|
|
3583
|
+
if (!Number.isInteger(progress[key]) || progress[key] < 1 || progress[key] > maximum) {
|
|
3584
|
+
return `${label}必须是 1 到 ${maximum} 之间的整数。`;
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
return "";
|
|
3588
|
+
}
|
|
3589
|
+
|
|
3590
|
+
function renderProgressCardSettings(input, settings) {
|
|
3591
|
+
const container = input("progress-settings");
|
|
3592
|
+
if (!container) return;
|
|
3593
|
+
const progress = progressCardSettings(settings);
|
|
3594
|
+
container.hidden = !settings.progress_card_enabled;
|
|
3595
|
+
const source = input("progress-source");
|
|
3596
|
+
if (source) source.hidden = settings.progress_card_settings !== null;
|
|
3597
|
+
for (const node of container.querySelectorAll("input, select")) {
|
|
3598
|
+
const field = node.id.split("-progress-").at(-1);
|
|
3599
|
+
const key = field.replaceAll("-", "_");
|
|
3600
|
+
if (field.startsWith("show-")) node.checked = progress?.[key] || false;
|
|
3601
|
+
else node.value = progress?.[key] ?? "";
|
|
3602
|
+
node.disabled = !progress || !settings.progress_card_enabled
|
|
3603
|
+
|| (field.startsWith("commentary-") && !progress.show_commentary)
|
|
3604
|
+
|| (field.startsWith("operation-") && !progress.show_operations);
|
|
3605
|
+
}
|
|
3606
|
+
for (const [kind, shown] of [["commentary", progress?.show_commentary], ["operation", progress?.show_operations]]) {
|
|
3607
|
+
input(`progress-${kind}-capacity`).hidden = !shown;
|
|
3608
|
+
}
|
|
3609
|
+
const error = progress ? progressCardSettingsError(settings) : "读取全局配置后可编辑过程卡细项。";
|
|
3610
|
+
const note = input("progress-error");
|
|
3611
|
+
note.textContent = error;
|
|
3612
|
+
note.hidden = !error;
|
|
3493
3613
|
}
|
|
3494
3614
|
|
|
3495
3615
|
function scheduleSessionSummary(settings) {
|
|
@@ -3535,6 +3655,7 @@ function renderSessionSettingsFields(input, settings, models, contextAvailable)
|
|
|
3535
3655
|
input("reactions").checked = settings.reaction_pulse_enabled;
|
|
3536
3656
|
input("progress").checked = settings.progress_card_enabled;
|
|
3537
3657
|
input("completion-mention").checked = settings.completion_mention_enabled;
|
|
3658
|
+
renderProgressCardSettings(input, settings);
|
|
3538
3659
|
return model;
|
|
3539
3660
|
}
|
|
3540
3661
|
|
|
@@ -3552,6 +3673,15 @@ function changeSessionSettingsField(input, settings, models, field, baseTurn = n
|
|
|
3552
3673
|
else if (field === "reactions") settings.reaction_pulse_enabled = input("reactions").checked;
|
|
3553
3674
|
else if (field === "progress") settings.progress_card_enabled = input("progress").checked;
|
|
3554
3675
|
else if (field === "completion-mention") settings.completion_mention_enabled = input("completion-mention").checked;
|
|
3676
|
+
else if (field.startsWith("progress-") && progressCardFields.includes(field.slice(9))) {
|
|
3677
|
+
const progress = progressCardSettings(settings);
|
|
3678
|
+
if (!progress) return;
|
|
3679
|
+
const key = field.slice(9).replaceAll("-", "_");
|
|
3680
|
+
const node = input(field);
|
|
3681
|
+
const value = key.startsWith("show_") ? node.checked
|
|
3682
|
+
: key === "organization" || node.value === "" ? node.value : Number(node.value);
|
|
3683
|
+
settings.progress_card_settings = { ...progress, [key]: value };
|
|
3684
|
+
}
|
|
3555
3685
|
}
|
|
3556
3686
|
|
|
3557
3687
|
function renderScheduleSessionSettings() {
|
|
@@ -4488,8 +4618,9 @@ async function refresh(tab, cursor = undefined) {
|
|
|
4488
4618
|
if (tab === "schedules" && await loadSchedules(cursor) === false) return false;
|
|
4489
4619
|
if (tab === "defaults") await loadDefaults();
|
|
4490
4620
|
if (tab === "system") {
|
|
4491
|
-
const results = await Promise.all([window.NetizenIdentity.loadUsers(), window.NetizenSessionAccess?.load()
|
|
4492
|
-
|
|
4621
|
+
const results = await Promise.all([window.NetizenIdentity.loadUsers(), window.NetizenSessionAccess?.load(),
|
|
4622
|
+
window.NetizenProgressCard?.load()]);
|
|
4623
|
+
if (results.includes(false)) return false;
|
|
4493
4624
|
}
|
|
4494
4625
|
if (state.authExpired) return false;
|
|
4495
4626
|
if (isCurrentView()) setStatus("已更新。");
|
|
@@ -4527,7 +4658,7 @@ function selectSystemTab(name) {
|
|
|
4527
4658
|
if (state.authExpired || state.systemTab === name) return;
|
|
4528
4659
|
window.NetizenSelect?.close();
|
|
4529
4660
|
if (state.systemTab === "admins") window.NetizenIdentity?.suspendSelector();
|
|
4530
|
-
else window.NetizenSessionAccess?.closePickers();
|
|
4661
|
+
else if (state.systemTab === "access") window.NetizenSessionAccess?.closePickers();
|
|
4531
4662
|
state.systemTab = name;
|
|
4532
4663
|
for (const button of document.querySelectorAll("[data-system-tab]")) {
|
|
4533
4664
|
const selected = button.dataset.systemTab === name;
|
|
@@ -4594,8 +4725,10 @@ for (const tab of document.querySelectorAll("[data-system-tab]")) {
|
|
|
4594
4725
|
tab.addEventListener("keydown", (event) => {
|
|
4595
4726
|
if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) return;
|
|
4596
4727
|
event.preventDefault();
|
|
4597
|
-
const
|
|
4598
|
-
|
|
4728
|
+
const names = [...document.querySelectorAll("[data-system-tab]")].map((button) => button.dataset.systemTab);
|
|
4729
|
+
const index = names.indexOf(tab.dataset.systemTab);
|
|
4730
|
+
const name = event.key === "Home" ? names[0] : event.key === "End" ? names.at(-1)
|
|
4731
|
+
: names[(index + (event.key === "ArrowRight" ? 1 : names.length - 1)) % names.length];
|
|
4599
4732
|
selectSystemTab(name);
|
|
4600
4733
|
document.querySelector(`#system-tab-${name}`).focus();
|
|
4601
4734
|
});
|
|
@@ -4652,7 +4785,8 @@ sessionSettingsInput("drawer").addEventListener("cancel", (event) => {
|
|
|
4652
4785
|
closeSessionSettingsEditor();
|
|
4653
4786
|
});
|
|
4654
4787
|
sessionSettingsInput("editor").addEventListener("submit", saveSessionSettings);
|
|
4655
|
-
for (const field of ["model", "effort", "tier", "context", "reactions", "progress", "completion-mention"
|
|
4788
|
+
for (const field of ["model", "effort", "tier", "context", "reactions", "progress", "completion-mention",
|
|
4789
|
+
...progressCardFields.map((name) => `progress-${name}`)]) {
|
|
4656
4790
|
sessionSettingsInput(field).addEventListener("change", () => changeSessionSettings(field));
|
|
4657
4791
|
}
|
|
4658
4792
|
defaultsInput("new").addEventListener("click", () => openDefaultEditor(defaultsTab));
|
|
@@ -4679,7 +4813,8 @@ for (const field of ["workspace", "worktree"]) {
|
|
|
4679
4813
|
defaultsInput(field).addEventListener("change", () => changeDefaultWorkspace(field));
|
|
4680
4814
|
}
|
|
4681
4815
|
defaultsInput("workspace-ref").addEventListener("input", () => changeDefaultWorkspace("workspace-ref"));
|
|
4682
|
-
for (const field of ["model", "effort", "tier", "context", "reactions", "progress", "completion-mention"
|
|
4816
|
+
for (const field of ["model", "effort", "tier", "context", "reactions", "progress", "completion-mention",
|
|
4817
|
+
...progressCardFields.map((name) => `progress-${name}`)]) {
|
|
4683
4818
|
defaultsInput(field).addEventListener("change", () => changeDefaultSettings(field));
|
|
4684
4819
|
}
|
|
4685
4820
|
for (const [name, delta] of [["previous", -50], ["next", 50]]) {
|