boss-agent-cli 3.0.0__tar.gz → 3.1.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.
- boss_agent_cli-3.1.0/.coderabbit.yaml +64 -0
- boss_agent_cli-3.1.0/.github/dependabot.yml +31 -0
- boss_agent_cli-3.1.0/.github/labeler.yml +25 -0
- boss_agent_cli-3.1.0/.github/workflows/ci.yml +91 -0
- boss_agent_cli-3.1.0/.github/workflows/dependabot-auto-merge.yml +29 -0
- boss_agent_cli-3.1.0/.github/workflows/labeler.yml +25 -0
- boss_agent_cli-3.1.0/.github/workflows/stale.yml +38 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.gitignore +3 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.pre-commit-config.yaml +2 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/CHANGELOG.md +79 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/CONTRIBUTING.en.md +4 -4
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/CONTRIBUTING.md +4 -4
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/CONTRIBUTORS.svg +7 -7
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/PKG-INFO +22 -15
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/README.en.md +14 -12
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/README.md +13 -11
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/index.html +48 -40
- boss_agent_cli-3.1.0/demo/keynote-animation/.gitignore +7 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/README.en.md +63 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/README.md +63 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/assets/Inter-var.woff +0 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/assets/LICENSES.md +15 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/assets/NotoSansSC-500.woff +0 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/assets/NotoSansSC-800.woff +0 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/assets/OFL.txt +94 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/directions.html +14 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/eras.js +6 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/export_showcase.py +56 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/index.html +17 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/output/soundtrack.m4a +0 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/player.js +38 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/render.py +194 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/render_directions.py +48 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/scenes.js +138 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/score.py +133 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/storyboard.json +22 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/verify.py +153 -0
- boss_agent_cli-3.1.0/demo/keynote-animation/visuals.js +89 -0
- boss_agent_cli-3.1.0/demo/llms.txt +36 -0
- boss_agent_cli-3.1.0/demo/promo-showcase/README.en.md +32 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/promo-showcase/README.md +7 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/promo-showcase/scenes.jsx +1 -1
- boss_agent_cli-3.1.0/demo/showcase/boss-agent-cli-showcase-thumb.jpg +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/agent-quickstart.en.md +12 -4
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/agent-quickstart.md +12 -4
- boss_agent_cli-3.1.0/docs/assets/logo.png +0 -0
- boss_agent_cli-3.1.0/docs/assets/star-history-dark.svg +44 -0
- boss_agent_cli-3.1.0/docs/assets/star-history.svg +44 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/capability-matrix.en.md +3 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/capability-matrix.md +3 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/commands.en.md +94 -8
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/commands.md +93 -7
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/integrations/cursor.md +1 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/integrations/python-sdk.md +1 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/integrations/windsurf.md +1 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/maintainer/branch-protection.md +7 -5
- boss_agent_cli-3.1.0/docs/maintainer/release-checklist.md +83 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/marketing/en-launch-story.md +1 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/marketing/zh-launch-story.md +1 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/platform-risk.en.md +69 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/platform-risk.md +58 -0
- boss_agent_cli-3.1.0/docs/research/upstream-antidetection-evaluation-2026-10-29.md +72 -0
- boss_agent_cli-3.1.0/docs/research/zhipin-cdp-free-read-path-2026-10-29.md +248 -0
- boss_agent_cli-3.1.0/docs/research/zhipin-request-identity-2026-10-29.md +263 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/troubleshooting.en.md +53 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/troubleshooting.md +44 -1
- boss_agent_cli-3.1.0/llms.txt +35 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/mcp-server/README.en.md +2 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/mcp-server/README.md +2 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/pyproject.toml +29 -7
- boss_agent_cli-3.1.0/scripts/README.md +61 -0
- boss_agent_cli-3.1.0/scripts/_release_probe.py +152 -0
- boss_agent_cli-3.1.0/scripts/capture_request_identity.py +195 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/scripts/package_portable.py +1 -1
- boss_agent_cli-3.1.0/scripts/verify_release.py +317 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/__init__.py +1 -1
- boss_agent_cli-3.1.0/src/boss_agent_cli/api/_base_client.py +513 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/boss.yaml +67 -11
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/browser_client.py +601 -55
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/browser_source.py +19 -0
- boss_agent_cli-3.1.0/src/boss_agent_cli/api/cdp_risk_lock.py +176 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/client.py +119 -48
- boss_agent_cli-3.1.0/src/boss_agent_cli/api/egress.py +193 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/endpoints.py +2 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/endpoints_loader.py +24 -2
- boss_agent_cli-3.1.0/src/boss_agent_cli/api/httpx_helpers.py +143 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/models.py +34 -1
- boss_agent_cli-3.1.0/src/boss_agent_cli/api/proxy.py +86 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/recruiter.yaml +76 -6
- boss_agent_cli-3.1.0/src/boss_agent_cli/api/recruiter_client.py +1692 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/recruiter_endpoints.py +2 -0
- boss_agent_cli-3.1.0/src/boss_agent_cli/api/recruiter_resume.py +274 -0
- boss_agent_cli-3.1.0/src/boss_agent_cli/api/request_budget.py +418 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/throttle.py +19 -14
- boss_agent_cli-3.1.0/src/boss_agent_cli/api/zhipin_errors.py +154 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/auth/browser.py +277 -122
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/auth/cookie_extract.py +7 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/auth/manager.py +129 -10
- boss_agent_cli-3.1.0/src/boss_agent_cli/auth/page_identity.py +102 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/auth/qr_login.py +36 -7
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/adapters.py +2 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/boss_adapter.py +42 -9
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/execution.py +23 -7
- boss_agent_cli-3.1.0/src/boss_agent_cli/automation/runner.py +125 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/safety.py +35 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/storage.py +93 -7
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/cache/store.py +68 -14
- boss_agent_cli-3.1.0/src/boss_agent_cli/commands/_doctor_checks.py +218 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/_login_errors.py +1 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/_platform.py +2 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/_recruiter_platform.py +2 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/agent.py +24 -10
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/apply.py +6 -7
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/clean.py +36 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/config_cmd.py +27 -13
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/crawl.py +19 -5
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/detail.py +7 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/doctor.py +104 -36
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/favorites.py +4 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/greet.py +2 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/login.py +10 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/preset.py +11 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recommend.py +12 -4
- boss_agent_cli-3.1.0/src/boss_agent_cli/commands/recruiter/chat.py +542 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/jobs.py +3 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/resume.py +5 -1
- boss_agent_cli-3.1.0/src/boss_agent_cli/commands/recruiter/whoami.py +67 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/register.py +2 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/schema.py +10 -6
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/search.py +70 -10
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/shortlist.py +5 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/show.py +3 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/status.py +5 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/watch.py +22 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/wizard.py +2 -1
- boss_agent_cli-3.1.0/src/boss_agent_cli/config.py +97 -0
- boss_agent_cli-3.1.0/src/boss_agent_cli/crawler/controls.py +21 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/crawler/service.py +268 -82
- boss_agent_cli-3.1.0/src/boss_agent_cli/crawler/transport.py +543 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/display.py +159 -27
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/index_cache.py +1 -0
- boss_agent_cli-3.1.0/src/boss_agent_cli/main.py +289 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/mcp_args.py +11 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/mcp_server.py +148 -16
- boss_agent_cli-3.1.0/src/boss_agent_cli/mcp_tools.py +88 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/output.py +64 -7
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/platforms/base.py +10 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/platforms/factory.py +3 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/platforms/recruiter_base.py +8 -4
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/platforms/zhipin.py +20 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/platforms/zhipin_recruiter.py +51 -15
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/schema/data.py +134 -22
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/schema/error_codes.py +33 -3
- boss_agent_cli-3.1.0/src/boss_agent_cli/schema/formats.py +162 -0
- boss_agent_cli-3.1.0/src/boss_agent_cli/schema/tool_catalog.py +1021 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/search_filters.py +497 -73
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/job_card.py +2 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/job_export.py +1 -1
- boss_agent_cli-3.1.0/src/boss_agent_cli/services/job_identity.py +24 -0
- boss_agent_cli-3.1.0/src/boss_agent_cli/services/recruiter_identity.py +52 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/resume_parser.py +3 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/actions.py +42 -6
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/prompts.py +5 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/renderer.py +5 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/runner.py +62 -6
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/store.py +3 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_agent_crawl.py +3 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_agent_docs.py +2 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_api.py +35 -13
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_api_client_methods.py +67 -9
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_api_client_retry.py +41 -54
- boss_agent_cli-3.1.0/tests/test_api_egress.py +177 -0
- boss_agent_cli-3.1.0/tests/test_api_httpx_helpers.py +170 -0
- boss_agent_cli-3.1.0/tests/test_api_proxy.py +65 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_auth_browser.py +9 -2
- boss_agent_cli-3.1.0/tests/test_auth_page_identity.py +81 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_browser_client.py +128 -15
- boss_agent_cli-3.1.0/tests/test_browser_client_account_guard.py +83 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_browser_source.py +6 -3
- boss_agent_cli-3.1.0/tests/test_cdp_request_safety.py +497 -0
- boss_agent_cli-3.1.0/tests/test_cdp_risk_lock_coverage.py +313 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_cli_invariants.py +49 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_commands.py +4 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_compliance.py +3 -1
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_config_cmd.py +34 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_cookie_extract_regression.py +33 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_crawl.py +65 -24
- boss_agent_cli-3.1.0/tests/test_dash_prefixed_security_id.py +53 -0
- boss_agent_cli-3.1.0/tests/test_default_headers_consistency.py +107 -0
- boss_agent_cli-3.1.0/tests/test_dependency_constraints.py +61 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_display.py +56 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_doctor_extended.py +216 -14
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_endpoints_loader.py +22 -1
- boss_agent_cli-3.1.0/tests/test_exit_codes.py +96 -0
- boss_agent_cli-3.1.0/tests/test_httpx_accept_encoding.py +56 -0
- boss_agent_cli-3.1.0/tests/test_httpx_http2.py +69 -0
- boss_agent_cli-3.1.0/tests/test_httpx_only_channel.py +86 -0
- boss_agent_cli-3.1.0/tests/test_httpx_only_hint.py +29 -0
- boss_agent_cli-3.1.0/tests/test_login_stage_messaging.py +29 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_mcp_handler_registration.py +41 -5
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_mcp_server.py +2 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_new_commands.py +3 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_open_source_docs.py +38 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_output.py +84 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_platform_base.py +7 -2
- boss_agent_cli-3.1.0/tests/test_recruiter_chat_summary.py +279 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_recruiter_client_retry.py +49 -37
- boss_agent_cli-3.1.0/tests/test_recruiter_exchange_availability.py +251 -0
- boss_agent_cli-3.1.0/tests/test_recruiter_exchange_confirm.py +424 -0
- boss_agent_cli-3.1.0/tests/test_recruiter_identity.py +109 -0
- boss_agent_cli-3.1.0/tests/test_recruiter_jobs_list.py +106 -0
- boss_agent_cli-3.1.0/tests/test_recruiter_last_msg_batching.py +154 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_recruiter_recommendations_and_read.py +17 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_recruiter_resume_attachments.py +7 -0
- boss_agent_cli-3.1.0/tests/test_release_verification.py +320 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_schema_contract.py +8 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_schema_formats.py +32 -8
- boss_agent_cli-3.1.0/tests/test_schema_mcp_tools.py +99 -0
- boss_agent_cli-3.1.0/tests/test_search_active_filter.py +322 -0
- boss_agent_cli-3.1.0/tests/test_search_active_request_volume.py +419 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_search_pipeline.py +158 -0
- boss_agent_cli-3.1.0/tests/test_security_page_details.py +37 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_shortlist.py +2 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_throttle.py +3 -3
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_wizard.py +75 -2
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/uv.lock +563 -579
- boss_agent_cli-3.0.0/demo/llms.txt +0 -28
- boss_agent_cli-3.0.0/demo/showcase/boss-agent-cli-showcase-thumb.jpg +0 -0
- boss_agent_cli-3.0.0/docs/assets/star-history-dark.svg +0 -43
- boss_agent_cli-3.0.0/docs/assets/star-history.svg +0 -43
- boss_agent_cli-3.0.0/docs/maintainer/release-checklist.md +0 -65
- boss_agent_cli-3.0.0/scripts/README.md +0 -40
- boss_agent_cli-3.0.0/src/boss_agent_cli/api/_base_client.py +0 -222
- boss_agent_cli-3.0.0/src/boss_agent_cli/api/httpx_helpers.py +0 -65
- boss_agent_cli-3.0.0/src/boss_agent_cli/api/recruiter_client.py +0 -808
- boss_agent_cli-3.0.0/src/boss_agent_cli/api/recruiter_resume.py +0 -113
- boss_agent_cli-3.0.0/src/boss_agent_cli/api/zhipin_errors.py +0 -48
- boss_agent_cli-3.0.0/src/boss_agent_cli/automation/runner.py +0 -120
- boss_agent_cli-3.0.0/src/boss_agent_cli/commands/_doctor_checks.py +0 -134
- boss_agent_cli-3.0.0/src/boss_agent_cli/commands/recruiter/chat.py +0 -281
- boss_agent_cli-3.0.0/src/boss_agent_cli/config.py +0 -59
- boss_agent_cli-3.0.0/src/boss_agent_cli/crawler/transport.py +0 -499
- boss_agent_cli-3.0.0/src/boss_agent_cli/main.py +0 -125
- boss_agent_cli-3.0.0/src/boss_agent_cli/mcp_tools.py +0 -1033
- boss_agent_cli-3.0.0/src/boss_agent_cli/schema/formats.py +0 -128
- boss_agent_cli-3.0.0/tests/test_api_httpx_helpers.py +0 -84
- boss_agent_cli-3.0.0/tests/test_schema_mcp_tools.py +0 -42
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.codecov.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.devcontainer/devcontainer.json +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.dockerignore +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.gitattributes +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/CODEOWNERS +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/ISSUE_TEMPLATE/documentation.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/social-preview.png +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/workflows/pages.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/workflows/release.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/workflows/star-history.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/workflows/triage-cleanup.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/.github/workflows/update-contributors.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/CODE_OF_CONDUCT.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/Dockerfile +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/LICENSE +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/ROADMAP.en.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/ROADMAP.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/SECURITY.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/demo-en.tape +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/demo-zh.tape +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/demo_showcase.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/demo_showcase_en.py +0 -0
- {boss_agent_cli-3.0.0/docs → boss_agent_cli-3.1.0/demo/keynote-animation}/assets/logo.png +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/promo-showcase/animations.jsx +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/promo-showcase/app.jsx +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/promo-showcase/boss-agent-cli-promo.html +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/demo/promo-showcase/lib.jsx +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docker-compose.yml +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/adr/0001-default-low-risk-assistance-mode.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/adr/0002-explicit-research-operating-mode.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/agent-hosts.en.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/agent-hosts.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/getting-started.en.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/getting-started.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/integrations/ai-models.en.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/integrations/ai-models.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/integrations/claude-code.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/integrations/codex.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/integrations/docker.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/integrations/shell-agent.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/maintainer/labels.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/marketing/awesome-submissions.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/marketing/promotion-article.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/platform-abstraction.en.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/platform-abstraction.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/readme-badge-policy.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/research/platforms/README.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/research/platforms/lagou.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/research/platforms/liepin.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/research/platforms/zhipin.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/docs/smoke-testing.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/evals/README.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/evals/results/20260624T103356Z-fixture.json +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/evals/results/README.md +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/evals/results/necessary-conditions-2026-06-24.json +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/evals/run_eval.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/evals/scenarios.json +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/examples/opencode/opencode.json +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/glama.json +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/mcp-server/server.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/scripts/probe_recruiter_chat_frontend.ps1 +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/scripts/probe_recruiter_chat_frontend.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/scripts/quality_baseline.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/scripts/smoke_p0.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/scripts/update_contributors.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/ai/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/ai/config.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/ai/local_models.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/ai/prompts.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/ai/service.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/api/browser_urls.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/auth/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/auth/curl_import.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/auth/health.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/auth/token_store.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/config.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/decision.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/events.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/mock_adapter.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/models.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/reply_ai.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/automation/scoring.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/cache/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/chat_summary.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/_contact_lookup.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/ai_cmd.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/ai_local.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/chat.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/chat_summary.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/chatmsg.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/cities.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/digest.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/exchange.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/export.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/history.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/interviews.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/logout.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/mark.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/me.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/pipeline.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/platforms.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/accept_resume.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/applications.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/candidates.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/download_resume.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/recommendations.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/reply.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/recruiter/request_resume.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/resume_cmd.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/commands/stats.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/compliance.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/crawler/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/crawler/exporter.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/crawler/hooks.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/crawler/operations.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/digest.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/hooks.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/match_score.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/pipeline_state.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/platforms/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/py.typed +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/resume/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/resume/export.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/resume/models.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/resume/store.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/resume/templates.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/schema/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/schema/availability.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/browser_runtime.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/chat_export.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/chat_snapshot.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/chat_utils.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/contact_lookup.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/services/friend_list_pages.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/__init__.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/catalog.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/live_crawl.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/models.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/src/boss_agent_cli/wizard/preflight.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/conftest.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/fixtures/favorites_card.json +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_agent_automation.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_agent_automation_cross_validation.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_agent_error_contract.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_agent_host_examples.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_commands.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_config.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_config_cmd.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_cover_letter.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_fit.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_local.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_prompts.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_resume_optimize.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_service.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_ai_suggest_keywords.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_apply.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_auth.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_auth_and_login_extended.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_auth_manager_extended.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_auth_manager_flow.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_cache.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_cache_extended.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_chat_export_extended.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_chat_snapshot_extended.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_chat_summary.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_chat_summary_command.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_chatmsg_extended.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_chatmsg_uid_flow.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_clean_cmd.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_contact_lookup.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_coverage_second_sprint.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_crawl_cli.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_curl_auth_import.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_digest.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_digest_command.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_eval_harness.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_export_extended.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_favorites.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_greet_detail_extended.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_greet_extended.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_hooks.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_index_cache.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_job_card_browser.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_job_item_lid.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_match_score.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_mcp_server_protocol.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_pipeline_commands.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_pipeline_state.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_platform_cli.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_platform_not_supported.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_platforms_cmd.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_portable_package.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_preset.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_probe_script.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_public_api.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_qr_login.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_quality_baseline.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_recruiter_safety_regressions.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_resume_commands.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_resume_export.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_resume_import_compat.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_resume_init_hints.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_resume_models.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_resume_store.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_resume_templates.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_search_filters.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_smoke_p0.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_stats.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_system_proxy.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_watch.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_watch_run_all.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_welfare_filter.py +0 -0
- {boss_agent_cli-3.0.0 → boss_agent_cli-3.1.0}/tests/test_zhipin_errors.py +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
|
2
|
+
# CodeRabbit 配置:安静模式,只做中文审查与概要,不发诗、不发装饰性内容。
|
|
3
|
+
language: zh-CN
|
|
4
|
+
early_access: false
|
|
5
|
+
reviews:
|
|
6
|
+
profile: chill
|
|
7
|
+
request_changes_workflow: false
|
|
8
|
+
high_level_summary: true
|
|
9
|
+
review_status: false
|
|
10
|
+
review_details: false
|
|
11
|
+
poem: false
|
|
12
|
+
in_progress_fortune: false
|
|
13
|
+
sequence_diagrams: false
|
|
14
|
+
estimate_code_review_effort: false
|
|
15
|
+
related_prs: false
|
|
16
|
+
suggested_labels: false
|
|
17
|
+
suggested_reviewers: false
|
|
18
|
+
collapse_walkthrough: true
|
|
19
|
+
auto_review:
|
|
20
|
+
enabled: true
|
|
21
|
+
drafts: false
|
|
22
|
+
ignore_title_keywords:
|
|
23
|
+
- "WIP"
|
|
24
|
+
- "[skip review]"
|
|
25
|
+
path_filters:
|
|
26
|
+
- "!docs/assets/star-history*.svg"
|
|
27
|
+
- "!CONTRIBUTORS.svg"
|
|
28
|
+
- "!demo/**/*.tape"
|
|
29
|
+
- "!**/package-lock.json"
|
|
30
|
+
- "!**/*.lock"
|
|
31
|
+
- "!**/go.sum"
|
|
32
|
+
- "!**/*.min.js"
|
|
33
|
+
- "!**/*.png"
|
|
34
|
+
- "!**/*.jpg"
|
|
35
|
+
- "!**/*.jpeg"
|
|
36
|
+
- "!**/*.gif"
|
|
37
|
+
- "!**/*.webp"
|
|
38
|
+
- "!**/*.ico"
|
|
39
|
+
- "!**/*.mp4"
|
|
40
|
+
- "!**/*.m4a"
|
|
41
|
+
- "!**/*.woff"
|
|
42
|
+
- "!**/*.woff2"
|
|
43
|
+
- "!**/*.ttf"
|
|
44
|
+
path_instructions:
|
|
45
|
+
- path: "src/boss_agent_cli/**"
|
|
46
|
+
instructions: |
|
|
47
|
+
这是 BOSS 直聘的 Agent CLI,平台风控很敏感,评审时重点看:
|
|
48
|
+
- 命令输出必须守 JSON 信封契约:stdout 只输出 JSON 信封(ok / data / error / hints),日志与进度走 stderr;出错要带 error.code、recoverable、recovery_action。
|
|
49
|
+
- CDP / 浏览器通道下不要改用 httpx 直连平台接口;平台请求只能串行,不能并发或批量并行。
|
|
50
|
+
- 遇到风控码 36/37 必须立即停止并返回可恢复错误,不能重试或绕过。
|
|
51
|
+
- 不得新增任何会主动向真实候选人/招聘方发消息、打招呼、交换联系方式的默认行为;这类动作必须由用户显式发起。
|
|
52
|
+
- 不要引入运行时遥测或远程日志。Python 源码用 tab 缩进,类型需通过 mypy。
|
|
53
|
+
- path: "tests/**"
|
|
54
|
+
instructions: |
|
|
55
|
+
测试必须完全离线:mock AuthManager / BossClient / CacheStore / AIService,不访问网络、不启动真实浏览器、不使用真实账号,绝不向真实候选人发送消息。每条成功路径至少对应一条错误路径。
|
|
56
|
+
chat:
|
|
57
|
+
art: false
|
|
58
|
+
knowledge_base:
|
|
59
|
+
code_guidelines:
|
|
60
|
+
enabled: true
|
|
61
|
+
# 默认已包含 AGENTS.md / CLAUDE.md 等;这里补充仓库自己的贡献规范
|
|
62
|
+
filePatterns:
|
|
63
|
+
- "**/AGENTS.md"
|
|
64
|
+
- "CONTRIBUTING.md"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "uv"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
day: "monday"
|
|
8
|
+
time: "09:00"
|
|
9
|
+
timezone: "Asia/Shanghai"
|
|
10
|
+
open-pull-requests-limit: 3
|
|
11
|
+
commit-message:
|
|
12
|
+
prefix: "chore"
|
|
13
|
+
groups:
|
|
14
|
+
uv-minor-patch:
|
|
15
|
+
update-types:
|
|
16
|
+
- "minor"
|
|
17
|
+
- "patch"
|
|
18
|
+
- package-ecosystem: "github-actions"
|
|
19
|
+
directory: "/"
|
|
20
|
+
schedule:
|
|
21
|
+
interval: "weekly"
|
|
22
|
+
day: "monday"
|
|
23
|
+
time: "09:00"
|
|
24
|
+
timezone: "Asia/Shanghai"
|
|
25
|
+
open-pull-requests-limit: 3
|
|
26
|
+
commit-message:
|
|
27
|
+
prefix: "ci"
|
|
28
|
+
groups:
|
|
29
|
+
github-actions:
|
|
30
|
+
patterns:
|
|
31
|
+
- "*"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 按改动路径给 PR 打标签(actions/labeler)。标签需事先存在于仓库。
|
|
2
|
+
documentation:
|
|
3
|
+
- changed-files:
|
|
4
|
+
- any-glob-to-any-file:
|
|
5
|
+
- "docs/**"
|
|
6
|
+
- "**/*.md"
|
|
7
|
+
ci:
|
|
8
|
+
- changed-files:
|
|
9
|
+
- any-glob-to-any-file:
|
|
10
|
+
- ".github/**"
|
|
11
|
+
dependencies:
|
|
12
|
+
- changed-files:
|
|
13
|
+
- any-glob-to-any-file:
|
|
14
|
+
- "pyproject.toml"
|
|
15
|
+
- "uv.lock"
|
|
16
|
+
test:
|
|
17
|
+
- changed-files:
|
|
18
|
+
- any-glob-to-any-file:
|
|
19
|
+
- "tests/**"
|
|
20
|
+
recruiter:
|
|
21
|
+
- changed-files:
|
|
22
|
+
- any-glob-to-any-file:
|
|
23
|
+
- "src/boss_agent_cli/commands/recruiter/**"
|
|
24
|
+
- "src/boss_agent_cli/api/recruiter*"
|
|
25
|
+
- "src/boss_agent_cli/platforms/*recruiter*"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
# 外部贡献者的 PR 也要跑:用 pull_request(不是 pull_request_target),
|
|
4
|
+
# fork 的 PR 只拿到只读 token、拿不到任何 secret,本工作流也不需要 secret。
|
|
5
|
+
on:
|
|
6
|
+
pull_request:
|
|
7
|
+
push:
|
|
8
|
+
branches: [master]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
env:
|
|
19
|
+
PYTHONUTF8: "1"
|
|
20
|
+
UV_LOCKED: "1"
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
lint:
|
|
24
|
+
name: Lint & typecheck
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 15
|
|
27
|
+
env:
|
|
28
|
+
UV_PYTHON: "3.12"
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v7
|
|
31
|
+
|
|
32
|
+
- name: Install uv
|
|
33
|
+
uses: astral-sh/setup-uv@v7
|
|
34
|
+
with:
|
|
35
|
+
enable-cache: true
|
|
36
|
+
cache-dependency-glob: uv.lock
|
|
37
|
+
|
|
38
|
+
- name: Install dependencies
|
|
39
|
+
run: |
|
|
40
|
+
uv python install
|
|
41
|
+
uv sync --all-extras
|
|
42
|
+
|
|
43
|
+
- name: Ruff
|
|
44
|
+
run: uv run ruff check src/boss_agent_cli tests scripts --output-format=github
|
|
45
|
+
|
|
46
|
+
- name: Mypy
|
|
47
|
+
run: uv run mypy src/boss_agent_cli
|
|
48
|
+
|
|
49
|
+
- name: Cache pre-commit hooks
|
|
50
|
+
uses: actions/cache@v6
|
|
51
|
+
with:
|
|
52
|
+
path: ~/.cache/pre-commit
|
|
53
|
+
key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}
|
|
54
|
+
|
|
55
|
+
- name: Pre-commit
|
|
56
|
+
run: uv run pre-commit run --all-files --show-diff-on-failure
|
|
57
|
+
|
|
58
|
+
- name: CLI loads and schema envelope is valid
|
|
59
|
+
run: |
|
|
60
|
+
uv run boss --help > /dev/null
|
|
61
|
+
uv run boss --json schema --format native \
|
|
62
|
+
| python3 -c "import sys, json; d = json.load(sys.stdin); assert d['ok'], d; print('schema commands:', len(d['data']['commands']))"
|
|
63
|
+
|
|
64
|
+
test:
|
|
65
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
timeout-minutes: 20
|
|
68
|
+
strategy:
|
|
69
|
+
fail-fast: false
|
|
70
|
+
matrix:
|
|
71
|
+
# 最低支持版本、主力版本、最新版本
|
|
72
|
+
python-version: ["3.11", "3.12", "3.14"]
|
|
73
|
+
env:
|
|
74
|
+
UV_PYTHON: ${{ matrix.python-version }}
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/checkout@v7
|
|
77
|
+
|
|
78
|
+
- name: Install uv
|
|
79
|
+
uses: astral-sh/setup-uv@v7
|
|
80
|
+
with:
|
|
81
|
+
enable-cache: true
|
|
82
|
+
cache-dependency-glob: uv.lock
|
|
83
|
+
|
|
84
|
+
- name: Install dependencies
|
|
85
|
+
run: |
|
|
86
|
+
uv python install
|
|
87
|
+
uv sync --all-extras
|
|
88
|
+
|
|
89
|
+
# 测试全部离线:平台接口、浏览器、CDP 都是 mock,不需要网络和真实浏览器。
|
|
90
|
+
- name: Pytest
|
|
91
|
+
run: uv run pytest -q
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Dependabot auto-merge
|
|
2
|
+
|
|
3
|
+
on: pull_request_target
|
|
4
|
+
|
|
5
|
+
permissions:
|
|
6
|
+
contents: write
|
|
7
|
+
pull-requests: write
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
auto-merge:
|
|
11
|
+
if: github.event.pull_request.user.login == 'dependabot[bot]'
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- name: Fetch Dependabot metadata
|
|
15
|
+
id: meta
|
|
16
|
+
uses: dependabot/fetch-metadata@v3
|
|
17
|
+
with:
|
|
18
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
19
|
+
|
|
20
|
+
# Patch/minor only; major bumps and browser-automation deps stay manual.
|
|
21
|
+
- name: Enable auto-merge
|
|
22
|
+
if: >-
|
|
23
|
+
steps.meta.outputs.update-type != 'version-update:semver-major' &&
|
|
24
|
+
!contains(steps.meta.outputs.dependency-names, 'patchright') &&
|
|
25
|
+
!contains(steps.meta.outputs.dependency-names, 'playwright')
|
|
26
|
+
run: gh pr merge --auto --squash "$PR_URL"
|
|
27
|
+
env:
|
|
28
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
29
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Labeler
|
|
2
|
+
|
|
3
|
+
# 用 pull_request_target 才能给 fork 来的 PR 打标签。
|
|
4
|
+
# 这里不 checkout、不运行 PR 里的任何代码,只读取默认分支上的 .github/labeler.yml,
|
|
5
|
+
# 因此不会把写权限暴露给 PR 代码。
|
|
6
|
+
on:
|
|
7
|
+
pull_request_target:
|
|
8
|
+
types: [opened, synchronize, reopened]
|
|
9
|
+
|
|
10
|
+
permissions: {}
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: labeler-${{ github.event.pull_request.number }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
label:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
pull-requests: write
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/labeler@v7
|
|
24
|
+
with:
|
|
25
|
+
sync-labels: false
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Stale
|
|
2
|
+
|
|
3
|
+
# 保守的过期清理:60 天无动静标记 stale,再 14 天无回应才关闭。
|
|
4
|
+
# 有负责人、草稿 PR、带豁免标签的不处理;任何新评论或更新都会摘掉 stale。
|
|
5
|
+
on:
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: "17 2 * * 1" # 每周一 10:17(北京时间)
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions: {}
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
stale:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
actions: write
|
|
17
|
+
issues: write
|
|
18
|
+
pull-requests: write
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/stale@v11
|
|
21
|
+
with:
|
|
22
|
+
days-before-stale: 60
|
|
23
|
+
days-before-close: 14
|
|
24
|
+
stale-issue-label: stale
|
|
25
|
+
stale-pr-label: stale
|
|
26
|
+
exempt-issue-labels: "pinned,security,bug,in-progress,blocked,triage,needs-repro,research"
|
|
27
|
+
exempt-pr-labels: "pinned,security,bug,in-progress,blocked,triage,needs-repro,research"
|
|
28
|
+
exempt-all-assignees: true
|
|
29
|
+
exempt-draft-pr: true
|
|
30
|
+
operations-per-run: 30
|
|
31
|
+
stale-issue-message: >-
|
|
32
|
+
这个 issue 已经 60 天没有动静,先标记为 stale;如果 14 天内仍无更新会自动关闭。还需要的话留言即可保留。
|
|
33
|
+
/ This issue has had no activity for 60 days and is now marked stale. It will be closed in 14 days unless there is new activity — just leave a comment to keep it open.
|
|
34
|
+
stale-pr-message: >-
|
|
35
|
+
这个 PR 已经 60 天没有动静,先标记为 stale;如果 14 天内仍无更新会自动关闭。还在推进的话推个提交或留言即可。
|
|
36
|
+
/ This PR has had no activity for 60 days and is now marked stale. It will be closed in 14 days unless there is new activity — push a commit or comment to keep it open.
|
|
37
|
+
close-issue-message: "因长期无更新自动关闭,需要时可随时重新打开。/ Closed due to inactivity — feel free to reopen."
|
|
38
|
+
close-pr-message: "因长期无更新自动关闭,需要时可随时重新打开。/ Closed due to inactivity — feel free to reopen."
|
|
@@ -2,7 +2,85 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [Semantic Versioning](https://semver.org/)。
|
|
4
4
|
|
|
5
|
-
## [
|
|
5
|
+
## [3.1.0] - 2026-10-30
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- 新增 `--browser-source httpx-only`:通道白名单为空,结构上不打开任何浏览器;`search` / `recommend` / `detail` / `friend_list` / `chat_history` 全部走 httpx,需要页面的能力返回 `BROWSER_DISABLED`。线上稳定性尚未证实,只作为显式选择,不做默认也不做自动降级;失败时 `hints.operator_actions` 提示回退 `auto`。
|
|
9
|
+
- 新增 `api/proxy.py` 的 `resolve_proxy()`:httpx 与每个 Chromium 启动点共用同一出口。此前 Chromium 完全忽略 `HTTPS_PROXY`/`ALL_PROXY`,登录走真实 IP 而请求走代理 IP。
|
|
10
|
+
- 新增 `auth/page_identity.py`:从真实页面请求采集 `token` / `zp_token` 并随会话加密落盘,httpx 与浏览器两条通道回放同一组值。
|
|
11
|
+
- 新增 `api/egress.py` 与 `BOSS_EGRESS_PROBE_URL`:出口地区与声明的语言/时区矛盾时 `CrawlService.create()` 拒绝开跑;未配置时不发任何探测流量,判为 `unknown` 且不阻断。
|
|
12
|
+
- `boss doctor` 新增 `request_delay` 检查:请求间隔下限低于 30 秒时 warn 并给出建议值。
|
|
13
|
+
- 新增三份研究文档:`docs/research/zhipin-request-identity-2026-10-29.md`(147 条业务请求的逐 header 规则)、`zhipin-cdp-free-read-path-2026-10-29.md`(只读链路脱离 CDP 的可行性、code 37 受控对照与恢复步骤)、`upstream-antidetection-evaluation-2026-10-29.md`(ruyijs / Safarier 的评估与不集成理由)。
|
|
14
|
+
|
|
15
|
+
- 搜索结果新增 `job_url`:由 `encryptJobId` 拼出 `https://www.zhipin.com/job_detail/<id>.html`,不额外请求平台。导出脱敏时与 `job_id` 一起替换为 `[REDACTED]`。
|
|
16
|
+
- 新增 `boss hr whoami` / MCP `boss_hr_whoami`:只读 `getUserInfo`,用 `identity` 判断当前登录态是否在招聘者侧。`identity` 为 1 时 `ready` 为 true;账号资料字段 `recruit` 只以 `profile_recruit` 回显,不参与判断。双身份账号停在求职者侧时返回 `ready: false` 和官方页面切换指引,命令本身不切换身份。
|
|
17
|
+
- 新增跨实例、CLI/MCP 子进程与 crawl 的本地共享请求预算:默认单个主动操作持锁至响应分类完成,滑动 60 秒最多 20 次,总等待上限 30 秒;`request_budget_dir` 可显式分组,组内采用统一限制并共享风险阻断。HTTP 429 / code 9 和有效 `Retry-After` 持久化冷却,进程退出只释放执行锁;预算超限返回 `REQUEST_BUDGET_EXHAUSTED`,保留 checkpoint 后显式恢复。主动操作计量不覆盖浏览器自主资源、轮询、自动重定向或认证内部的每条网络请求,不按公网 IP 自动合并任务。
|
|
18
|
+
- 招聘者 `agent run --resume` / MCP `boss_agent_run.resume` 提供显式恢复入口,保留确认结果与队列,普通运行不清除停止状态。
|
|
19
|
+
- 招聘者 `hr chat` 的 hints 新增 `total_unread`:聊天页显示的未读总数,读自页面 geek-list 组件的 `uncountTab$` 第 1 项(实测与页面 UI 一致,覆盖全部会话,不限于已加载的部分);同时给出原始分项计数 `unread_by_tab` 和来源 `total_unread_source`(`page.uncountTab$[1]`)。只读页面内存,不额外发请求;页面不可用(非 CDP 或没打开聊天页)时三项均为 `null`(Refs #456)。
|
|
20
|
+
- `boss search` 新增 `--active <档位>`,按 HR 活跃度筛选职位(#442)。档位 `online` / `today` / `3d` / `week` / `2w` / `month` / `half-year`,也认 `3day`、`3日` 等写法;平台文案按「在线/刚刚活跃 > 今日活跃 > 3日内活跃 > 本周活跃 > 2周内活跃 > 本月活跃 > 近半年活跃 > 半年前活跃」比较。列表带 `activeTimeDesc` 或 `bossOnline` 为在线时直接判断,否则查 job_card;和 `--welfare` 同用时一次详情请求同时判断两项。启用后跳过搜索缓存,无法识别的文案被排除并写进 `hints.active_filter`。职位结果新增 `boss_active_desc` 字段(`boss_active` 不变,搜索缓存 schema 升到 3),`preset add`、MCP `boss_search` / `boss_preset_add` 与向导求职流程同步支持。
|
|
21
|
+
- 替换仓库 README 与项目站点的展示动画为 48 秒极光发布会成片,提供 MP4、轻量动图、新封面和可交互源工程;站点播放期间保持当前画面,切换到终端演示时暂停视频。
|
|
22
|
+
- 新增维护者发布验证脚本:默认离线核对版本、wheel/sdist 元数据与分发文件,显式启用后可在临时环境全新解析依赖、验证 CLI/MCP,或从 PyPI 安装指定版本复验;输出结构化步骤结果,不执行发布或真实平台请求。
|
|
23
|
+
- 新增仓库根 `llms.txt`:面向 LLM 的单页能力入口(能力真源、信封契约、运行边界与链接),指向 `boss schema` 与关键文档;不引入会与 schema 漂移的静态工具清单。
|
|
24
|
+
- `boss login` 的浏览器 Cookie 提取从 6 个扩展到 10 个:新增 Vivaldi / Arc / LibreWolf / Safari,自动检测优先级不变、新浏览器作为后备;macOS Safari 需要完全磁盘访问,读取失败时静默尝试下一个浏览器。
|
|
25
|
+
- 新增 `docs/research/opencli-benchmark-2026-10-15.md`(含英文对照):对标 OpenCLI / boss-cli / opencli-mcp / xhs-cli 的差距矩阵、已确认缺陷(文档漂移)与分批改进方案;分层规则复核更正见方案 §3.3。
|
|
26
|
+
- 新增全局 `--exit-codes {envelope,sysexits}`(默认 envelope,0/1 契约不变):sysexits 模式按错误类别返回语义化退出码(77 认证;75 限流/预算/超时;78 参数/配置;69 风控/平台不支持;其余 1),usage error 通过解析前预扫描同一选项;stdout 信封不受影响。
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- **行为变更:默认请求间隔 `--delay` 从 `1.5-3.0` 改为 `30-60`**(`config.DEFAULT_REQUEST_DELAY`,原先 10 处字面量收敛为一个常量)。受控对照:15 秒间隔连续 3 次 `search` 会在第 3 次命中 code 37「您的环境存在异常」,30 秒起两轮共 6/6 通过。单条只读命令只发一次请求、首次调用不等待(`boss status` 仍约 0.3 秒);受影响的是分页、批量详情与 crawl。该下限来自本机观测,不是平台公布阈值。
|
|
30
|
+
- 请求身份对齐真实页面抓包:`User-Agent`、`sec-ch-ua*`、`Accept-Language`、`Accept-Encoding`、`priority`,补上页面自带的 `token`、`zp_token`、`traceid` 与 `X-Requested-With`;`sec-ch-ua-platform` 改由 User-Agent 推导(原先按宿主操作系统,Windows 上会发出「UA 说 macOS、Client Hint 说 Windows」的矛盾组合)。
|
|
31
|
+
- `search` 改为真机的 `POST` + `application/x-www-form-urlencoded` 表单体,字段集合与顺序按抓包固定,缺省筛选项发空串而非省略;`recommend` 保持 GET。
|
|
32
|
+
- httpx 通道改用 HTTP/2(依赖改为 `httpx[socks,http2]`,新增 `brotli`、`zstandard`),`Accept-Encoding` 的声明与可解码能力保持一致。
|
|
33
|
+
- Chromium 启动加入 `--force-webrtc-ip-handling-policy=disable_non_proxied_udp` 与 `--enforce-webrtc-ip-permission-check`,避免 WebRTC 用真实地址发送 UDP。
|
|
34
|
+
|
|
35
|
+
- `boss doctor` 默认不再读取浏览器 Cookie,避免 macOS 钥匙串授权弹窗。需要核对浏览器登录态时使用 `boss doctor --probe-cookies`。`boss status` 与 `boss search` 本来就只看本地凭据。
|
|
36
|
+
- `hr jobs list` 改为读取职位管理页的 `data/list` 接口,并用 `--page` 分页。MCP `boss_hr_jobs` 的 `page` 只在 list 时传给该分页。`boss schema` 同步登记该选项。
|
|
37
|
+
- 招聘者 `chat_geek_info` 改为沟通页当前参数:`uid`、`securityId`,以及调用方提供时的 `geekSource`。没有命令调用这个方法。
|
|
38
|
+
- `boss doctor --live-probe` 复用 `hr whoami` 的身份判断:`identity` 为 0 时先记下求职者侧登录态,不继续请求招聘者接口;`identity` 为 1 时才做招聘者只读探测。命令不切换身份。
|
|
39
|
+
- MCP、OpenAI 和 Anthropic 工具格式统一使用不依赖 MCP SDK 的共享目录,工具导出由旧的不完整命令映射改为与运行时一致的 77 个工具;原生 schema 保留 39 个顶层命令。保留工具参数结构的脱敏例外仅限 schema 明确声明的内置参数路径,真实业务数据和敏感默认值/示例仍脱敏。
|
|
40
|
+
- 恢复面向 PR 的 `CI` 工作流(参照 Wholiver/metis 的 Test 工作流):`pull_request` 与推送 `master` 时运行 ruff、mypy、pre-commit、CLI/schema 冒烟和 Python 3.10 / 3.12 / 3.14 测试矩阵;只读权限、同一 PR 新推送取消旧运行、不使用任何 secret,外部贡献者的 fork PR 可直接运行。pre-commit 的 end-of-file-fixer 排除 star-history 自动生成的 SVG,并补上 `wizard/renderer.py` 结尾换行,使 `pre-commit run --all-files` 在 master 上可以通过;贡献指南同步更新 CI 说明,去掉已失效的 Codecov 描述。
|
|
41
|
+
- 同步项目站点中英文正文与 `llms.txt` 的 v3.0.0 版本、命令与 MCP 数量、双角色工作流及平台风险停止/显式恢复说明,移除过时的模式级阻断宣传;修正发布会源工程的本地预览服务目录。
|
|
42
|
+
- 文档对齐:`CLAUDE.md` 与 `docs/maintainer/branch-protection.md` 同步 2026-10-09 已恢复的 PR CI(lint + Python 3.10 / 3.12 / 3.14 测试矩阵;required status checks 仍未配置);`pyproject.toml` 注释改指本地 `scripts/verify_release.py --fresh-install`;中英文 README 与 `CLAUDE.md` 的测试计数更新为 2900+。
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
- 复用自动探测到的 CDP 浏览器前,先比对 `wt2` 与本地凭据:不同账号时拒绝复用其会话,改用本地凭据自建浏览器,避免拿 A 账号的登录态执行 B 账号的请求(实测会立刻得到 code 37)。
|
|
46
|
+
- `security_id` 可以合法以 `-` 开头(实测 328 字符的 base64url 取值),此前会被 Click 当成未知选项,`boss detail` 直接传时报 `No such option`;现在为未声明的横杠开头取值补 `--`。
|
|
47
|
+
- 候选者侧 referer 由 `/web/geek/job` 更正为真实页面 `/web/geek/jobs`(`web_pages` 与 5 处 referer 一并修正)。
|
|
48
|
+
- 抓包脚本判定目标页改用 host 解析,不再用子串匹配(CodeQL `py/incomplete-url-substring-sanitization`)。
|
|
49
|
+
|
|
50
|
+
- `boss login` 的中间提示不再宣称「检测到登录成功」:扫码确认到 `wt2` 出现只是**识别**,之后还要校验页面、等 3 秒、回首页提取,任一步命中官方验证页都会停下。现在统一为「已识别到扫码确认,正在校验并保存凭证…」,真正的「登录成功(…)」仍由命令层在凭据落盘后输出(#488)。
|
|
51
|
+
- `security_page` / 访问受限页的错误详情补上 `risk_source` 命中的页面路径(`error.details.path`):此前只有 `risk_source`,用户无法区分 `verify.html`(安全校验)与 `security.html`(风险页),维护者也拿不到定位依据(#488)。
|
|
52
|
+
- `boss search` 等浏览器通道在冷启动时只对首页做一次 15 秒 `page.goto`,首页卡住就以 `NETWORK_ERROR` 原样抛出 `Page.goto Timeout 15000ms`(Discussion #250)。现在与登录预热对齐:超时后若不是安全验证页,就跳到 `about:blank` 再试一次;仍然失败则返回 `BROWSER_NAV_TIMEOUT`,说明要先打开官网首页或刷新登录态。`--url` 仍只解析筛选条件,搜索请求之前还是要先打开首页。把 `--json` 等全局选项写在子命令后面时,`INVALID_PARAM` 会提示该选项必须写在子命令之前。
|
|
53
|
+
- 修正节流完成时间覆盖后续预约、高斯采样突破间隔下限及 crawl 分类别预算边界;使用单调时钟保持预约,crawl 首页种子导航、分页、页面 fetch 和 CDP fallback 分别申请预算。等待及发送前检查停止、风险和截止时间,停止信号不触发重试或通道降级;写后确认受阻保留 `ACTION_UNCONFIRMED` 和 `confirmation_stop`,失败下载仍记节流,429 下载不读正文或创建文件。crawl 在中断或清理失败前保存进度,清理异常保留原风险或预算停止状态。
|
|
54
|
+
- 校验 `--delay`、延迟范围和共享预算配置的有限数值、正整数及绝对路径约束;非法配置不落盘,保留配置修复入口。预算组有效风险状态进入 `status` / `doctor`,显式清风险锁保留预算及冷却,风险写盘失败仍阻断当前实例。
|
|
55
|
+
- 浏览器风险识别续查:聊天页 `/wapi/` 的 HTTP 403 在响应头事件立即停止,不等正文;错误/缺失 Content-Type 的受限 HTML 仍生成脱敏分类元数据。业务 JSON 先解析原码,避免成功响应中的 HTML 说明触发误锁;纯文本业务响应同样检查风险,外站和普通静态资源不误锁。
|
|
56
|
+
- 补齐 code 31(IP/环境限制)、32(账号限制)及官方 `403.html` 访问受限页:API、浏览器、认证与 crawl 在刷新、重登清 Cookie 或继续导航前停止并保存原码/未知状态;隐藏文案不用于猜测当前原因。当前网页 code 31 已只读观察,32 仅有静态与离线证据;页面展示时间和移动端可用均不触发自动解锁。
|
|
57
|
+
- 风险锁改为显式本地恢复:code 35/36、环境类或含糊的 code 37、HTTP 403 和官方 verify/security 安全页在候选、招聘者与认证通道锁存原始风险原因及可用业务码;httpx、headless、裸 CDP、令牌变化和历史 `--ignore-risk-lock` 均不能绕过已记录锁。用户确认目标业务页恢复后执行 `boss clean --risk-lock` 再显式恢复任务,清理不代表平台解封,再次风险立即重锁。code 37 刷新要求凭据与明确过期语义同时存在,风险/安全验证优先;code 35/security 路径与含糊 token 分类为静态证据和离线回归,未声称真实账号线上解除已验证。
|
|
58
|
+
- 独立 crawl 与 API 共用同 `data_dir` 风险锁,在浏览器构造、连接和后台启动前阻断已锁任务;新风险持久化原始原因/业务码,未知码保持 `null`,code 38 明确属于身份资料流程。风险 outcome、已采集队列和 checkpoint 保留,人工恢复放在 `operator_actions`,resume 不清锁;本地结果与已完成 run 导入仍可用。
|
|
59
|
+
- 候选人搜索、推荐、批量沟通与 watch 在同次结果/分页流程中按非空职位 ID 去重,保留首条完整 `security_id/lid`,不按职位 ID 合并不同账号的历史记录。候选池可选 `lid` 经兼容 SQLite 扩展保存,CLI/MCP/schema、crawl/favorites 导入同步;favorites 更新访问上下文时不拼接旧 `lid`。
|
|
60
|
+
- `recommend` 保留缺失/不明确的分页标记为 `has_more=null`,只有平台明确返回布尔 `true` 才给出下一页提示,避免上层无依据继续请求;兼容 `total` 仍是本页条数,新增 `total_kind` 明确其范围。
|
|
61
|
+
- 风险响应在刷新、登录降级或采集 fallback 前停止:原始 code 36、环境类/不明确 code 37、HTTP 403 和安全页共享错误契约;Cookie、二维码各阶段、CDP 探测/刷新、招聘者动作前后回读与自动化读响应均原样传播风险,保存可用 checkpoint,不继续请求或更换通道。
|
|
62
|
+
- 端点显式声明读写与可重放性质,GET 变更和未知操作不再按方法推断可重试;fetch/响应体与 CDP renderer 加有界截止。浏览器上下文销毁、httpx 断链/损坏响应等未知写结果保留 `ACTION_UNCONFIRMED`,候选人与招聘者均不提示自动重发;招聘者准确绑定目标好友,不强制开启禁用编辑器,不以 outgoing WS 或未知手机号动作编号确认成功。
|
|
63
|
+
- 自动化使用独立原子停止标志并在动作边界重新读取,逐项保存已确认防重结果,风险和中断保留进度;wizard 成功结果先落盘再处理超时,旧更新不能覆盖 stop。MCP handler 改用异步子进程,长运行期间控制工具仍可响应,取消/超时有界中断并回收进程,保留副作用未知标记与 checkpoint 宽限。
|
|
64
|
+
- 搜索缓存命中重建本次排序的编号索引,`lid` 随编号、show/detail/job-card 传递,crawl 候选池仅从同 run/job/security 的既有本机缓存恢复 `lid`,兼容旧数据。福利/活跃度筛选先跳过已沟通过职位,有限需求按需串行并在结果足够时停止;apply 原始风险分支不再提示自动重试。
|
|
65
|
+
- 招聘者 `hr chat` 打开聊天页后页面来源仍是 0 条、`unread` 全为 `null`(#456 后续)。实测聊天页(Vue 2 + vue-rx)的会话列表挂在 geek-list 组件实例的 `list$` 和父组件 chat 的 `allList$` 订阅上(`$observables`),不在原快照扫描的 `$data` / computed / `$store` 里;列表项自带 `newMsgCount`、`lastText`、`lastTS`、`lastMsgStatus`、`lastIsSelf`。快照脚本现在先读 vue-rx 订阅(仍只读页面内存、字段白名单),页面已加载的会话直接给出未读数、最后一条消息和时间,没覆盖到的会话再走 `userLastMsg`;`hints.summary_sources.page_snapshot` 给出数据来源路径、已加载条数和页面是否还有更多(`has_more`)。页面只保存已滚动加载的会话,未加载的会话拿不到未读数,仍为 `null`。另外修正快照脚本从未真正执行的问题:`evaluate_js` 不带参数时只把函数表达式求值成函数对象而不调用,快照因此一直为空,现在带参数调用。
|
|
66
|
+
- 招聘者 `hr chat` 的最近消息补全实测全部失败(`last_messages_error: 未知的非法参数`,356 条都退回 `friend_list`,#456 后续)。对照前端代码和 3 个 friendId 的实测:`userLastMsg` 参数本身没错(表单 `src=0&friendIds=a,b,c`),问题是把整页 356 个 friendId 一次塞进去,前端自己每批不超过 100 个,并按 friendSource 分组(店长直聘好友 `src=1`)。现在按 friendSource 分组、每批 50 个串行请求,默认只补前 100 个会话(最多 2 次请求),`hr chat --summary-limit`(0–300,0=不请求)可调,任一批失败立即停止并在 `hints.summary_sources` 记录 `last_messages_error` / `last_messages_error_code` / `last_messages_requests` / `last_messages_skipped`;`hr last-messages` 同样分批并新增 `--limit`。按实测返回形状(`uid`、`lastTS`、`lastMsgInfo.showText/fromId/status/msgTime`)解析:时间优先用毫秒时间戳而不是「12:00」展示串,候选人发来的最后一条消息不再显示成「发送中」(`msg_status` 只对自己发出的消息有值)。该接口不返回未读数,`unread` 仍只来自聊天页快照。
|
|
67
|
+
- 风控锁(#453)补齐聊天页动作和登录覆盖。招聘者 `hr reply` / `hr request-resume` / `hr resume --exchange` 在执行前仅检查本地锁,不为核对令牌建立 CDP 连接;未解除时不执行页面动作。页面的 code 35/36/37 或安全页会锁存并保留原始原因,`error.details.page_risk` 保留接口路径和码。登录、导入和刷新也在平台请求前检查同一锁;历史 `--ignore-risk-lock` 参数保留兼容但不放行,用户确认官方目标业务页恢复后须执行 `boss clean --risk-lock` 显式清除本地阻断。
|
|
68
|
+
- 招聘者 `hr chat` 的未读数、最后一条消息、时间不再全是 `null` / `未知` / `-`。实测沟通列表接口(filterByLabel)只返回 friendId、姓名、updateTime 等基础字段,原实现的补全又没对上数据。现在 CDP 模式下先读聊天页 geek-list 组件里已加载的会话列表(只读页面内存、不发请求,字段按白名单挑选);页面没覆盖到的会话才调用一次 `userLastMsg`(单次、串行),并兼容消息对象(按 from/to uid 对应候选人)和 `{friendId: 消息}` 映射等返回形状;都拿不到时字段为 `null`,`last_time` 退回 `updateTime` 并标注 `last_time_source`。每条记录新增 `summary_source`,`hints.summary_sources` 给出来源统计和最近消息接口错误。`hr last-messages` 同步改为未知字段输出 `null`。
|
|
69
|
+
- 招聘者 `hr resume --exchange` 在换电话/换微信按钮还没解锁时不再走一遍页面动作、最后报含糊的 `ACTION_UNCONFIRMED`。实测平台要求招聘者先在会话里发过消息才解锁这两个按钮(求简历不受限),未解锁时 `handleExChange` 照常返回但什么都没发。现在交换前先检查按钮组件的禁用状态(`disabled` / `aria-disabled` 属性、`disabled`/`gray` 等 class、根元素 `pointer-events: none`、组件 props/data 的禁用标记);页面判断不了时,用动作前读到的完整聊天记录里是否有自己发出的消息兜底。确定未解锁时不调用 `handleExChange`,返回新错误码 `EXCHANGE_NOT_AVAILABLE`(`recoverable=true`,提示先 `boss hr reply` 或 `boss hr request-resume` 后再试),`error.details` 带 `availability`、`availability_signals`、`history_self_message`;信号拿不准时不拦截。按钮看起来可用但聊天记录里没有自己的消息时仍按原流程执行,若最终未确认,`ACTION_UNCONFIRMED` 的提示会点出按钮可能尚未解锁。
|
|
70
|
+
- 招聘者 `hr resume --exchange --type wechat` 实际已发出换微信请求却返回 `ACTION_UNCONFIRMED`(#443 后续)。实测这类请求在聊天记录里是不带文案的动作卡片(`body.type=4`、`action.aid=32`),原判定只认文案。现在聊天记录和 WS 帧都按动作卡片的 aid 判定:aid 32 = 换微信,aid 37 = 求附件简历;换手机号的 aid 尚无样本,暂时接受除这两个之外任意 aid 的卡片。卡片必须是自己发出、动作后新出现(mid 不在动作前快照里,且时间不早于动作开始 60 秒以上)。没有 WS 证据时聊天记录回读改为轮询(首读加 3 次重试,共约 6 秒),`error.details` 新增 `history_attempts`;换微信时出现的 aid 37 卡片也计入 `resume_request_detected`。
|
|
71
|
+
- CDP 模式不再用 httpx 带着浏览器登录态访问平台(#452 / #451 后续)。实测 `--cdp-url` 下 `job_card` 先走 httpx(Cookie 从 Chrome 拷出、`__zp_stoken__` 作查询参数),与浏览器通道并发,Chrome 里的 stoken 随即被判异常,之后 CLI 的浏览器请求一律 code 37,而手动浏览因页面重新校验换了 stoken 仍正常。现在配了 `--cdp-url`、显式 `--browser-source existing-browser` / `stored-cookie`,或本进程已接上 CDP Chrome 时,`BossClient` / `BossRecruiterClient` 的所有平台读写都只走浏览器通道(`job_card` 不再 httpx 优先,`detail`、向导详情、收藏、投递记录、聊天等读取一并改走浏览器),没有浏览器实现的操作(招聘者附件下载)返回 `NOT_SUPPORTED`;`search` / `watch` / 向导的福利、活跃度补详情在 CDP 下改为串行并按 `CrawlBudget` 间隔;`crawl` 的列表兜底和详情改为在采集页签内同源请求,去掉 httpx 回退。风险锁沿用历史 `cdp_risk_lock` 名称,摘要仅作诊断;锁存后所有 BOSS 请求在本地拒绝,账号风险保留 `ACCOUNT_RISK`,环境锁保留 `ENVIRONMENT_RISK_LOCKED`。`boss doctor` / `boss status` 展示本地状态,只有用户确认目标业务页恢复并执行 `boss clean --risk-lock` 后才能显式继续;令牌变化不会自动解锁,HTTP/headless 也不能绕过已有锁。`detail` 命中风控后不再换通道补请求。
|
|
72
|
+
- 收紧 `boss search --active` 的请求量(#451 回归,#442)。实测列表项不带 `activeTimeDesc`,原实现会固定翻 5 页并对离线 HR 的职位 3 线程并发取 job_card,`--active 3d` 跑约 28 秒后触发平台风控 code 37。现在 `--active online` 只看列表的 `bossOnline`,不查详情、只翻 1 页,请求量与普通搜索相同;其余档位先看 1 页,结果不足 10 条(或 `limit`)且本页仍有职位要查详情才继续,最多 3 页;在线行直接通过任何档位。需要查详情时改为串行,每次请求前按列表请求的节奏(5–10 秒)间隔,CDP / 指定浏览器来源时只走浏览器 job_card,不再 httpx 与浏览器混用;与 `--welfare` 同用时同样保守,单独 `--welfare` 行为不变。`bossOnline` 统一按 `True` / `1` / `"1"` 判为在线(`JobItem.boss_active` 与活跃度判断共用),`hints.active_filter` 新增 `detail_lookups` 提示实际查了多少个详情。`boss watch` 和向导求职流程的默认翻页同步调整。
|
|
73
|
+
- 招聘者 `hr request-resume` / `hr resume --exchange` 不再把已生效的动作误报为 `unexpected page result`,换微信也不再顺带发出求附件简历请求(#443)。确认按钮只在当前组件和本次动作新弹出的可见弹层里按文字「确定」查找,没有新弹层就不点;求简历同时认新旧两种文案(含「想要一份您的附件简历」),并在动作后只读回查聊天记录。页面动作执行但找不到发送证据时返回新错误码 `ACTION_UNCONFIRMED`(`recoverable=false`,先 `boss hr chatmsg <friend_id>` 核实、勿直接重试),页面日志、确认状态和 WS 统计放进 `error.details`;同时修正 CDP 文本帧被当作 base64 解码的问题。
|
|
74
|
+
- 定向更新安全依赖:`[mcp]` 的 PyJWT 锁定到 2.15.1、`[crawl]` 的 urllib3 锁定到 2.8.0、`[dev]` 的 virtualenv 锁定到 21.7.13,并仅连带更新 python-discovery 到 1.6.1。在对应 extra 中声明安全版本下界,避免全新安装回退到已知风险版本,不扩大基础运行依赖;补齐依赖作用域和 JWT 调用者选项隔离/过期声明校验回归。
|
|
75
|
+
- `boss config set platform` 在写入前按当前注册表拒绝已移除、未知或空平台值;失败不创建配置文件,也不改写已有内容,保留显式 `--platform zhipin` 修复旧配置的入口。
|
|
76
|
+
- `boss doctor` 将可执行后继命令与真人操作指引分别放入 `next_actions` / `operator_actions`,命令保留数据目录、平台、浏览器来源和 CDP 上下文;TTY 显示真人指引。源码质量工具检查和维护脚本建议仅面向本项目源码运行,安装包用户不再被要求拥有开发工具链。
|
|
77
|
+
|
|
78
|
+
## [3.0.1] - 2026-10-23
|
|
79
|
+
|
|
80
|
+
### Fixed
|
|
81
|
+
- 招聘者在线简历接口 `/wapi/zpjob/view/geek/info` 返回「旧简历接口已下线」时,`hr resume` 与 wizard 改为 `ENDPOINT_DEPRECATED`(不可恢复,停止重试),并在 `error.details.tracking_issue` 指向 #472。聊天发送旧端点 #217 仍走同一错误码,跟踪链接改到各自的 `details`,不再写死在 `recovery_action`。`recovery_action` 文案改为查看 `error.details.tracking_issue`,错误码本身不变。
|
|
82
|
+
- CDP 回读在线简历时,已解开的 `resumeInfo` 在弹层内部的 `new-chat-resume` 上,外层 `transition` 的 `$children` 为空。读取改为同时扫描弹层里的 Vue 实例;`geekBaseInfo` 只保留解析器会用到的字段。教育经历同时认 `degreeName` / `startDateDesc` / `endDateDesc`。
|
|
83
|
+
- `hr resume` 的在线简历请求改为 `uid`、`encryptJid`、`securityId`,并带 `X-Requested-With: XMLHttpRequest`。不再发送插件时期的参数名,也不生成 `sigx`。登录态沟通页的完整正文由页面自己请求 `GET /wapi/zpjob/view/geek/info/v2`(含 wasm 的 `challenge`);CLI 不复刻该请求。CDP 下若旧接口仍返回下线文案,且已打开 `/web/chat/index`,再调用页面自己的 `newChatResumeViewer`,只读取 securityId 匹配的白名单字段并关闭弹层。没有聊天页或没有可读正文时,仍返回 `ENDPOINT_DEPRECATED`。
|
|
6
84
|
|
|
7
85
|
## [3.0.0] - 2026-10-02
|
|
8
86
|
|
|
@@ -16,13 +16,13 @@ uv run pytest tests/ -v
|
|
|
16
16
|
uv run pre-commit install
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Python **≥ 3.
|
|
19
|
+
Python **≥ 3.11** is required. We use [`uv`](https://github.com/astral-sh/uv) for dependency management — `uv sync --all-extras` installs runtime + dev deps in a local `.venv`.
|
|
20
20
|
|
|
21
21
|
## Coding Standards
|
|
22
22
|
|
|
23
23
|
- Python source indentation uses **tabs**.
|
|
24
24
|
- `indent-width = 4` in `pyproject.toml` is the formatter display width. It does not mean Python files should switch to spaces.
|
|
25
|
-
- Use Python >= 3.
|
|
25
|
+
- Use Python >= 3.11 and `X | Y` union syntax.
|
|
26
26
|
- Command output must preserve the JSON envelope contract: stdout is agent-readable JSON only, stderr is logs and progress.
|
|
27
27
|
- Commit messages use the repository Chinese format `type: 中文描述`.
|
|
28
28
|
- Type checking is blocking in CI. New code must pass `uv run mypy src/boss_agent_cli`.
|
|
@@ -70,7 +70,7 @@ Before investing in promotion, examples, or integrations, check those passive si
|
|
|
70
70
|
```
|
|
71
71
|
5. **Commit** atomically — one logical change per commit.
|
|
72
72
|
6. **Push** and open a PR against `master`.
|
|
73
|
-
7. **CI green** is a hard prerequisite before merge
|
|
73
|
+
7. **CI green** is a hard prerequisite before merge: the `CI` workflow runs ruff / mypy / pre-commit and tests on Python 3.11, 3.12 and 3.14 for every PR (fork PRs included, no secrets needed), plus CodeQL and GitGuardian scans. Tests are fully offline; don't add tests that need the network, a real browser or a real account.
|
|
74
74
|
|
|
75
75
|
Maintainers will `squash merge`, so the squash title must follow the commit convention above.
|
|
76
76
|
|
|
@@ -117,7 +117,7 @@ On error, the envelope must contain `error.code`, `error.recoverable`, and `erro
|
|
|
117
117
|
|
|
118
118
|
## Testing Philosophy
|
|
119
119
|
|
|
120
|
-
- **TDD encouraged**: write the test before the implementation.
|
|
120
|
+
- **TDD encouraged**: write the test before the implementation. For coverage, run `uv run pytest --cov=boss_agent_cli` locally.
|
|
121
121
|
- **Mock external I/O**: `AuthManager`, `BossClient`, `CacheStore`, and `AIService` are mock boundaries — tests should not hit the real BOSS Zhipin API.
|
|
122
122
|
- **Error-path parity**: for every success path, add at least one error path test (auth expired, rate-limited, invalid param, etc.).
|
|
123
123
|
|
|
@@ -16,13 +16,13 @@ uv run pytest tests/ -v
|
|
|
16
16
|
uv run pre-commit install
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Python **≥ 3.
|
|
19
|
+
Python **≥ 3.11** 是最低要求。项目使用 [`uv`](https://github.com/astral-sh/uv) 管理依赖,`uv sync --all-extras` 会在本地 `.venv` 中安装运行时和开发依赖。
|
|
20
20
|
|
|
21
21
|
## 编码规范
|
|
22
22
|
|
|
23
23
|
- Python 源码缩进使用 **tab**。
|
|
24
24
|
- `pyproject.toml` 中的 `indent-width = 4` 表示格式工具的视觉宽度,不表示改为空格缩进。
|
|
25
|
-
- Python >= 3.
|
|
25
|
+
- Python >= 3.11,使用 `X | Y` 联合类型。
|
|
26
26
|
- 命令输出必须保持 JSON 信封契约:stdout 只输出 Agent 可读 JSON,stderr 输出日志和进度。
|
|
27
27
|
- commit message:`type: 中文描述`(feat / fix / refactor / docs / test / chore / ci)。
|
|
28
28
|
- 类型检查:`uv run mypy src/boss_agent_cli`,CI 阻塞式门禁,新代码必须零 mypy 错误。
|
|
@@ -70,7 +70,7 @@ git diff --check
|
|
|
70
70
|
```
|
|
71
71
|
5. **原子提交**:每个 commit 只做一件事。
|
|
72
72
|
6. **Push** 并向 `master` 发起 Pull Request。
|
|
73
|
-
7. **CI
|
|
73
|
+
7. **CI 全绿**才能合并:`CI` 工作流在 PR 上跑 ruff / mypy / pre-commit 和 Python 3.11、3.12、3.14 的测试(fork 的 PR 同样会跑,不需要任何 secret),另有 CodeQL 和 GitGuardian 安全扫描。测试全部离线,不要写需要网络、真实浏览器或真实账号的测试。
|
|
74
74
|
|
|
75
75
|
维护者会使用 squash merge,所以最终 squash 标题也要遵守上面的 commit 格式。
|
|
76
76
|
|
|
@@ -99,7 +99,7 @@ git diff --check
|
|
|
99
99
|
|
|
100
100
|
## 测试理念
|
|
101
101
|
|
|
102
|
-
- **鼓励 TDD
|
|
102
|
+
- **鼓励 TDD**:先写测试再写实现。需要看覆盖率时本地跑 `uv run pytest --cov=boss_agent_cli`。
|
|
103
103
|
- **Mock 外部 I/O**:`AuthManager`、`BossClient`、`CacheStore`、`AIService` 是 mock 边界,测试不应真正调用 BOSS 直聘 API。
|
|
104
104
|
- **错误路径对等**:每条成功路径至少对应一条错误路径测试(认证过期、限流、参数非法等)。
|
|
105
105
|
|