sourcecode 3.2.2__tar.gz → 3.3.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.
- {sourcecode-3.2.2 → sourcecode-3.3.0}/CHANGELOG.md +11 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/PKG-INFO +1 -1
- {sourcecode-3.2.2 → sourcecode-3.3.0}/pyproject.toml +1 -1
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/cli.py +33 -36
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/license.py +68 -6
- {sourcecode-3.2.2 → sourcecode-3.3.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/.gitignore +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/.ruff.toml +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/CONTRIBUTING.md +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/LICENSE +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/README.md +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/SECURITY.md +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/raw +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/scripts/perf_harness.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/archetype.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/architectural_baseline.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/architectural_delta.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/cache.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/cache_model.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/chain_rules.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/change_plan.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/compare.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/constraint_diff.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/contract_diff.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/deployment_prefix.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/envelope.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/explain.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/facts/__init__.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/facts/registry.json +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/filter_surface.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/integration_coordinates.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/migration_blast.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/parse_cache.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/perf.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/posture.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/readiness_timeline.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/reference_facts.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/repository_ir.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/ris.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/security_config.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/serializer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_profiles.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_properties.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/test_sources.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/token_estimate.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/verify_edit.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/verify_repo.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/verify_rules.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/version_check.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/functions/README.md +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-3.2.2 → sourcecode-3.3.0}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [3.3.0] — 2026-07-29
|
|
6
|
+
|
|
7
|
+
**A default you must remember to disable is the wrong default for someone else's code.**
|
|
8
|
+
Telemetry moves from opt-out to opt-in. A minor and not a patch: no API changed, but a default
|
|
9
|
+
about data leaving the machine did, and that is a change a user must be told about rather than
|
|
10
|
+
discover.
|
|
11
|
+
|
|
12
|
+
**Upgrade note.** If you ever ran `ask telemetry enable` or `ask telemetry disable`, nothing
|
|
13
|
+
changes for you — your choice is on record and is honoured. If you never chose, telemetry is
|
|
14
|
+
now off and `ask telemetry enable` is how you turn it on.
|
|
15
|
+
|
|
5
16
|
### Changed
|
|
6
17
|
|
|
7
18
|
- **Telemetry is opt-in** (P-1). It was opt-out; with no explicit choice on record, nothing is
|
|
@@ -8105,47 +8105,44 @@ def auth_status_cmd() -> None:
|
|
|
8105
8105
|
"""Show current authentication and plan status."""
|
|
8106
8106
|
import json as _json
|
|
8107
8107
|
try:
|
|
8108
|
-
from sourcecode.license import
|
|
8109
|
-
|
|
8110
|
-
_license_data as _ld,
|
|
8111
|
-
is_pro as _ip,
|
|
8112
|
-
)
|
|
8108
|
+
from sourcecode.license import _license_data as _ld, entitlement as _entitlement
|
|
8109
|
+
_ent = _entitlement()
|
|
8113
8110
|
except Exception:
|
|
8114
8111
|
_ld = None
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
# While the early-adoption unlock is on, every Pro command runs. Reporting
|
|
8119
|
-
# `pro: false` here contradicted the --help header and the commands' own
|
|
8120
|
-
# behaviour: the status has to describe the gating that is actually in force,
|
|
8121
|
-
# not the credential that happens to be absent.
|
|
8122
|
-
_gating = {
|
|
8123
|
-
"pro_gating": "disabled" if _unlock else "enabled",
|
|
8124
|
-
"pro_effective": bool(_ip or _unlock),
|
|
8125
|
-
}
|
|
8126
|
-
if _unlock:
|
|
8127
|
-
_gating["pro_reason"] = "early-adoption unlock: Pro commands run without a license"
|
|
8128
|
-
|
|
8129
|
-
if not _ld:
|
|
8130
|
-
out: dict = {
|
|
8131
|
-
"status": "unauthenticated",
|
|
8132
|
-
"pro": bool(_unlock),
|
|
8133
|
-
**_gating,
|
|
8112
|
+
_ent = {
|
|
8113
|
+
"entitlement": "free", "source": "free_tier", "authenticated": False,
|
|
8114
|
+
"paywall_active": True, "when_it_changes": "", "free_repo_java_file_limit": None,
|
|
8134
8115
|
}
|
|
8135
|
-
sys.stdout.write(_json.dumps(out, ensure_ascii=False) + "\n")
|
|
8136
|
-
sys.stdout.flush()
|
|
8137
|
-
return
|
|
8138
8116
|
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
"pro":
|
|
8146
|
-
"
|
|
8147
|
-
|
|
8117
|
+
# P-2: one authority (`license.entitlement`) answers "what runs here, and why".
|
|
8118
|
+
# The legacy keys below are *derived* from it rather than computed a second
|
|
8119
|
+
# time — that is what stops `{"status": "unauthenticated", "pro": true}` from
|
|
8120
|
+
# reappearing. They are deprecated and will be removed in a future major.
|
|
8121
|
+
_pro = _ent["entitlement"] == "pro"
|
|
8122
|
+
_legacy = {
|
|
8123
|
+
"pro": _pro,
|
|
8124
|
+
"pro_effective": _pro,
|
|
8125
|
+
"pro_gating": "enabled" if _ent["paywall_active"] else "disabled",
|
|
8148
8126
|
}
|
|
8127
|
+
if _ent["source"] == "early_adoption_unlock":
|
|
8128
|
+
_legacy["pro_reason"] = "early-adoption unlock: Pro commands run without a license"
|
|
8129
|
+
|
|
8130
|
+
out: dict = {
|
|
8131
|
+
"status": "authenticated" if _ent["authenticated"] else "unauthenticated",
|
|
8132
|
+
**_ent,
|
|
8133
|
+
**_legacy,
|
|
8134
|
+
"deprecated_fields": ["pro", "pro_effective", "pro_gating", "pro_reason"],
|
|
8135
|
+
}
|
|
8136
|
+
if _ld:
|
|
8137
|
+
out.update({
|
|
8138
|
+
"auth_method": _ld.get("auth_method", "license_key"),
|
|
8139
|
+
"email": _ld.get("email", ""),
|
|
8140
|
+
"plan": _ld.get("plan", "unknown"),
|
|
8141
|
+
# The authority reads a missing status as active, so reporting
|
|
8142
|
+
# "unknown" here would contradict the entitlement in the same object.
|
|
8143
|
+
"plan_status": _ld.get("status", "active"),
|
|
8144
|
+
"validated_at": _ld.get("validated_at") or _ld.get("activated_at") or "",
|
|
8145
|
+
})
|
|
8149
8146
|
sys.stdout.write(_json.dumps(out, indent=2, ensure_ascii=False) + "\n")
|
|
8150
8147
|
sys.stdout.flush()
|
|
8151
8148
|
|
|
@@ -376,16 +376,78 @@ def _maybe_revalidate() -> None:
|
|
|
376
376
|
pass
|
|
377
377
|
|
|
378
378
|
|
|
379
|
-
def
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
379
|
+
def entitlement() -> dict:
|
|
380
|
+
"""The one answer to "what runs here today, and why" (P-2).
|
|
381
|
+
|
|
382
|
+
`auth status` used to publish four fields about this — `status`, `pro`,
|
|
383
|
+
`pro_gating`, `pro_effective`, plus a `pro_reason` sentence — and they read as
|
|
384
|
+
a contradiction: `{"status": "unauthenticated", "pro": true}`. Each field was
|
|
385
|
+
true on its own axis; together they told a buyer nothing about what they have,
|
|
386
|
+
why they have it, or what changes when it ends. That is the ADR-0008 pattern
|
|
387
|
+
exactly, on the commercial surface instead of an analysis one.
|
|
388
|
+
|
|
389
|
+
Every published entitlement field is derived from this dict and nowhere else.
|
|
390
|
+
|
|
391
|
+
Keys:
|
|
392
|
+
entitlement "pro" | "free" — what actually runs right now
|
|
393
|
+
source why: "license_key" | "early_adoption_unlock" | "free_tier"
|
|
394
|
+
authenticated whether a credential is on this machine (an independent
|
|
395
|
+
fact: today one can be entitled to Pro without one)
|
|
396
|
+
paywall_active whether the paywall is enforcing anything at all
|
|
397
|
+
when_it_changes what a user loses when `source` stops applying, in the
|
|
398
|
+
terms the gate actually uses — never a price
|
|
399
|
+
free_repo_java_file_limit
|
|
400
|
+
the number the size gate compares against
|
|
401
|
+
"""
|
|
402
|
+
authenticated = _license_data is not None
|
|
403
|
+
licensed = bool(
|
|
383
404
|
_license_data is not None
|
|
384
405
|
and _license_data.get("plan") == "pro"
|
|
385
406
|
and _license_data.get("status", "active") != "inactive"
|
|
386
407
|
)
|
|
387
|
-
if
|
|
388
|
-
|
|
408
|
+
if licensed:
|
|
409
|
+
source = "license_key"
|
|
410
|
+
elif _PRO_UNLOCK_ALL:
|
|
411
|
+
source = "early_adoption_unlock"
|
|
412
|
+
else:
|
|
413
|
+
source = "free_tier"
|
|
414
|
+
|
|
415
|
+
if source == "license_key":
|
|
416
|
+
when = "Your licence entitles you to Pro; nothing changes while it stays active."
|
|
417
|
+
elif source == "early_adoption_unlock":
|
|
418
|
+
when = (
|
|
419
|
+
"Pro runs without a licence during early adoption. When that ends, every command "
|
|
420
|
+
f"still runs at full output on repositories up to {_FREE_REPO_JAVA_FILE_LIMIT} Java "
|
|
421
|
+
"source files; above that, the heavy-analysis commands ask for Pro. Capability is "
|
|
422
|
+
"never what is gated — size, automation and team are."
|
|
423
|
+
)
|
|
424
|
+
else:
|
|
425
|
+
when = (
|
|
426
|
+
f"Every command runs at full output on repositories up to {_FREE_REPO_JAVA_FILE_LIMIT} "
|
|
427
|
+
"Java source files. Above that, the heavy-analysis commands require Pro."
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
return {
|
|
431
|
+
"entitlement": "pro" if (licensed or _PRO_UNLOCK_ALL) else "free",
|
|
432
|
+
"source": source,
|
|
433
|
+
"authenticated": authenticated,
|
|
434
|
+
"paywall_active": not _PRO_UNLOCK_ALL,
|
|
435
|
+
"when_it_changes": when,
|
|
436
|
+
"free_repo_java_file_limit": _FREE_REPO_JAVA_FILE_LIMIT,
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def _init() -> None:
|
|
441
|
+
"""Load the credential and derive the entitlement from the one authority.
|
|
442
|
+
|
|
443
|
+
`is_pro` is what every gate reads (`can_use`, `require_feature`), and it is
|
|
444
|
+
computed here from `entitlement()` rather than beside it — a second copy of
|
|
445
|
+
this rule is how `auth status` came to publish a state the commands
|
|
446
|
+
contradicted (P-2).
|
|
447
|
+
"""
|
|
448
|
+
global _license_data, is_pro
|
|
449
|
+
_license_data = _load_license_file()
|
|
450
|
+
is_pro = entitlement()["entitlement"] == "pro"
|
|
389
451
|
|
|
390
452
|
|
|
391
453
|
_init()
|
|
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
|
|
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
|
|
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
|
|
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
|