cartograph-cli 0.7.2__tar.gz → 0.7.4__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.
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/CLAUDE.md +0 -32
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/PKG-INFO +1 -1
- cartograph_cli-0.7.4/cg/cg_universal_graph_cycles_python/.validation_stamp.json +1 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/widget.json +3 -3
- cartograph_cli-0.7.4/cg/infra_agent_cli_python/.cartograph_source +1 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/widget.json +5 -5
- cartograph_cli-0.7.4/cg/infra_archive_manifest_consistency_python/examples/example_usage.py +53 -0
- cartograph_cli-0.7.4/cg/infra_archive_manifest_consistency_python/src/archive_manifest_consistency.py +107 -0
- cartograph_cli-0.7.4/cg/infra_archive_manifest_consistency_python/tests/test_archive_manifest_consistency.py +148 -0
- cartograph_cli-0.7.4/cg/infra_archive_manifest_consistency_python/widget.json +31 -0
- cartograph_cli-0.7.4/cg/infra_file_stamp_python/.validation_stamp.json +1 -0
- cartograph_cli-0.7.4/cg/infra_file_stamp_python/widget.json +30 -0
- cartograph_cli-0.7.4/cg/universal_block_walker_python/src/__init__.py +1 -0
- cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/.validation_stamp.json +1 -0
- cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/examples/example_usage.py +54 -0
- cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/src/__init__.py +1 -0
- cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/src/ttl_disk_cache.py +122 -0
- cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/tests/test_ttl_disk_cache.py +197 -0
- cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/widget.json +31 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/pyproject.toml +1 -1
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/__init__.py +2 -0
- cartograph_cli-0.7.4/src/cartograph/architect/markdown.py +187 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/auth.py +46 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/cli.py +340 -340
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/config.py +16 -1
- cartograph_cli-0.7.4/src/cartograph/search/ngram.py +109 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_cli_contract.py +2 -2
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_search.py +35 -0
- cartograph_cli-0.7.2/cg/infra_agent_cli_python/.validation_stamp.json +0 -1
- cartograph_cli-0.7.2/cg/infra_file_stamp_python/.validation_stamp.json +0 -1
- cartograph_cli-0.7.2/cg/infra_file_stamp_python/widget.json +0 -24
- cartograph_cli-0.7.2/src/cartograph/search/ngram.py +0 -83
- cartograph_cli-0.7.2/tests/test_architect.py +0 -895
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.githooks/pre-push +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.github/FUNDING.yml +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.github/workflows/fresh-install.yml +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.github/workflows/publish.yml +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.github/workflows/test.yml +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.gitignore +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/CONTRIBUTING.md +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/LICENSE +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/README.md +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/VALIDATION.md +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/architect.mmd +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/architect.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/.cartograph_source +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/src/graph_cycles.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/tests/test_graph_cycles.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/.validation_stamp.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/src/mermaid_graph_renderer.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/tests/test_mermaid_graph_renderer.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_python_module_loader_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_python_module_loader_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_python_module_loader_python/src/python_module_loader.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_python_module_loader_python/tests/test_python_module_loader.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_python_module_loader_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/src/agent_cli.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/tests/test_agent_cli.py +0 -0
- {cartograph_cli-0.7.2/cg/infra_directory_tarball_python → cartograph_cli-0.7.4/cg/infra_archive_manifest_consistency_python}/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/.validation_stamp.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/src/binary_resolver.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/tests/test_binary_resolver.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/.validation_stamp.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/src/command_catalog.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/tests/test_command_catalog.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_directory_tarball_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2/cg/infra_file_stamp_python → cartograph_cli-0.7.4/cg/infra_directory_tarball_python}/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_directory_tarball_python/src/directory_tarball.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_directory_tarball_python/tests/test_directory_tarball.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_directory_tarball_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_file_stamp_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2/cg/infra_pinned_deps_resolver_python → cartograph_cli-0.7.4/cg/infra_file_stamp_python}/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_file_stamp_python/src/file_stamp.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_file_stamp_python/tests/test_file_stamp.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/.validation_stamp.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/src/http_endpoint_registry.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/tests/test_http_endpoint_registry.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/.validation_stamp.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/src/openapi_generator.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/tests/test_openapi_generator.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_pinned_deps_resolver_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2/cg/infra_prefix_router_python → cartograph_cli-0.7.4/cg/infra_pinned_deps_resolver_python}/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_pinned_deps_resolver_python/src/pinned_deps_resolver.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_pinned_deps_resolver_python/tests/test_pinned_deps_resolver.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_pinned_deps_resolver_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_prefix_router_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2/cg/infra_version_bump_policy_python → cartograph_cli-0.7.4/cg/infra_prefix_router_python}/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_prefix_router_python/src/prefix_router.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_prefix_router_python/tests/test_prefix_router.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_prefix_router_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/.validation_stamp.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/src/urllib_client.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/tests/test_urllib_client.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_version_bump_policy_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2/cg/universal_block_walker_python → cartograph_cli-0.7.4/cg/infra_version_bump_policy_python}/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_version_bump_policy_python/src/version_bump_policy.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_version_bump_policy_python/tests/test_version_bump_policy.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_version_bump_policy_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/.validation_stamp.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/src/block_walker.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/tests/test_block_walker.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/.validation_stamp.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/src/build_artifact_ignore.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/tests/test_build_artifact_ignore.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/.validation_stamp.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/examples/example_usage.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/src/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/src/list_paginator.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/tests/test_list_paginator.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/widget.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/docs/languages/nim.md +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-1024.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-128.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-256.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-512.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black-1024.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black-128.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black-256.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black-512.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black.svg +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white-1024.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white-128.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white-256.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white-512.png +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white.svg +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph.svg +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/pytest.ini +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/scripts/bump_version.sh +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/scripts/preflight.sh +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/__main__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/loader.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/mutate.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/paths.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/renderer.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/scaffold.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/schema.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/validator.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_checkin.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_deps.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_install.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_publish.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_status.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_validator.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprints.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/checkin.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/cloud.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/contamination.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/dashboard.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/dashboard_ui.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/engine.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/inspector.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/installer.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/angular.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/base.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/javascript.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/nim.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/openscad.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/php.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/python.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/registry.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/scanners/js_scanner.js +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/scanners/nim_scanner.nim +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/systemverilog.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/terraform.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/library_config.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/manifest.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/rules.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/scaffolding/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/filters.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/hybrid.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/synonyms.json +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/tfidf.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/trust.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/update_check.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/validation_stamp.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/validator.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/__init__.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/cloud_health.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/conftest.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/fresh_install/Dockerfile +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/fresh_install/test_fresh_install.sh +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_auth.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_checkin.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_contamination.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_create.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_deps.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_install.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_languages.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_publish.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_search_inspect.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_status.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_validator.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprints.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_checkin.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_checkin_publish.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_cloud_zip.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_config.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_contamination.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_create.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_inspect.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_install.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_language_engines.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_library_integrity.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_loading.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_manifest.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_rules.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_setup.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_update_check.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_upgrade.py +0 -0
- {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_validate.py +0 -0
|
@@ -107,38 +107,6 @@ current directory (or the directory specified by `--target`).
|
|
|
107
107
|
rules reset --language <lang> [--global]
|
|
108
108
|
Restore a rules file to its default template.
|
|
109
109
|
|
|
110
|
-
**Architect (project-level planning)**
|
|
111
|
-
|
|
112
|
-
architect init [--path X] [--force]
|
|
113
|
-
Scaffold a starter architect.py at the project root. Architect is
|
|
114
|
-
a project-local Python file describing components and relationships
|
|
115
|
-
(cross-domain: software, modeling, rtl, physical). The agent reads
|
|
116
|
-
it for app-level planning context before reaching for widgets.
|
|
117
|
-
|
|
118
|
-
architect validate [--path X]
|
|
119
|
-
Structural checks only: unique component ids, edge/parent ref
|
|
120
|
-
integrity, parent cycles, schema_version, known domains. The
|
|
121
|
-
vibes layer (kind/description/what) is intentionally not checked.
|
|
122
|
-
|
|
123
|
-
architect render [--path X] [--output X | --stdout] [--direction TD|TB|LR|BT|RL] [--force]
|
|
124
|
-
Render architect.py as a Mermaid flowchart. Defaults to writing
|
|
125
|
-
architect.mmd next to the source so it commits cleanly and renders
|
|
126
|
-
in GitHub. Refuses to render an invalid architecture unless --force.
|
|
127
|
-
|
|
128
|
-
architect link <component_id> <widget_dir> [--path X]
|
|
129
|
-
Link an installed widget to a Component slot. Multiple widgets
|
|
130
|
-
may compose one slot (router + validator + logger as one
|
|
131
|
-
service). Refuses if the widget is not installed under cg/, or
|
|
132
|
-
if it is already linked.
|
|
133
|
-
|
|
134
|
-
architect link <component_id> <widget_dir> --clear [--path X]
|
|
135
|
-
Unlink a specific widget from a Component slot.
|
|
136
|
-
|
|
137
|
-
architect link <component_id> --clear [--path X]
|
|
138
|
-
Unlink ALL widgets from a Component slot. Edits architect.py via
|
|
139
|
-
AST surgery; comments outside the target Component block are
|
|
140
|
-
preserved.
|
|
141
|
-
|
|
142
110
|
**Configuration**
|
|
143
111
|
|
|
144
112
|
config [key] [value]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fingerprint": "b5dd0d134e637c9c93f85aababe75e58bdfcb7e0ad2457490f677fcfe3f2071c", "stamped_at": "2026-06-04T21:40:30.314561+00:00", "language": "python", "engine_version": 1, "runtime": "python 3.14.5", "test_results": {}, "validated_at": "2026-06-04T21:40:30.314237+00:00"}
|
{cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/widget.json
RENAMED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"meta": {
|
|
3
3
|
"id": "universal-graph-cycles-python",
|
|
4
4
|
"name": "Graph Cycles",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.1",
|
|
6
6
|
"domain": "universal",
|
|
7
7
|
"tags": [
|
|
8
8
|
"graph",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"validation": {
|
|
27
27
|
"engine_version": 1,
|
|
28
|
-
"validated_at": "2026-
|
|
29
|
-
"runtime": "python 3.
|
|
28
|
+
"validated_at": "2026-06-04T21:40:31.582833+00:00",
|
|
29
|
+
"runtime": "python 3.14.5"
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"owner": "benteigland11", "registry_url": "https://api.cartograph.tools"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"meta": {
|
|
3
3
|
"id": "infra-agent-cli-python",
|
|
4
4
|
"name": "Agent CLI",
|
|
5
|
-
"version": "1.2.
|
|
5
|
+
"version": "1.2.2",
|
|
6
6
|
"domain": "infra",
|
|
7
7
|
"tags": [
|
|
8
8
|
"cli",
|
|
@@ -12,19 +12,19 @@
|
|
|
12
12
|
"llm-tools"
|
|
13
13
|
]
|
|
14
14
|
},
|
|
15
|
-
"description": "Declarative CLI framework for LLM/agent-driven tools. JSON output,
|
|
15
|
+
"description": "Declarative CLI framework that provides machine-first argparse wiring for LLM/agent-driven tools. Features JSON-first output, non-interactive execution, and grouped help.",
|
|
16
16
|
"tech_stack": {
|
|
17
17
|
"language": "python",
|
|
18
18
|
"dependencies": []
|
|
19
19
|
},
|
|
20
20
|
"library_notes": {
|
|
21
21
|
"general": "Single responsibility - one widget does one thing. No global state. No project-specific code, hardcoded paths, credentials, or environment-specific values. Expose variation points as constructor parameters or function arguments - no hardcoded thresholds, colors, sizes, or behavior flags. URLs and endpoints belong in examples as demonstration data, not in src/ - if a widget needs a URL to operate, it must be a parameter the caller provides. All dependencies must be declared in widget.json tech_stack.dependencies. Widgets cannot depend on other widgets - they must be fully self-contained. If you need logic from another widget, copy it into src/ directly. Examples must run and exit cleanly with no user input, no network calls, and no external services or API keys - use fake/hardcoded data. The widget's own declared dependencies are fine and will be installed by the validator before the example runs. Do not modify library_notes - it is managed by Cartograph and will be restored on checkin.",
|
|
22
|
-
"language": "No project-specific names, identifiers, or terminology anywhere in src/, tests/, or examples/ - use generic names like 'user', 'item', 'value', 'example_org'. A test that references your project's real entity names is contaminated. Use pytest for all tests - no unittest. Type hints required on all public functions. No __init__.py in tests/. No if __name__ == '__main__' blocks in src/ files. Imports ordered: stdlib, third-party, local. ML domain: framework-free (numpy, scikit-learn, plain Python) and API-based inference (HTTP calls to OpenAI, Anthropic, HuggingFace Inference API) work everywhere. Heavy frameworks
|
|
22
|
+
"language": "No project-specific names, identifiers, or terminology anywhere in src/, tests/, or examples/ - use generic names like 'user', 'item', 'value', 'example_org'. A test that references your project's real entity names is contaminated. Use pytest for all tests - no unittest. Type hints required on all public functions. No __init__.py in tests/. No if __name__ == '__main__' blocks in src/ files. Imports ordered: stdlib, third-party, local. ML domain: framework-free (numpy, scikit-learn, plain Python) and API-based inference (HTTP calls to OpenAI, Anthropic, HuggingFace Inference API) work everywhere. Heavy optional frameworks must be pre-installed - Cartograph will not auto-install them. Declare dependencies in widget.json normally; consumers must also have them installed to validate.",
|
|
23
23
|
"domain": "Accept all paths and hostnames as parameters - never construct paths from hardcoded roots. Config keys, log formats, and health check endpoints must be configurable. Return structured status objects rather than printing; let the caller handle output. Side effects (file writes, process spawns) must be opt-in, not automatic."
|
|
24
24
|
},
|
|
25
25
|
"validation": {
|
|
26
26
|
"engine_version": 1,
|
|
27
|
-
"validated_at": "2026-
|
|
28
|
-
"runtime": "python 3.
|
|
27
|
+
"validated_at": "2026-05-02T04:28:33.143608+00:00",
|
|
28
|
+
"runtime": "python 3.13.13"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Example: verify a tarball matches a declared manifest.
|
|
2
|
+
|
|
3
|
+
Builds an in-memory archive that includes an unintended __pycache__ file
|
|
4
|
+
and shows the consistency check catching both an extra entry and a
|
|
5
|
+
forbidden entry against caller-supplied declarations.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import io
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
import tarfile
|
|
12
|
+
|
|
13
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
14
|
+
|
|
15
|
+
from src.archive_manifest_consistency import check_consistency
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _build(members):
|
|
19
|
+
buf = io.BytesIO()
|
|
20
|
+
with tarfile.open(fileobj=buf, mode="w") as tf:
|
|
21
|
+
for name, data in members:
|
|
22
|
+
info = tarfile.TarInfo(name=name)
|
|
23
|
+
info.size = len(data)
|
|
24
|
+
info.mode = 0o644
|
|
25
|
+
tf.addfile(info, io.BytesIO(data))
|
|
26
|
+
return buf.getvalue()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def main() -> None:
|
|
30
|
+
archive = _build([
|
|
31
|
+
("manifest.json", b'{"id": "example"}'),
|
|
32
|
+
("src/a.py", b"x = 1\n"),
|
|
33
|
+
("src/b.py", b"y = 2\n"),
|
|
34
|
+
("__pycache__/a.cpython-312.pyc", b"compiled"),
|
|
35
|
+
])
|
|
36
|
+
|
|
37
|
+
report = check_consistency(
|
|
38
|
+
archive,
|
|
39
|
+
expected={"manifest.json", "src/a.py", "src/b.py"},
|
|
40
|
+
required={"manifest.json"},
|
|
41
|
+
forbidden={"__pycache__/a.cpython-312.pyc"},
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
print(f"ok: {report.ok}")
|
|
45
|
+
print(f"all_files: {list(report.all_files)}")
|
|
46
|
+
print(f"missing: {list(report.missing)}")
|
|
47
|
+
print(f"extra: {list(report.extra)}")
|
|
48
|
+
print(f"required_missing: {list(report.required_missing)}")
|
|
49
|
+
print(f"forbidden_present: {list(report.forbidden_present)}")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if __name__ == "__main__":
|
|
53
|
+
main()
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""Verify a tarball's contents match a declared file manifest.
|
|
2
|
+
|
|
3
|
+
Given a tarball and three optional declarations, returns a structured
|
|
4
|
+
report:
|
|
5
|
+
|
|
6
|
+
* `expected` - the full enumerated set of paths the archive should
|
|
7
|
+
contain. Anything in the archive not in this set is
|
|
8
|
+
reported as `extra`; anything in this set not in the
|
|
9
|
+
archive is reported as `missing`. When `expected` is
|
|
10
|
+
omitted, neither `extra` nor `missing` is reported.
|
|
11
|
+
* `required` - a subset that MUST be present, even when the full
|
|
12
|
+
expected list is unknown. Useful for sanity checks
|
|
13
|
+
("manifest.json must be in the archive") without
|
|
14
|
+
enumerating every file.
|
|
15
|
+
* `forbidden` - paths that must NOT be present. Useful for catching
|
|
16
|
+
build artifacts or vendor dirs that should have been
|
|
17
|
+
excluded at pack time.
|
|
18
|
+
|
|
19
|
+
Pure stdlib (tarfile). Sets are returned sorted for stable diffs.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import io
|
|
23
|
+
import os
|
|
24
|
+
import tarfile
|
|
25
|
+
from dataclasses import dataclass
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ConsistencyError(Exception):
|
|
29
|
+
"""Base class for consistency errors."""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class ConsistencyReport:
|
|
34
|
+
"""Structured comparison result.
|
|
35
|
+
|
|
36
|
+
`ok` is True iff missing/extra/forbidden_present are all empty
|
|
37
|
+
relative to whatever declarations the caller provided. `all_files`
|
|
38
|
+
is the full sorted file list found in the archive (regular files
|
|
39
|
+
only - directories and links are excluded).
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
ok: bool
|
|
43
|
+
all_files: tuple[str, ...]
|
|
44
|
+
missing: tuple[str, ...]
|
|
45
|
+
extra: tuple[str, ...]
|
|
46
|
+
forbidden_present: tuple[str, ...]
|
|
47
|
+
required_missing: tuple[str, ...]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _list_archive_files(archive: bytes | str) -> set[str]:
|
|
51
|
+
"""Return the set of regular-file paths inside the archive."""
|
|
52
|
+
if isinstance(archive, (bytes, bytearray)):
|
|
53
|
+
opener = tarfile.open(fileobj=io.BytesIO(archive), mode="r:*")
|
|
54
|
+
elif isinstance(archive, str):
|
|
55
|
+
if not os.path.isfile(archive):
|
|
56
|
+
raise ConsistencyError(f"archive not found: {archive!r}")
|
|
57
|
+
opener = tarfile.open(name=archive, mode="r:*")
|
|
58
|
+
else:
|
|
59
|
+
raise ConsistencyError(
|
|
60
|
+
f"archive must be bytes or path string, got {type(archive).__name__}"
|
|
61
|
+
)
|
|
62
|
+
with opener as tf:
|
|
63
|
+
return {m.name for m in tf.getmembers() if m.isreg()}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def check_consistency(
|
|
67
|
+
archive: bytes | str,
|
|
68
|
+
*,
|
|
69
|
+
expected: set[str] | None = None,
|
|
70
|
+
required: set[str] | None = None,
|
|
71
|
+
forbidden: set[str] | None = None,
|
|
72
|
+
) -> ConsistencyReport:
|
|
73
|
+
"""Compare the archive's file list to the caller's declarations.
|
|
74
|
+
|
|
75
|
+
All declarations are optional - omitted ones contribute nothing to
|
|
76
|
+
the report's `ok` verdict. Path strings are compared literally; the
|
|
77
|
+
caller is responsible for normalizing separators or arcname prefixes
|
|
78
|
+
before calling.
|
|
79
|
+
"""
|
|
80
|
+
found = _list_archive_files(archive)
|
|
81
|
+
|
|
82
|
+
missing: tuple[str, ...] = ()
|
|
83
|
+
extra: tuple[str, ...] = ()
|
|
84
|
+
if expected is not None:
|
|
85
|
+
missing = tuple(sorted(expected - found))
|
|
86
|
+
extra = tuple(sorted(found - expected))
|
|
87
|
+
|
|
88
|
+
required_missing: tuple[str, ...] = ()
|
|
89
|
+
if required is not None:
|
|
90
|
+
required_missing = tuple(sorted(required - found))
|
|
91
|
+
|
|
92
|
+
forbidden_present: tuple[str, ...] = ()
|
|
93
|
+
if forbidden is not None:
|
|
94
|
+
forbidden_present = tuple(sorted(forbidden & found))
|
|
95
|
+
|
|
96
|
+
ok = (
|
|
97
|
+
not missing and not extra
|
|
98
|
+
and not required_missing and not forbidden_present
|
|
99
|
+
)
|
|
100
|
+
return ConsistencyReport(
|
|
101
|
+
ok=ok,
|
|
102
|
+
all_files=tuple(sorted(found)),
|
|
103
|
+
missing=missing,
|
|
104
|
+
extra=extra,
|
|
105
|
+
forbidden_present=forbidden_present,
|
|
106
|
+
required_missing=required_missing,
|
|
107
|
+
)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import tarfile
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from src.archive_manifest_consistency import (
|
|
7
|
+
ConsistencyError,
|
|
8
|
+
check_consistency,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _build_tar(members: list[tuple[str, bytes]]) -> bytes:
|
|
13
|
+
buf = io.BytesIO()
|
|
14
|
+
with tarfile.open(fileobj=buf, mode="w") as tf:
|
|
15
|
+
for name, data in members:
|
|
16
|
+
info = tarfile.TarInfo(name=name)
|
|
17
|
+
info.size = len(data)
|
|
18
|
+
info.mode = 0o644
|
|
19
|
+
tf.addfile(info, io.BytesIO(data))
|
|
20
|
+
return buf.getvalue()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_no_declarations_means_ok_with_full_listing():
|
|
24
|
+
data = _build_tar([("a.txt", b"x"), ("b.txt", b"y")])
|
|
25
|
+
r = check_consistency(data)
|
|
26
|
+
assert r.ok is True
|
|
27
|
+
assert r.all_files == ("a.txt", "b.txt")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_expected_matches_archive_exactly():
|
|
31
|
+
data = _build_tar([("a.txt", b"x"), ("b.txt", b"y")])
|
|
32
|
+
r = check_consistency(data, expected={"a.txt", "b.txt"})
|
|
33
|
+
assert r.ok is True
|
|
34
|
+
assert r.missing == ()
|
|
35
|
+
assert r.extra == ()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_extra_files_in_archive_reported():
|
|
39
|
+
data = _build_tar([("a.txt", b"x"), ("b.txt", b"y"), ("c.txt", b"z")])
|
|
40
|
+
r = check_consistency(data, expected={"a.txt", "b.txt"})
|
|
41
|
+
assert r.ok is False
|
|
42
|
+
assert r.extra == ("c.txt",)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_missing_files_reported():
|
|
46
|
+
data = _build_tar([("a.txt", b"x")])
|
|
47
|
+
r = check_consistency(data, expected={"a.txt", "b.txt"})
|
|
48
|
+
assert r.ok is False
|
|
49
|
+
assert r.missing == ("b.txt",)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_required_present_passes():
|
|
53
|
+
data = _build_tar([("manifest.json", b"{}"), ("a.txt", b"x")])
|
|
54
|
+
r = check_consistency(data, required={"manifest.json"})
|
|
55
|
+
assert r.ok is True
|
|
56
|
+
assert r.required_missing == ()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_required_missing_reported():
|
|
60
|
+
data = _build_tar([("a.txt", b"x")])
|
|
61
|
+
r = check_consistency(data, required={"manifest.json"})
|
|
62
|
+
assert r.ok is False
|
|
63
|
+
assert r.required_missing == ("manifest.json",)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_forbidden_absent_passes():
|
|
67
|
+
data = _build_tar([("src/a.py", b"x")])
|
|
68
|
+
r = check_consistency(data, forbidden={"__pycache__/junk.pyc"})
|
|
69
|
+
assert r.ok is True
|
|
70
|
+
assert r.forbidden_present == ()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_forbidden_present_reported():
|
|
74
|
+
data = _build_tar([("src/a.py", b"x"), ("__pycache__/junk.pyc", b"y")])
|
|
75
|
+
r = check_consistency(data, forbidden={"__pycache__/junk.pyc"})
|
|
76
|
+
assert r.ok is False
|
|
77
|
+
assert r.forbidden_present == ("__pycache__/junk.pyc",)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_combined_declarations_all_evaluated():
|
|
81
|
+
data = _build_tar([
|
|
82
|
+
("manifest.json", b"{}"),
|
|
83
|
+
("a.txt", b"x"),
|
|
84
|
+
("__pycache__/junk.pyc", b"y"),
|
|
85
|
+
])
|
|
86
|
+
r = check_consistency(
|
|
87
|
+
data,
|
|
88
|
+
expected={"manifest.json", "a.txt"},
|
|
89
|
+
required={"manifest.json"},
|
|
90
|
+
forbidden={"__pycache__/junk.pyc"},
|
|
91
|
+
)
|
|
92
|
+
assert r.ok is False
|
|
93
|
+
assert r.extra == ("__pycache__/junk.pyc",)
|
|
94
|
+
assert r.forbidden_present == ("__pycache__/junk.pyc",)
|
|
95
|
+
assert r.required_missing == ()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_directories_excluded_from_file_list():
|
|
99
|
+
"""Directory entries should not appear in all_files."""
|
|
100
|
+
buf = io.BytesIO()
|
|
101
|
+
with tarfile.open(fileobj=buf, mode="w") as tf:
|
|
102
|
+
dir_info = tarfile.TarInfo(name="pkg")
|
|
103
|
+
dir_info.type = tarfile.DIRTYPE
|
|
104
|
+
tf.addfile(dir_info)
|
|
105
|
+
file_info = tarfile.TarInfo(name="pkg/a.py")
|
|
106
|
+
file_info.size = 1
|
|
107
|
+
tf.addfile(file_info, io.BytesIO(b"x"))
|
|
108
|
+
r = check_consistency(buf.getvalue())
|
|
109
|
+
assert r.all_files == ("pkg/a.py",)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test_extracts_from_file_path(tmp_path):
|
|
113
|
+
data = _build_tar([("a.txt", b"hello")])
|
|
114
|
+
p = tmp_path / "in.tar"
|
|
115
|
+
p.write_bytes(data)
|
|
116
|
+
r = check_consistency(str(p), expected={"a.txt"})
|
|
117
|
+
assert r.ok is True
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def test_missing_archive_path_raises(tmp_path):
|
|
121
|
+
with pytest.raises(ConsistencyError):
|
|
122
|
+
check_consistency(str(tmp_path / "nope.tar"))
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_archive_must_be_bytes_or_str():
|
|
126
|
+
with pytest.raises(ConsistencyError):
|
|
127
|
+
check_consistency(123) # type: ignore[arg-type]
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_all_files_sorted():
|
|
131
|
+
data = _build_tar([("z.txt", b"z"), ("a.txt", b"a"), ("m.txt", b"m")])
|
|
132
|
+
r = check_consistency(data)
|
|
133
|
+
assert r.all_files == ("a.txt", "m.txt", "z.txt")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def test_empty_expected_set_means_archive_must_be_empty():
|
|
137
|
+
"""Passing an empty set as `expected` (vs None) is a real declaration."""
|
|
138
|
+
data = _build_tar([("a.txt", b"x")])
|
|
139
|
+
r = check_consistency(data, expected=set())
|
|
140
|
+
assert r.ok is False
|
|
141
|
+
assert r.extra == ("a.txt",)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def test_empty_archive():
|
|
145
|
+
data = _build_tar([])
|
|
146
|
+
r = check_consistency(data, expected=set())
|
|
147
|
+
assert r.ok is True
|
|
148
|
+
assert r.all_files == ()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"id": "infra-archive-manifest-consistency-python",
|
|
4
|
+
"name": "Archive Manifest Consistency",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"domain": "infra",
|
|
7
|
+
"tags": [
|
|
8
|
+
"archive",
|
|
9
|
+
"manifest",
|
|
10
|
+
"consistency",
|
|
11
|
+
"supply-chain",
|
|
12
|
+
"verification"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"description": "Verify a tarball's contents match a declared file manifest. Given a tarball and any combination of expected (full enumerated set), required (must-be-present subset), and forbidden (must-not-be-present) path declarations, returns a structured report listing missing files, extra files, required-but-missing, and forbidden-present. Path strings are compared literally so callers control normalization. Pure stdlib (tarfile).",
|
|
16
|
+
"tech_stack": {
|
|
17
|
+
"language": "python",
|
|
18
|
+
"dependencies": []
|
|
19
|
+
},
|
|
20
|
+
"custom_notes": "",
|
|
21
|
+
"library_notes": {
|
|
22
|
+
"general": "Single responsibility - one widget does one thing. No global state. No project-specific code, hardcoded paths, credentials, or environment-specific values. Expose variation points as constructor parameters or function arguments - no hardcoded thresholds, colors, sizes, or behavior flags. URLs and endpoints belong in examples as demonstration data, not in src/ - if a widget needs a URL to operate, it must be a parameter the caller provides. All dependencies must be declared in widget.json tech_stack.dependencies. Widgets cannot depend on other widgets - they must be fully self-contained. If you need logic from another widget, copy it into src/ directly. Examples must run and exit cleanly with no user input, no network calls, and no external services or API keys - use fake/hardcoded data. The widget's own declared dependencies are fine and will be installed by the validator before the example runs. Do not modify library_notes - it is managed by Cartograph and will be restored on checkin.",
|
|
23
|
+
"language": "No project-specific names, identifiers, or terminology anywhere in src/, tests/, or examples/ - use generic names like 'user', 'item', 'value', 'example_org'. A test that references your project's real entity names is contaminated. Use pytest for all tests - no unittest. Type hints required on all public functions. No __init__.py in tests/. No if __name__ == '__main__' blocks in src/ files. Imports ordered: stdlib, third-party, local. ML domain: framework-free (numpy, scikit-learn, plain Python) and API-based inference (HTTP calls to OpenAI, Anthropic, HuggingFace Inference API) work everywhere. Heavy optional frameworks must be pre-installed - Cartograph will not auto-install them. Declare dependencies in widget.json normally; consumers must also have them installed to validate.",
|
|
24
|
+
"domain": "Accept all paths and hostnames as parameters - never construct paths from hardcoded roots. Config keys, log formats, and health check endpoints must be configurable. Return structured status objects rather than printing; let the caller handle output. Side effects (file writes, process spawns) must be opt-in, not automatic."
|
|
25
|
+
},
|
|
26
|
+
"validation": {
|
|
27
|
+
"engine_version": 1,
|
|
28
|
+
"validated_at": "2026-05-07T02:23:11.212189+00:00",
|
|
29
|
+
"runtime": "python 3.14.4"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fingerprint": "bdbee4a0c3d45c3e71441189f39cd8b9abee33ae3612ec2b9fe728e39b4c8691", "stamped_at": "2026-06-04T21:33:30.432552+00:00", "language": "python", "engine_version": 1, "runtime": "python 3.14.5", "test_results": {}, "validated_at": "2026-06-04T21:33:30.432184+00:00"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"id": "infra-file-stamp-python",
|
|
4
|
+
"name": "File Stamp",
|
|
5
|
+
"version": "1.0.2",
|
|
6
|
+
"domain": "infra",
|
|
7
|
+
"tags": [
|
|
8
|
+
"fingerprint",
|
|
9
|
+
"cache-invalidation",
|
|
10
|
+
"file-hash",
|
|
11
|
+
"change-detection",
|
|
12
|
+
"build-tools"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"description": "Fingerprint-based change detection for file sets. Computes SHA-256 over watched files, writes a JSON stamp, and checks validity on subsequent runs. Useful for build cache invalidation, validation short-circuiting, and incremental processing pipelines.",
|
|
16
|
+
"tech_stack": {
|
|
17
|
+
"language": "python",
|
|
18
|
+
"dependencies": []
|
|
19
|
+
},
|
|
20
|
+
"library_notes": {
|
|
21
|
+
"general": "Single responsibility - one widget does one thing. No global state. No project-specific code, hardcoded paths, credentials, or environment-specific values. Expose variation points as constructor parameters or function arguments - no hardcoded thresholds, colors, sizes, or behavior flags. URLs and endpoints belong in examples as demonstration data, not in src/ - if a widget needs a URL to operate, it must be a parameter the caller provides. All dependencies must be declared in widget.json tech_stack.dependencies. Widgets cannot depend on other widgets - they must be fully self-contained. If you need logic from another widget, copy it into src/ directly. Examples must run and exit cleanly with no user input, no network calls, and no external services or API keys - use fake/hardcoded data. The widget's own declared dependencies are fine and will be installed by the validator before the example runs. Do not modify library_notes - it is managed by Cartograph and will be restored on checkin.",
|
|
22
|
+
"language": "No project-specific names, identifiers, or terminology anywhere in src/, tests/, or examples/ - use generic names like 'user', 'item', 'value', 'example_org'. A test that references your project's real entity names is contaminated. Use pytest for all tests - no unittest. Type hints required on all public functions. No __init__.py in tests/. No if __name__ == '__main__' blocks in src/ files. Imports ordered: stdlib, third-party, local. ML domain: framework-free (numpy, scikit-learn, plain Python) and API-based inference (HTTP calls to OpenAI, Anthropic, HuggingFace Inference API) work everywhere. Heavy optional frameworks must be pre-installed - Cartograph will not auto-install them. Declare dependencies in widget.json normally; consumers must also have them installed to validate.",
|
|
23
|
+
"domain": "Accept all paths and hostnames as parameters - never construct paths from hardcoded roots. Config keys, log formats, and health check endpoints must be configurable. Return structured status objects rather than printing; let the caller handle output. Side effects (file writes, process spawns) must be opt-in, not automatic."
|
|
24
|
+
},
|
|
25
|
+
"validation": {
|
|
26
|
+
"engine_version": 1,
|
|
27
|
+
"validated_at": "2026-06-04T21:33:38.758184+00:00",
|
|
28
|
+
"runtime": "python 3.14.5"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Package marker - add explicit exports here once the public API is stable.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fingerprint": "66f9d8e1bf9b8bc1949f0423451beab19a8238e13c4c710f40a6d3ce14dbb55b", "stamped_at": "2026-06-04T21:18:41.001785+00:00", "language": "python", "engine_version": 1, "runtime": "python 3.14.5", "test_results": {}, "validated_at": "2026-06-04T21:18:41.001510+00:00"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Demonstrate the cache-around-a-callable pattern.
|
|
2
|
+
|
|
3
|
+
A short-lived CLI wants to avoid paying for an expensive lookup on every
|
|
4
|
+
invocation. Wrap the call in a get-then-set helper backed by ttl-disk-cache:
|
|
5
|
+
first call computes and stores; subsequent calls within the TTL window
|
|
6
|
+
short-circuit on the disk read.
|
|
7
|
+
|
|
8
|
+
Runs offline with a faked-out 'expensive lookup'. Tear-down at the end
|
|
9
|
+
keeps the example directory clean for re-runs.
|
|
10
|
+
"""
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
import tempfile
|
|
14
|
+
|
|
15
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
|
16
|
+
from src.ttl_disk_cache import get, set, clear
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def expensive_lookup(user_id: str) -> dict:
|
|
20
|
+
"""Stand-in for a slow network call. In real use this would be an
|
|
21
|
+
HTTP request, a database read, or anything else worth caching."""
|
|
22
|
+
return {"user_id": user_id, "tier": "gold", "lookups": 1}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def cached_lookup(cache_root: str, user_id: str, ttl_seconds: float) -> dict:
|
|
26
|
+
hit = get(cache_root, user_id)
|
|
27
|
+
if hit is not None:
|
|
28
|
+
return hit
|
|
29
|
+
value = expensive_lookup(user_id)
|
|
30
|
+
set(cache_root, user_id, value, ttl_seconds)
|
|
31
|
+
return value
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def main() -> None:
|
|
35
|
+
with tempfile.TemporaryDirectory() as cache_root:
|
|
36
|
+
first = cached_lookup(cache_root, "ada", ttl_seconds=60)
|
|
37
|
+
print(f"first call (miss, computed): {first}")
|
|
38
|
+
|
|
39
|
+
second = cached_lookup(cache_root, "ada", ttl_seconds=60)
|
|
40
|
+
print(f"second call (hit, from disk): {second}")
|
|
41
|
+
assert first == second, "cache should return the stored value"
|
|
42
|
+
|
|
43
|
+
# Inspect what's on disk.
|
|
44
|
+
files = sorted(os.listdir(cache_root))
|
|
45
|
+
print(f"cache files on disk: {files}")
|
|
46
|
+
|
|
47
|
+
# Targeted invalidation — useful when underlying data changes.
|
|
48
|
+
clear(cache_root, "ada")
|
|
49
|
+
assert get(cache_root, "ada") is None
|
|
50
|
+
print("after clear: cache miss as expected")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if __name__ == "__main__":
|
|
54
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Package marker - add explicit exports here once the public API is stable.
|