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.
Files changed (240) hide show
  1. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/CLAUDE.md +0 -32
  2. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/PKG-INFO +1 -1
  3. cartograph_cli-0.7.4/cg/cg_universal_graph_cycles_python/.validation_stamp.json +1 -0
  4. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/widget.json +3 -3
  5. cartograph_cli-0.7.4/cg/infra_agent_cli_python/.cartograph_source +1 -0
  6. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/widget.json +5 -5
  7. cartograph_cli-0.7.4/cg/infra_archive_manifest_consistency_python/examples/example_usage.py +53 -0
  8. cartograph_cli-0.7.4/cg/infra_archive_manifest_consistency_python/src/archive_manifest_consistency.py +107 -0
  9. cartograph_cli-0.7.4/cg/infra_archive_manifest_consistency_python/tests/test_archive_manifest_consistency.py +148 -0
  10. cartograph_cli-0.7.4/cg/infra_archive_manifest_consistency_python/widget.json +31 -0
  11. cartograph_cli-0.7.4/cg/infra_file_stamp_python/.validation_stamp.json +1 -0
  12. cartograph_cli-0.7.4/cg/infra_file_stamp_python/widget.json +30 -0
  13. cartograph_cli-0.7.4/cg/universal_block_walker_python/src/__init__.py +1 -0
  14. cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/.validation_stamp.json +1 -0
  15. cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/examples/example_usage.py +54 -0
  16. cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/src/__init__.py +1 -0
  17. cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/src/ttl_disk_cache.py +122 -0
  18. cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/tests/test_ttl_disk_cache.py +197 -0
  19. cartograph_cli-0.7.4/cg/universal_ttl_disk_cache_python/widget.json +31 -0
  20. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/pyproject.toml +1 -1
  21. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/__init__.py +2 -0
  22. cartograph_cli-0.7.4/src/cartograph/architect/markdown.py +187 -0
  23. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/auth.py +46 -0
  24. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/cli.py +340 -340
  25. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/config.py +16 -1
  26. cartograph_cli-0.7.4/src/cartograph/search/ngram.py +109 -0
  27. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_cli_contract.py +2 -2
  28. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_search.py +35 -0
  29. cartograph_cli-0.7.2/cg/infra_agent_cli_python/.validation_stamp.json +0 -1
  30. cartograph_cli-0.7.2/cg/infra_file_stamp_python/.validation_stamp.json +0 -1
  31. cartograph_cli-0.7.2/cg/infra_file_stamp_python/widget.json +0 -24
  32. cartograph_cli-0.7.2/src/cartograph/search/ngram.py +0 -83
  33. cartograph_cli-0.7.2/tests/test_architect.py +0 -895
  34. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.githooks/pre-push +0 -0
  35. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.github/FUNDING.yml +0 -0
  36. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.github/workflows/fresh-install.yml +0 -0
  37. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.github/workflows/publish.yml +0 -0
  38. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.github/workflows/test.yml +0 -0
  39. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/.gitignore +0 -0
  40. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/CONTRIBUTING.md +0 -0
  41. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/LICENSE +0 -0
  42. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/README.md +0 -0
  43. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/VALIDATION.md +0 -0
  44. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/architect.mmd +0 -0
  45. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/architect.py +0 -0
  46. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/.cartograph_source +0 -0
  47. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/examples/example_usage.py +0 -0
  48. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/src/__init__.py +0 -0
  49. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/src/graph_cycles.py +0 -0
  50. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_graph_cycles_python/tests/test_graph_cycles.py +0 -0
  51. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/.validation_stamp.json +0 -0
  52. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/examples/example_usage.py +0 -0
  53. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/src/__init__.py +0 -0
  54. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/src/mermaid_graph_renderer.py +0 -0
  55. {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
  56. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_mermaid_graph_renderer_python/widget.json +0 -0
  57. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_python_module_loader_python/examples/example_usage.py +0 -0
  58. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_python_module_loader_python/src/__init__.py +0 -0
  59. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_python_module_loader_python/src/python_module_loader.py +0 -0
  60. {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
  61. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/cg_universal_python_module_loader_python/widget.json +0 -0
  62. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/examples/example_usage.py +0 -0
  63. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/src/__init__.py +0 -0
  64. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/src/agent_cli.py +0 -0
  65. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_agent_cli_python/tests/test_agent_cli.py +0 -0
  66. {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
  67. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/.validation_stamp.json +0 -0
  68. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/examples/example_usage.py +0 -0
  69. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/src/__init__.py +0 -0
  70. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/src/binary_resolver.py +0 -0
  71. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/tests/test_binary_resolver.py +0 -0
  72. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_binary_resolver_python/widget.json +0 -0
  73. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/.validation_stamp.json +0 -0
  74. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/examples/example_usage.py +0 -0
  75. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/src/__init__.py +0 -0
  76. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/src/command_catalog.py +0 -0
  77. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/tests/test_command_catalog.py +0 -0
  78. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_command_catalog_python/widget.json +0 -0
  79. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_directory_tarball_python/examples/example_usage.py +0 -0
  80. {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
  81. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_directory_tarball_python/src/directory_tarball.py +0 -0
  82. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_directory_tarball_python/tests/test_directory_tarball.py +0 -0
  83. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_directory_tarball_python/widget.json +0 -0
  84. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_file_stamp_python/examples/example_usage.py +0 -0
  85. {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
  86. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_file_stamp_python/src/file_stamp.py +0 -0
  87. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_file_stamp_python/tests/test_file_stamp.py +0 -0
  88. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/.validation_stamp.json +0 -0
  89. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/examples/example_usage.py +0 -0
  90. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/src/__init__.py +0 -0
  91. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/src/http_endpoint_registry.py +0 -0
  92. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/tests/test_http_endpoint_registry.py +0 -0
  93. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_http_endpoint_registry_python/widget.json +0 -0
  94. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/.validation_stamp.json +0 -0
  95. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/examples/example_usage.py +0 -0
  96. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/src/__init__.py +0 -0
  97. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/src/openapi_generator.py +0 -0
  98. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/tests/test_openapi_generator.py +0 -0
  99. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_openapi_generator_python/widget.json +0 -0
  100. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_pinned_deps_resolver_python/examples/example_usage.py +0 -0
  101. {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
  102. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_pinned_deps_resolver_python/src/pinned_deps_resolver.py +0 -0
  103. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_pinned_deps_resolver_python/tests/test_pinned_deps_resolver.py +0 -0
  104. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_pinned_deps_resolver_python/widget.json +0 -0
  105. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_prefix_router_python/examples/example_usage.py +0 -0
  106. {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
  107. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_prefix_router_python/src/prefix_router.py +0 -0
  108. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_prefix_router_python/tests/test_prefix_router.py +0 -0
  109. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_prefix_router_python/widget.json +0 -0
  110. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/.validation_stamp.json +0 -0
  111. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/examples/example_usage.py +0 -0
  112. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/src/__init__.py +0 -0
  113. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/src/urllib_client.py +0 -0
  114. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/tests/test_urllib_client.py +0 -0
  115. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_urllib_client_python/widget.json +0 -0
  116. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_version_bump_policy_python/examples/example_usage.py +0 -0
  117. {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
  118. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_version_bump_policy_python/src/version_bump_policy.py +0 -0
  119. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_version_bump_policy_python/tests/test_version_bump_policy.py +0 -0
  120. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/infra_version_bump_policy_python/widget.json +0 -0
  121. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/.validation_stamp.json +0 -0
  122. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/examples/example_usage.py +0 -0
  123. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/src/block_walker.py +0 -0
  124. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/tests/test_block_walker.py +0 -0
  125. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_block_walker_python/widget.json +0 -0
  126. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/.validation_stamp.json +0 -0
  127. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/examples/example_usage.py +0 -0
  128. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/src/__init__.py +0 -0
  129. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/src/build_artifact_ignore.py +0 -0
  130. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/tests/test_build_artifact_ignore.py +0 -0
  131. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_build_artifact_ignore_python/widget.json +0 -0
  132. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/.validation_stamp.json +0 -0
  133. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/examples/example_usage.py +0 -0
  134. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/src/__init__.py +0 -0
  135. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/src/list_paginator.py +0 -0
  136. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/tests/test_list_paginator.py +0 -0
  137. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/cg/universal_list_paginator_python/widget.json +0 -0
  138. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/docs/languages/nim.md +0 -0
  139. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-1024.png +0 -0
  140. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-128.png +0 -0
  141. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-256.png +0 -0
  142. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-512.png +0 -0
  143. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black-1024.png +0 -0
  144. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black-128.png +0 -0
  145. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black-256.png +0 -0
  146. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black-512.png +0 -0
  147. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-black.svg +0 -0
  148. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white-1024.png +0 -0
  149. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white-128.png +0 -0
  150. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white-256.png +0 -0
  151. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white-512.png +0 -0
  152. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph-white.svg +0 -0
  153. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/logo/logo-cartograph.svg +0 -0
  154. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/pytest.ini +0 -0
  155. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/scripts/bump_version.sh +0 -0
  156. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/scripts/preflight.sh +0 -0
  157. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/__init__.py +0 -0
  158. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/__main__.py +0 -0
  159. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/loader.py +0 -0
  160. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/mutate.py +0 -0
  161. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/paths.py +0 -0
  162. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/renderer.py +0 -0
  163. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/scaffold.py +0 -0
  164. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/schema.py +0 -0
  165. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/architect/validator.py +0 -0
  166. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_checkin.py +0 -0
  167. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_deps.py +0 -0
  168. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_install.py +0 -0
  169. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_publish.py +0 -0
  170. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_status.py +0 -0
  171. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprint_validator.py +0 -0
  172. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/blueprints.py +0 -0
  173. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/checkin.py +0 -0
  174. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/cloud.py +0 -0
  175. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/contamination.py +0 -0
  176. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/dashboard.py +0 -0
  177. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/dashboard_ui.py +0 -0
  178. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/engine.py +0 -0
  179. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/inspector.py +0 -0
  180. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/installer.py +0 -0
  181. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/__init__.py +0 -0
  182. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/angular.py +0 -0
  183. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/base.py +0 -0
  184. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/javascript.py +0 -0
  185. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/nim.py +0 -0
  186. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/openscad.py +0 -0
  187. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/php.py +0 -0
  188. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/python.py +0 -0
  189. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/registry.py +0 -0
  190. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/scanners/js_scanner.js +0 -0
  191. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/scanners/nim_scanner.nim +0 -0
  192. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/systemverilog.py +0 -0
  193. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/languages/terraform.py +0 -0
  194. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/library_config.json +0 -0
  195. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/manifest.py +0 -0
  196. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/rules.py +0 -0
  197. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/scaffolding/__init__.py +0 -0
  198. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/__init__.py +0 -0
  199. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/filters.py +0 -0
  200. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/hybrid.py +0 -0
  201. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/synonyms.json +0 -0
  202. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/search/tfidf.py +0 -0
  203. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/trust.py +0 -0
  204. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/update_check.py +0 -0
  205. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/validation_stamp.py +0 -0
  206. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/src/cartograph/validator.py +0 -0
  207. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/__init__.py +0 -0
  208. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/cloud_health.py +0 -0
  209. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/conftest.py +0 -0
  210. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/fresh_install/Dockerfile +0 -0
  211. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/fresh_install/test_fresh_install.sh +0 -0
  212. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_auth.py +0 -0
  213. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_checkin.py +0 -0
  214. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_contamination.py +0 -0
  215. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_create.py +0 -0
  216. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_deps.py +0 -0
  217. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_install.py +0 -0
  218. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_languages.py +0 -0
  219. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_publish.py +0 -0
  220. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_search_inspect.py +0 -0
  221. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_status.py +0 -0
  222. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprint_validator.py +0 -0
  223. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_blueprints.py +0 -0
  224. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_checkin.py +0 -0
  225. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_checkin_publish.py +0 -0
  226. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_cloud_zip.py +0 -0
  227. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_config.py +0 -0
  228. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_contamination.py +0 -0
  229. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_create.py +0 -0
  230. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_inspect.py +0 -0
  231. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_install.py +0 -0
  232. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_language_engines.py +0 -0
  233. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_library_integrity.py +0 -0
  234. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_loading.py +0 -0
  235. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_manifest.py +0 -0
  236. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_rules.py +0 -0
  237. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_setup.py +0 -0
  238. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_update_check.py +0 -0
  239. {cartograph_cli-0.7.2 → cartograph_cli-0.7.4}/tests/test_upgrade.py +0 -0
  240. {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]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cartograph-cli
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: Widget library manager for AI agents — CLI
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -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"}
@@ -2,7 +2,7 @@
2
2
  "meta": {
3
3
  "id": "universal-graph-cycles-python",
4
4
  "name": "Graph Cycles",
5
- "version": "1.0.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-05-02T04:23:51.124498+00:00",
29
- "runtime": "python 3.13.13"
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.1",
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, no interactive prompts, grouped help, nested subcommands. Define commands as dicts, get argparse wiring for free.",
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 (torch, tensorflow, jax, and similar) are allowed but must be pre-installed - Cartograph will not auto-install them. Declare them in widget.json dependencies normally; consumers must also have them installed to validate.",
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-04-12T20:49:05.866788+00:00",
28
- "runtime": "python 3.14.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.