controlzero 1.13.1__tar.gz → 1.13.2__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.
- {controlzero-1.13.1 → controlzero-1.13.2}/CHANGELOG.md +25 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/PKG-INFO +1 -1
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/__init__.py +1 -1
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/main.py +76 -10
- {controlzero-1.13.1 → controlzero-1.13.2}/pyproject.toml +1 -1
- controlzero-1.13.2/tests/test_kiro_cli_v210_hooks.py +110 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/.gitignore +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/Dockerfile.test +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/LICENSE +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/README.md +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/__main__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/_messages.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/action_aliases.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/action_validator.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/bundle.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/condition_ops.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/credential_hook.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/credential_scanner.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/credentials_data/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/credentials_data/built_in.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/dlp_scanner.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/enforcer.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/hook_extractors.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/io_capture_producer.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/source_labels.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/tool_extractors.json +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/types.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/audit_local.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/audit_remote.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/canonical.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/__main__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/_secrets.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/agent_config.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/console.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/debug_bundle.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/doctor.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/exec_cmd.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hook_entry.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/antigravity.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/base.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/claude_code.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/codex_cli.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/cursor.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/cursor_cli.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/gemini_cli.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/kiro.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/hosts/unknown.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/kiro_adapter.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/migrate.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/output.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/spool_cmd.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/telemetry_consent.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/antigravity/hooks.json +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/antigravity.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/autogen.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/claude-code.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/codex-cli.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/cost-cap.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/crewai.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/cursor.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/gemini-cli.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/generic.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/kiro/ide-file-save.kiro.hook +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/kiro/ide-pre-tool-use.kiro.hook +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/kiro/ide-prompt-submit.kiro.hook +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/kiro/kiro.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/langchain.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/mcp.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/rag.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/update_cmd.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/client.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/device.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/enrollment.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/error_codes.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/error_codes.yaml +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/errors.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hitl/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hitl/grant_protocol.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hitl/mock.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hitl/pending_approval.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hitl/secret_leak_guard.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hitl/status.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hook_integrity.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hooks/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hooks/tool_output_handler.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/hosted_policy.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/anthropic.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/autogen.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/braintrust.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/crewai/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/crewai/agent.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/crewai/crew.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/crewai/task.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/crewai/tool.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/google.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/google_adk/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/google_adk/agent.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/google_adk/tool.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/langchain/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/langchain/agent.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/langchain/callbacks.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/langchain/chain.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/langchain/graph.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/langchain/modern.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/langchain/tool.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/langfuse.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/litellm.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/openai.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/pydantic_ai.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/integrations/vercel_ai.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/layout_migration.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/policy_loader.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/secrets/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/secrets/reference.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/secrets/resolver.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/secrets/secretstr.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_compress.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_constants.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_crc32c.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_crypto.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_frame.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_keyring.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_metrics.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_spool.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_state.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/_uploader.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/spool/cz-audit-v1.dict +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/tamper.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/controlzero/tracecontext.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/examples/hello_world.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/_fixtures/antigravity-envelope-expected.json +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/_fixtures/jcs_args_hash_vectors.json +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/conftest.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/integrations/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/integrations/test_google.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/parity/action_aliases.json +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/__init__.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/conftest.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_cli.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_concurrency.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_conformance.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_core.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_crash.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_diskfull.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_durable_default_tamper.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_keychain_dek.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_sink_wiring.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_transcript_localack.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/spool/test_spool_uploader.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_action_aliases.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_action_canonicalization.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_action_validator_t86.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_adapter_interface.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_agent_name_env.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_agy_docs_no_exit2_1373.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_antigravity_adapter.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_antigravity_envelope_parity.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_antigravity_ga_blockers_1248.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_antigravity_hook_check.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_antigravity_install.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_antigravity_posttooluse_observe_58.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_antigravity_tool_vocab_1303.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_api_key_mask.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_audit_project_id_attribution_pr2.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_audit_remote.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_audit_remote_io_capture.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_audit_remote_sdk_version.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_audit_sink_isolation.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_bundle_cache_freshness_1303.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_bundle_parser.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_bundle_translate.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_canonical_phase1a.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_capability_matrix_doc.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_carve_out.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_debug_bundle.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_extractor_integration.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_hook.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_hook_entry.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_hosted_refresh.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_init.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_init_templates.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_tail.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_test.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cli_validate.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_coding_agent_hooks.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_condition_operators_1495.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_conditions.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_config_format_parity_1303.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_conformance.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_console.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_credential_hook.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_cursor_adapter.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_default_action.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_deny_rule_reconciliation_1011.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_device.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_dlp_mask.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_dlp_scanner.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_doctor.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_engine_version_consistency.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_enrollment.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_env_dump_438.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_epic_1247_bryan_acceptance.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_error_codes.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_errors_e_codes.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_fail_closed_eval.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_failopen_1303.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_glob_matching.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_5d_email_install.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_6a_cli_flag.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_6a_exceptions.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_6a_get_secret_hitl.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_6a_mock_backend.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_6a_pending_approval.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_6a_request_approval.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_6a_secret_leak_guard.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_6a_wait.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_conformance.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_phase2b_protocol.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_reason_codes.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hitl_validator_keys.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hook_extractors.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hook_integrity.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hook_mask_failclosed.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hosted_local_audit_1247.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hosted_local_shadow_warn_1265.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hosted_policy_e2e.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hosts_adapter.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hybrid_mode_strict.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_hybrid_mode_warn.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_install_hook_command.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_install_hooks.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_io_capture_producer.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_kiro_adapter.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_kiro_cli_e2e.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_kiro_cli_hook_pin_1265.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_kiro_hook_templates.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_kiro_install.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_layout_migration_t101.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_layout_parity_t102.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_local_mode_dict.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_local_mode_file_json.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_local_mode_file_yaml.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_localized_reason.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_log_fallback_stderr.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_log_options_ignored_hosted.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_log_rotation.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_migrate.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_min_sdk_version_gate.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_multi_client_per_project_175.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_no_policy_no_key.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_observe_mode_1247.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_package_rename_shim.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_part3_active_policy_count_1303.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_per_client_isolation_1011.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_policy_engine_version_phase1b.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_policy_freshness.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_policy_load_failclosed_f3.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_policy_settings.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_policy_source_audit.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_pr4_install_messaging.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_pr4_output.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_pr4_status.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_probe_audit_isolation.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_quarantine.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_reason_code.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_refresh.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_secrets.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_secrets_reference_resolver.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_shell_semantic_class.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_source_labels.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_sql_semantic_class.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_synthetic_policy_id_t79.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_t103_precedence.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_t104_cache_gc.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_t108_local_override_audit.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_t96_single_audit_log.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_t99_install_prefetch_bundle.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_tamper.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_tamper_behavior.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_tamper_hook.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_telemetry_consent.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_tracecontext.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_unsafe_int_boundary.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_update_cmd.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tests/test_upgrade_nudge.py +0 -0
- {controlzero-1.13.1 → controlzero-1.13.2}/tools/cz-kiro-adapter +0 -0
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.13.2 (2026-06-28): kiro-cli 2.10 install crash + cross-adapter hook hardening
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **kiro-cli Windows / non-UTF-8 install crash (Ken Lee report).** `controlzero
|
|
8
|
+
kiro init` captured kiro-cli's output in text mode using the OS locale codec, so
|
|
9
|
+
kiro-cli's UTF-8 output crashed the install's subprocess reader thread on
|
|
10
|
+
non-UTF-8 Windows locales (Korean CP949, Japanese SJIS, Chinese GBK). That crash
|
|
11
|
+
could leave the governance agent not set as default, so `kiro-cli chat` then ran
|
|
12
|
+
the built-in default agent ungoverned (no hooks, no audit). All kiro-cli
|
|
13
|
+
shell-outs now decode as UTF-8 (`errors="replace"`) and never crash the install.
|
|
14
|
+
- **Codex hook-trust requirement surfaced at install.** Codex trust-gates the
|
|
15
|
+
non-managed `~/.codex/hooks.json` by hash and SKIPS it until trusted; the
|
|
16
|
+
installer now prints a loud ACTION-REQUIRED step (run `/hooks`, trust the Control
|
|
17
|
+
Zero hook, re-trust after every upgrade) instead of implying it enforces.
|
|
18
|
+
- **Gemini defensive hooks gate.** The installer writes `hooksConfig.enabled=true`
|
|
19
|
+
so an admin/older build with hooks gated off does not silently run ungoverned.
|
|
20
|
+
|
|
21
|
+
### Notes
|
|
22
|
+
|
|
23
|
+
- kiro-cli 2.10 was verified live to FIRE embedded agent-config `preToolUse` hooks;
|
|
24
|
+
the canonical tool-name matchers (`execute_bash`/`fs_write`/`fs_read`/`use_aws`)
|
|
25
|
+
and the `"*"` all-tools token are correct on 2.10 (both new `shell` and legacy
|
|
26
|
+
`execute_bash` names match).
|
|
27
|
+
|
|
3
28
|
## 1.13.1 (2026-06-27): shell semantic-class enforcement
|
|
4
29
|
|
|
5
30
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: controlzero
|
|
3
|
-
Version: 1.13.
|
|
3
|
+
Version: 1.13.2
|
|
4
4
|
Summary: AI agent governance: policies, audit, and observability for tool calls. Works locally with no signup.
|
|
5
5
|
Project-URL: Homepage, https://controlzero.ai
|
|
6
6
|
Project-URL: Documentation, https://docs.controlzero.ai
|
|
@@ -3737,12 +3737,30 @@ def install_gemini_cli(force: bool, merge: bool, settings: Optional[str], api_ke
|
|
|
3737
3737
|
]
|
|
3738
3738
|
before_tool.append(new_block)
|
|
3739
3739
|
|
|
3740
|
+
# Defensive gate (cross-adapter drift audit, 2026-06-28): the Gemini CLI
|
|
3741
|
+
# hooks subsystem is gated by hooksConfig.enabled. It defaults to true on
|
|
3742
|
+
# current builds, but an admin policy or an older/disabled build can leave
|
|
3743
|
+
# it off -- in which case our BeforeTool hook is silently never invoked
|
|
3744
|
+
# (enforcement off, verify still green). Write the gate explicitly and make
|
|
3745
|
+
# sure our hook is not in hooksConfig.disabled. Writing an unknown key is a
|
|
3746
|
+
# harmless no-op on builds that do not read it, so this only ever helps.
|
|
3747
|
+
hooks_config = existing.get("hooksConfig")
|
|
3748
|
+
if not isinstance(hooks_config, dict):
|
|
3749
|
+
hooks_config = {}
|
|
3750
|
+
existing["hooksConfig"] = hooks_config
|
|
3751
|
+
hooks_config["enabled"] = True
|
|
3752
|
+
disabled = hooks_config.get("disabled")
|
|
3753
|
+
if isinstance(disabled, list):
|
|
3754
|
+
hooks_config["disabled"] = [
|
|
3755
|
+
d for d in disabled if "controlzero" not in str(d)
|
|
3756
|
+
]
|
|
3757
|
+
|
|
3740
3758
|
settings_path.write_text(
|
|
3741
3759
|
json.dumps(existing, indent=2) + "\n",
|
|
3742
3760
|
encoding="utf-8",
|
|
3743
3761
|
)
|
|
3744
3762
|
_record_hook_baseline(settings_path)
|
|
3745
|
-
click.echo(f"Updated {settings_path} (added BeforeTool hook)")
|
|
3763
|
+
click.echo(f"Updated {settings_path} (added BeforeTool hook + hooksConfig.enabled)")
|
|
3746
3764
|
click.echo("")
|
|
3747
3765
|
click.echo("[Control Zero] Installed successfully.")
|
|
3748
3766
|
click.echo("")
|
|
@@ -3972,13 +3990,26 @@ def install_codex_cli(force: bool, merge: bool, config: Optional[str], api_key:
|
|
|
3972
3990
|
click.echo("")
|
|
3973
3991
|
click.echo("[Control Zero] Installed successfully.")
|
|
3974
3992
|
click.echo("")
|
|
3993
|
+
# Codex trust-gates command hooks BY HASH: ~/.codex/hooks.json is a
|
|
3994
|
+
# NON-managed hook, so Codex marks it "for review" and SKIPS it until the
|
|
3995
|
+
# user trusts it -- until then NO tool call is governed (enforcement is
|
|
3996
|
+
# silently OFF), and it re-locks on every upgrade that changes the hook
|
|
3997
|
+
# command/hash. This is the #1 silent-non-enforcement trap on Codex, so
|
|
3998
|
+
# surface it loudly. (developers.openai.com/codex/hooks; openai/codex#27833.)
|
|
3999
|
+
click.echo("[Control Zero] ACTION REQUIRED -- trust the hook or it will NOT run:")
|
|
4000
|
+
click.echo(" 1. Open Codex: codex")
|
|
4001
|
+
click.echo(" 2. Run /hooks and TRUST the Control Zero PreToolUse hook.")
|
|
4002
|
+
click.echo(" Until trusted, Codex SKIPS the hook and tools run UNGOVERNED.")
|
|
4003
|
+
click.echo(" 3. Re-trust after every Control Zero upgrade (the hook hash changes).")
|
|
4004
|
+
click.echo("")
|
|
3975
4005
|
_print_posture_summary(hosted, "codex-cli", posture_default_action, posture_rule_count)
|
|
3976
4006
|
if not hosted:
|
|
3977
4007
|
click.echo("")
|
|
3978
|
-
click.echo("
|
|
3979
|
-
click.echo(" 1.
|
|
3980
|
-
click.echo(" 2.
|
|
3981
|
-
click.echo("
|
|
4008
|
+
click.echo("Verify it ACTUALLY enforces (not just installed):")
|
|
4009
|
+
click.echo(" 1. In Codex, after trusting the hook, add a deny rule and try that tool.")
|
|
4010
|
+
click.echo(" 2. A governed call shows '[Control Zero] Allowed: <tool>'; a blocked one")
|
|
4011
|
+
click.echo(" shows '[Control Zero] <reason>'. If you see NEITHER, the hook is")
|
|
4012
|
+
click.echo(" untrusted/skipped -- re-run /hooks and trust it.")
|
|
3982
4013
|
click.echo("")
|
|
3983
4014
|
click.echo(f"Edit your policy: {GLOBAL_POLICY_PATH}")
|
|
3984
4015
|
click.echo(f"Audit log: {GLOBAL_AUDIT_PATH}")
|
|
@@ -4315,6 +4346,8 @@ def _cursor_enforcement_probe(installed_cmd: str) -> tuple:
|
|
|
4315
4346
|
shell=True,
|
|
4316
4347
|
input=json.dumps(payload),
|
|
4317
4348
|
text=True,
|
|
4349
|
+
encoding="utf-8",
|
|
4350
|
+
errors="replace",
|
|
4318
4351
|
capture_output=True,
|
|
4319
4352
|
env=probe_env,
|
|
4320
4353
|
timeout=15,
|
|
@@ -5241,9 +5274,19 @@ _KIRO_V3_AGENT_NAME = "controlzero"
|
|
|
5241
5274
|
_KIRO_V3_AGENT_DESCRIPTION = "Control Zero governance"
|
|
5242
5275
|
# kiro-cli's built-in default agent -- what the default is restored to on uninstall.
|
|
5243
5276
|
_KIRO_V3_BUILTIN_DEFAULT_AGENT = "kiro_default"
|
|
5244
|
-
# Internal Kiro tool names for the BLOCKING preToolUse trigger.
|
|
5245
|
-
#
|
|
5246
|
-
#
|
|
5277
|
+
# Internal Kiro tool names for the BLOCKING preToolUse trigger. The matcher is
|
|
5278
|
+
# evaluated against kiro-cli's CANONICAL internal tool names (execute_bash /
|
|
5279
|
+
# fs_write / fs_read / use_aws); kiro normalizes the simplified aliases
|
|
5280
|
+
# (shell / write / read / aws) to these, so the canonical matchers fire on every
|
|
5281
|
+
# kiro-cli version (verified against current kiro docs + #4810/#4867 by the
|
|
5282
|
+
# 2026-06-28 cross-adapter drift audit). postToolUse is observe-only and uses
|
|
5283
|
+
# the documented "*" all-tools token. Pinned by
|
|
5284
|
+
# tests/test_kiro_cli_v210_hooks.py -- do NOT rewrite into a "shell|..."
|
|
5285
|
+
# alternation on the belief a tool rename broke them: it did not.
|
|
5286
|
+
#
|
|
5287
|
+
# NOTE: the Ken Lee kiro-cli 2.10 hooks-not-firing report is a SEPARATE issue
|
|
5288
|
+
# (install-time encoding/locale + the Kiro IDE >=1.0.0 legacy-schema drift),
|
|
5289
|
+
# NOT a preToolUse tool-name rename. Do not conflate.
|
|
5247
5290
|
_KIRO_V3_PRE_TOOL_MATCHERS = ("execute_bash", "fs_write", "fs_read", "use_aws")
|
|
5248
5291
|
|
|
5249
5292
|
|
|
@@ -5290,9 +5333,21 @@ def _kiro_v3_set_default_agent(agent_name: str) -> tuple:
|
|
|
5290
5333
|
["kiro-cli", "agent", "set-default", agent_name],
|
|
5291
5334
|
capture_output=True,
|
|
5292
5335
|
text=True,
|
|
5336
|
+
# Decode kiro-cli's UTF-8 output as UTF-8, NOT the OS locale codec.
|
|
5337
|
+
# Without this, text=True uses locale.getpreferredencoding() -- e.g.
|
|
5338
|
+
# CP949 on Korean Windows, SJIS on Japanese, GBK on Chinese -- and
|
|
5339
|
+
# kiro-cli's em-dash/arrow output (byte 0xe2...) crashes the
|
|
5340
|
+
# subprocess reader thread (UnicodeDecodeError). errors="replace"
|
|
5341
|
+
# keeps any stray non-UTF-8 byte from ever crashing the install.
|
|
5342
|
+
encoding="utf-8",
|
|
5343
|
+
errors="replace",
|
|
5293
5344
|
timeout=15,
|
|
5294
5345
|
)
|
|
5295
|
-
|
|
5346
|
+
# Honor the "NEVER raises" contract: a best-effort kiro-cli shell-out must
|
|
5347
|
+
# not crash `kiro init`. OSError/SubprocessError cover absent/failed
|
|
5348
|
+
# kiro-cli; the broad guard also covers a decode/runtime surprise so the
|
|
5349
|
+
# caller can turn it into a loud WARNING instead of a traceback.
|
|
5350
|
+
except Exception as e: # noqa: BLE001 -- best-effort, see docstring
|
|
5296
5351
|
return False, str(e)
|
|
5297
5352
|
detail = ((proc.stdout or "") + (proc.stderr or "")).strip()
|
|
5298
5353
|
return proc.returncode == 0, detail
|
|
@@ -5319,9 +5374,14 @@ def _kiro_v3_create_agent_from_default() -> tuple:
|
|
|
5319
5374
|
],
|
|
5320
5375
|
capture_output=True,
|
|
5321
5376
|
text=True,
|
|
5377
|
+
# See _kiro_v3_set_default_agent: decode as UTF-8 (not the OS locale
|
|
5378
|
+
# codec) so non-ASCII kiro-cli output cannot crash the install on
|
|
5379
|
+
# CP949/SJIS/GBK Windows.
|
|
5380
|
+
encoding="utf-8",
|
|
5381
|
+
errors="replace",
|
|
5322
5382
|
timeout=15,
|
|
5323
5383
|
)
|
|
5324
|
-
except
|
|
5384
|
+
except Exception as e: # noqa: BLE001 -- best-effort, NEVER raises (docstring)
|
|
5325
5385
|
return False, str(e)
|
|
5326
5386
|
detail = ((proc.stdout or "") + (proc.stderr or "")).strip()
|
|
5327
5387
|
return proc.returncode == 0, detail
|
|
@@ -6005,6 +6065,8 @@ def _kiro_cli_enforcement_probe(installed_cmd: str) -> tuple:
|
|
|
6005
6065
|
shell=True,
|
|
6006
6066
|
input=json.dumps(payload),
|
|
6007
6067
|
text=True,
|
|
6068
|
+
encoding="utf-8",
|
|
6069
|
+
errors="replace",
|
|
6008
6070
|
capture_output=True,
|
|
6009
6071
|
env=probe_env,
|
|
6010
6072
|
timeout=15,
|
|
@@ -6169,6 +6231,8 @@ def kiro_verify(settings: Optional[str]) -> None:
|
|
|
6169
6231
|
shell=True,
|
|
6170
6232
|
input=json.dumps(payload),
|
|
6171
6233
|
text=True,
|
|
6234
|
+
encoding="utf-8",
|
|
6235
|
+
errors="replace",
|
|
6172
6236
|
capture_output=True,
|
|
6173
6237
|
env=env,
|
|
6174
6238
|
)
|
|
@@ -6178,6 +6242,8 @@ def kiro_verify(settings: Optional[str]) -> None:
|
|
|
6178
6242
|
"--policy", str(pol)],
|
|
6179
6243
|
input=json.dumps(payload),
|
|
6180
6244
|
text=True,
|
|
6245
|
+
encoding="utf-8",
|
|
6246
|
+
errors="replace",
|
|
6181
6247
|
capture_output=True,
|
|
6182
6248
|
env=env,
|
|
6183
6249
|
)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "controlzero"
|
|
7
|
-
version = "1.13.
|
|
7
|
+
version = "1.13.2"
|
|
8
8
|
description = "AI agent governance: policies, audit, and observability for tool calls. Works locally with no signup."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "Apache-2.0"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Regression tests for the kiro-cli install hardening (Ken Lee, 2026-06-28).
|
|
2
|
+
|
|
3
|
+
The Ken Lee kiro-cli 2.10 report had TWO themes; this file guards the part that
|
|
4
|
+
is a confirmed, code-level defect: the CP949 / locale ENCODING crash. The
|
|
5
|
+
2026-06-28 cross-adapter drift audit verified the preToolUse MATCHERS were NOT
|
|
6
|
+
the cause (kiro normalizes the simplified tool aliases shell/write/read/aws to
|
|
7
|
+
the canonical names execute_bash/fs_write/fs_read/use_aws, so the canonical
|
|
8
|
+
matchers fire on every kiro-cli version -- kiro #4810/#4867). These tests pin
|
|
9
|
+
the canonical matchers so they are never "fixed" into an alias alternation, and
|
|
10
|
+
guard the encoding fix.
|
|
11
|
+
|
|
12
|
+
ENCODING bug: the kiro-cli shell-outs captured output in text mode using the OS
|
|
13
|
+
locale codec, so kiro-cli's UTF-8 output (em-dash / arrow, byte 0xe2...) crashed
|
|
14
|
+
the subprocess reader thread on non-UTF-8 Windows locales (Korean CP949,
|
|
15
|
+
Japanese SJIS, Chinese GBK). All kiro-cli shell-outs now decode as
|
|
16
|
+
encoding="utf-8", errors="replace" and honor the "NEVER raises" contract.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import re
|
|
20
|
+
import subprocess
|
|
21
|
+
|
|
22
|
+
from controlzero.cli import main as m
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# ---------------------------------------------------------------------------
|
|
26
|
+
# Matchers: pin the canonical set (audit-verified correct) so it is never
|
|
27
|
+
# rewritten into an alias alternation on a mistaken "rename broke it" belief.
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
def test_pretooluse_matchers_are_the_canonical_kiro_tool_names():
|
|
30
|
+
assert m._KIRO_V3_PRE_TOOL_MATCHERS == (
|
|
31
|
+
"execute_bash",
|
|
32
|
+
"fs_write",
|
|
33
|
+
"fs_read",
|
|
34
|
+
"use_aws",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_pretooluse_matchers_are_valid_regex_and_match_their_canonical_tool():
|
|
39
|
+
"""Each canonical matcher is a valid regex (a malformed matcher silently
|
|
40
|
+
never fires) and matches its own tool name."""
|
|
41
|
+
for tool in m._KIRO_V3_PRE_TOOL_MATCHERS:
|
|
42
|
+
re.compile(tool) # raises re.error if invalid
|
|
43
|
+
assert re.search(tool, tool)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_posttooluse_uses_the_documented_all_tools_token():
|
|
47
|
+
"""postToolUse is observe-only and uses kiro's documented "*" all-tools
|
|
48
|
+
token (special-cased by kiro, not a raw regex)."""
|
|
49
|
+
hooks = m._kiro_v3_canonical_hooks()
|
|
50
|
+
assert hooks["postToolUse"][0]["matcher"] == "*"
|
|
51
|
+
# preToolUse entries are the canonical names.
|
|
52
|
+
pre_matchers = [h["matcher"] for h in hooks["preToolUse"]]
|
|
53
|
+
assert pre_matchers == list(m._KIRO_V3_PRE_TOOL_MATCHERS)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# ---------------------------------------------------------------------------
|
|
57
|
+
# Encoding: kiro-cli shell-outs decode as UTF-8 and never crash the install.
|
|
58
|
+
# ---------------------------------------------------------------------------
|
|
59
|
+
def test_set_default_agent_decodes_utf8_not_locale_codec(monkeypatch):
|
|
60
|
+
"""encoding='utf-8', errors='replace' so kiro-cli's non-ASCII output cannot
|
|
61
|
+
crash the reader thread on CP949/SJIS/GBK Windows."""
|
|
62
|
+
seen = {}
|
|
63
|
+
|
|
64
|
+
class FakeProc:
|
|
65
|
+
returncode = 0
|
|
66
|
+
stdout = "set-default ok"
|
|
67
|
+
stderr = ""
|
|
68
|
+
|
|
69
|
+
def fake_run(*args, **kwargs):
|
|
70
|
+
seen.update(kwargs)
|
|
71
|
+
return FakeProc()
|
|
72
|
+
|
|
73
|
+
monkeypatch.setattr(subprocess, "run", fake_run)
|
|
74
|
+
ok, _detail = m._kiro_v3_set_default_agent("controlzero")
|
|
75
|
+
assert ok is True
|
|
76
|
+
assert seen.get("encoding") == "utf-8"
|
|
77
|
+
assert seen.get("errors") == "replace"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_create_agent_from_default_decodes_utf8(monkeypatch):
|
|
81
|
+
seen = {}
|
|
82
|
+
|
|
83
|
+
class FakeProc:
|
|
84
|
+
returncode = 0
|
|
85
|
+
stdout = ""
|
|
86
|
+
stderr = ""
|
|
87
|
+
|
|
88
|
+
def fake_run(*args, **kwargs):
|
|
89
|
+
seen.update(kwargs)
|
|
90
|
+
return FakeProc()
|
|
91
|
+
|
|
92
|
+
monkeypatch.setattr(subprocess, "run", fake_run)
|
|
93
|
+
ok, _detail = m._kiro_v3_create_agent_from_default()
|
|
94
|
+
assert ok is True
|
|
95
|
+
assert seen.get("encoding") == "utf-8"
|
|
96
|
+
assert seen.get("errors") == "replace"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_set_default_agent_never_raises_on_any_subprocess_error(monkeypatch):
|
|
100
|
+
"""The 'NEVER raises' contract: a decode/runtime surprise must become a
|
|
101
|
+
(False, detail) the caller turns into a loud WARNING, not a traceback that
|
|
102
|
+
aborts `kiro init` (the Thread-2 _readerthread crash Ken saw)."""
|
|
103
|
+
|
|
104
|
+
def boom(*args, **kwargs):
|
|
105
|
+
raise UnicodeDecodeError("cp949", b"\xe2", 0, 1, "illegal multibyte sequence")
|
|
106
|
+
|
|
107
|
+
monkeypatch.setattr(subprocess, "run", boom)
|
|
108
|
+
ok, detail = m._kiro_v3_set_default_agent("controlzero")
|
|
109
|
+
assert ok is False
|
|
110
|
+
assert detail # carries the error string for the WARNING
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/credentials_data/__init__.py
RENAMED
|
File without changes
|
{controlzero-1.13.1 → controlzero-1.13.2}/controlzero/_internal/credentials_data/built_in.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/kiro/ide-file-save.kiro.hook
RENAMED
|
File without changes
|
{controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/kiro/ide-pre-tool-use.kiro.hook
RENAMED
|
File without changes
|
{controlzero-1.13.1 → controlzero-1.13.2}/controlzero/cli/templates/kiro/ide-prompt-submit.kiro.hook
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|