trellis-ai 0.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. trellis_ai-0.3.2/.gitignore +24 -0
  2. trellis_ai-0.3.2/CHANGELOG.md +109 -0
  3. trellis_ai-0.3.2/CODE_OF_CONDUCT.md +52 -0
  4. trellis_ai-0.3.2/CONTRIBUTING.md +92 -0
  5. trellis_ai-0.3.2/LICENSE +21 -0
  6. trellis_ai-0.3.2/Makefile +45 -0
  7. trellis_ai-0.3.2/PKG-INFO +331 -0
  8. trellis_ai-0.3.2/README.md +262 -0
  9. trellis_ai-0.3.2/RELEASING.md +103 -0
  10. trellis_ai-0.3.2/SECURITY.md +34 -0
  11. trellis_ai-0.3.2/docs/agent-guide/README.md +24 -0
  12. trellis_ai-0.3.2/docs/agent-guide/enriching-for-retrieval.md +112 -0
  13. trellis_ai-0.3.2/docs/agent-guide/modeling-guide.md +559 -0
  14. trellis_ai-0.3.2/docs/agent-guide/operations.md +928 -0
  15. trellis_ai-0.3.2/docs/agent-guide/playbooks.md +682 -0
  16. trellis_ai-0.3.2/docs/agent-guide/schemas.md +828 -0
  17. trellis_ai-0.3.2/docs/agent-guide/tiered-context-retrieval.md +159 -0
  18. trellis_ai-0.3.2/docs/agent-guide/trace-format.md +303 -0
  19. trellis_ai-0.3.2/docs/design/adr-deferred-cognition.md +166 -0
  20. trellis_ai-0.3.2/docs/design/adr-dual-loop-evolution.md +280 -0
  21. trellis_ai-0.3.2/docs/design/adr-llm-client-abstraction.md +290 -0
  22. trellis_ai-0.3.2/docs/design/architecture-design.md +92 -0
  23. trellis_ai-0.3.2/docs/design/classification-layer.md +665 -0
  24. trellis_ai-0.3.2/docs/design/context-economy-strategy.md +71 -0
  25. trellis_ai-0.3.2/docs/design/evolution-wireframes.md +477 -0
  26. trellis_ai-0.3.2/docs/design/graph-ui-integration.md +456 -0
  27. trellis_ai-0.3.2/docs/design/plan-context-economy.md +220 -0
  28. trellis_ai-0.3.2/docs/design/plan-pluggable-architecture.md +303 -0
  29. trellis_ai-0.3.2/docs/design/shared-first-schema-v1.md +292 -0
  30. trellis_ai-0.3.2/docs/getting-started/README.md +108 -0
  31. trellis_ai-0.3.2/docs/getting-started/mcp-claude-code.md +101 -0
  32. trellis_ai-0.3.2/docs/getting-started/mcp-claude-desktop.md +77 -0
  33. trellis_ai-0.3.2/docs/getting-started/mcp-cursor.md +86 -0
  34. trellis_ai-0.3.2/docs/issues/trellis-platform-integration-findings.md +137 -0
  35. trellis_ai-0.3.2/docs/plans/2026-03-16-entity-alias-implementation.md +149 -0
  36. trellis_ai-0.3.2/docs/plans/2026-03-16-pack-observability-implementation.md +111 -0
  37. trellis_ai-0.3.2/docs/plans/2026-04-16-phase2-step8-subtasks.md +285 -0
  38. trellis_ai-0.3.2/docs/plans/workflow-integration-hooks.md +159 -0
  39. trellis_ai-0.3.2/docs/research/client-layer-inventory.md +559 -0
  40. trellis_ai-0.3.2/docs/research/compaction-and-agent-patterns.md +582 -0
  41. trellis_ai-0.3.2/docs/research/memory-systems-landscape.md +397 -0
  42. trellis_ai-0.3.2/examples/README.md +40 -0
  43. trellis_ai-0.3.2/examples/__init__.py +0 -0
  44. trellis_ai-0.3.2/examples/batch_ingest.sh +37 -0
  45. trellis_ai-0.3.2/examples/custom_classifier.py +98 -0
  46. trellis_ai-0.3.2/examples/custom_extractor.py +128 -0
  47. trellis_ai-0.3.2/examples/integrations/__init__.py +0 -0
  48. trellis_ai-0.3.2/examples/integrations/langgraph/README.md +115 -0
  49. trellis_ai-0.3.2/examples/integrations/langgraph/__init__.py +0 -0
  50. trellis_ai-0.3.2/examples/integrations/langgraph/tools.py +181 -0
  51. trellis_ai-0.3.2/examples/integrations/obsidian/README.md +98 -0
  52. trellis_ai-0.3.2/examples/integrations/obsidian/__init__.py +0 -0
  53. trellis_ai-0.3.2/examples/integrations/obsidian/indexer.py +179 -0
  54. trellis_ai-0.3.2/examples/integrations/obsidian/vault.py +215 -0
  55. trellis_ai-0.3.2/examples/integrations/openclaw/README.md +102 -0
  56. trellis_ai-0.3.2/examples/integrations/openclaw/SKILL.md +97 -0
  57. trellis_ai-0.3.2/examples/integrations/openclaw/openclaw.example.json +8 -0
  58. trellis_ai-0.3.2/examples/langgraph_agent.py +83 -0
  59. trellis_ai-0.3.2/examples/mcp_claude_code.md +82 -0
  60. trellis_ai-0.3.2/examples/retrieve_before_task.py +76 -0
  61. trellis_ai-0.3.2/examples/sdk_local_demo.py +71 -0
  62. trellis_ai-0.3.2/examples/sdk_remote_demo.py +57 -0
  63. trellis_ai-0.3.2/pyproject.toml +175 -0
  64. trellis_ai-0.3.2/scripts/seed_demo.py +1160 -0
  65. trellis_ai-0.3.2/skills/README.md +53 -0
  66. trellis_ai-0.3.2/skills/link-evidence/SKILL.md +88 -0
  67. trellis_ai-0.3.2/skills/record-after-task/SKILL.md +96 -0
  68. trellis_ai-0.3.2/skills/retrieve-before-task/SKILL.md +57 -0
  69. trellis_ai-0.3.2/src/trellis/__init__.py +1 -0
  70. trellis_ai-0.3.2/src/trellis/classify/__init__.py +1 -0
  71. trellis_ai-0.3.2/src/trellis/classify/classifiers/__init__.py +1 -0
  72. trellis_ai-0.3.2/src/trellis/classify/classifiers/graph_neighbor.py +117 -0
  73. trellis_ai-0.3.2/src/trellis/classify/classifiers/keyword.py +216 -0
  74. trellis_ai-0.3.2/src/trellis/classify/classifiers/llm.py +109 -0
  75. trellis_ai-0.3.2/src/trellis/classify/classifiers/source_system.py +106 -0
  76. trellis_ai-0.3.2/src/trellis/classify/classifiers/structural.py +78 -0
  77. trellis_ai-0.3.2/src/trellis/classify/dedup/__init__.py +5 -0
  78. trellis_ai-0.3.2/src/trellis/classify/dedup/minhash.py +261 -0
  79. trellis_ai-0.3.2/src/trellis/classify/feedback.py +40 -0
  80. trellis_ai-0.3.2/src/trellis/classify/importance.py +32 -0
  81. trellis_ai-0.3.2/src/trellis/classify/pipeline.py +139 -0
  82. trellis_ai-0.3.2/src/trellis/classify/protocol.py +111 -0
  83. trellis_ai-0.3.2/src/trellis/core/__init__.py +0 -0
  84. trellis_ai-0.3.2/src/trellis/core/base.py +52 -0
  85. trellis_ai-0.3.2/src/trellis/core/hashing.py +15 -0
  86. trellis_ai-0.3.2/src/trellis/core/ids.py +23 -0
  87. trellis_ai-0.3.2/src/trellis/errors.py +73 -0
  88. trellis_ai-0.3.2/src/trellis/extract/__init__.py +50 -0
  89. trellis_ai-0.3.2/src/trellis/extract/alias_match.py +227 -0
  90. trellis_ai-0.3.2/src/trellis/extract/base.py +102 -0
  91. trellis_ai-0.3.2/src/trellis/extract/commands.py +91 -0
  92. trellis_ai-0.3.2/src/trellis/extract/context.py +31 -0
  93. trellis_ai-0.3.2/src/trellis/extract/dispatcher.py +164 -0
  94. trellis_ai-0.3.2/src/trellis/extract/hybrid.py +301 -0
  95. trellis_ai-0.3.2/src/trellis/extract/json_rules.py +369 -0
  96. trellis_ai-0.3.2/src/trellis/extract/llm.py +376 -0
  97. trellis_ai-0.3.2/src/trellis/extract/prompts/__init__.py +28 -0
  98. trellis_ai-0.3.2/src/trellis/extract/prompts/base.py +84 -0
  99. trellis_ai-0.3.2/src/trellis/extract/prompts/extraction.py +113 -0
  100. trellis_ai-0.3.2/src/trellis/extract/registry.py +100 -0
  101. trellis_ai-0.3.2/src/trellis/extract/save_memory.py +93 -0
  102. trellis_ai-0.3.2/src/trellis/feedback/__init__.py +10 -0
  103. trellis_ai-0.3.2/src/trellis/feedback/aggregation.py +69 -0
  104. trellis_ai-0.3.2/src/trellis/feedback/models.py +84 -0
  105. trellis_ai-0.3.2/src/trellis/feedback/recording.py +127 -0
  106. trellis_ai-0.3.2/src/trellis/learning/__init__.py +17 -0
  107. trellis_ai-0.3.2/src/trellis/learning/scoring.py +459 -0
  108. trellis_ai-0.3.2/src/trellis/llm/__init__.py +20 -0
  109. trellis_ai-0.3.2/src/trellis/llm/protocol.py +65 -0
  110. trellis_ai-0.3.2/src/trellis/llm/providers/__init__.py +11 -0
  111. trellis_ai-0.3.2/src/trellis/llm/providers/anthropic.py +137 -0
  112. trellis_ai-0.3.2/src/trellis/llm/providers/openai.py +157 -0
  113. trellis_ai-0.3.2/src/trellis/llm/types.py +40 -0
  114. trellis_ai-0.3.2/src/trellis/mcp/__init__.py +1 -0
  115. trellis_ai-0.3.2/src/trellis/mcp/_shared.py +88 -0
  116. trellis_ai-0.3.2/src/trellis/mcp/server.py +1212 -0
  117. trellis_ai-0.3.2/src/trellis/mutate/__init__.py +25 -0
  118. trellis_ai-0.3.2/src/trellis/mutate/commands.py +155 -0
  119. trellis_ai-0.3.2/src/trellis/mutate/executor.py +235 -0
  120. trellis_ai-0.3.2/src/trellis/mutate/handlers.py +249 -0
  121. trellis_ai-0.3.2/src/trellis/mutate/policy_gate.py +137 -0
  122. trellis_ai-0.3.2/src/trellis/py.typed +0 -0
  123. trellis_ai-0.3.2/src/trellis/retrieve/__init__.py +19 -0
  124. trellis_ai-0.3.2/src/trellis/retrieve/advisory_generator.py +519 -0
  125. trellis_ai-0.3.2/src/trellis/retrieve/budget_config.py +114 -0
  126. trellis_ai-0.3.2/src/trellis/retrieve/effectiveness.py +440 -0
  127. trellis_ai-0.3.2/src/trellis/retrieve/formatters.py +467 -0
  128. trellis_ai-0.3.2/src/trellis/retrieve/pack_builder.py +715 -0
  129. trellis_ai-0.3.2/src/trellis/retrieve/pack_sections.py +111 -0
  130. trellis_ai-0.3.2/src/trellis/retrieve/precedents.py +40 -0
  131. trellis_ai-0.3.2/src/trellis/retrieve/rerankers/__init__.py +12 -0
  132. trellis_ai-0.3.2/src/trellis/retrieve/rerankers/base.py +48 -0
  133. trellis_ai-0.3.2/src/trellis/retrieve/rerankers/mmr.py +141 -0
  134. trellis_ai-0.3.2/src/trellis/retrieve/rerankers/rrf.py +90 -0
  135. trellis_ai-0.3.2/src/trellis/retrieve/strategies.py +345 -0
  136. trellis_ai-0.3.2/src/trellis/retrieve/tier_mapping.py +175 -0
  137. trellis_ai-0.3.2/src/trellis/retrieve/token_tracker.py +60 -0
  138. trellis_ai-0.3.2/src/trellis/retrieve/token_usage.py +125 -0
  139. trellis_ai-0.3.2/src/trellis/schemas/__init__.py +94 -0
  140. trellis_ai-0.3.2/src/trellis/schemas/advisory.py +55 -0
  141. trellis_ai-0.3.2/src/trellis/schemas/classification.py +55 -0
  142. trellis_ai-0.3.2/src/trellis/schemas/entity.py +96 -0
  143. trellis_ai-0.3.2/src/trellis/schemas/enums.py +93 -0
  144. trellis_ai-0.3.2/src/trellis/schemas/evidence.py +39 -0
  145. trellis_ai-0.3.2/src/trellis/schemas/extraction.py +89 -0
  146. trellis_ai-0.3.2/src/trellis/schemas/graph.py +29 -0
  147. trellis_ai-0.3.2/src/trellis/schemas/pack.py +158 -0
  148. trellis_ai-0.3.2/src/trellis/schemas/policy.py +38 -0
  149. trellis_ai-0.3.2/src/trellis/schemas/precedent.py +27 -0
  150. trellis_ai-0.3.2/src/trellis/schemas/trace.py +95 -0
  151. trellis_ai-0.3.2/src/trellis/schemas/trace_builder.py +236 -0
  152. trellis_ai-0.3.2/src/trellis/stores/__init__.py +35 -0
  153. trellis_ai-0.3.2/src/trellis/stores/advisory_store.py +110 -0
  154. trellis_ai-0.3.2/src/trellis/stores/base/__init__.py +19 -0
  155. trellis_ai-0.3.2/src/trellis/stores/base/blob.py +41 -0
  156. trellis_ai-0.3.2/src/trellis/stores/base/document.py +76 -0
  157. trellis_ai-0.3.2/src/trellis/stores/base/event_log.py +149 -0
  158. trellis_ai-0.3.2/src/trellis/stores/base/graph.py +286 -0
  159. trellis_ai-0.3.2/src/trellis/stores/base/trace.py +44 -0
  160. trellis_ai-0.3.2/src/trellis/stores/base/vector.py +56 -0
  161. trellis_ai-0.3.2/src/trellis/stores/document.py +6 -0
  162. trellis_ai-0.3.2/src/trellis/stores/event_log.py +6 -0
  163. trellis_ai-0.3.2/src/trellis/stores/graph.py +6 -0
  164. trellis_ai-0.3.2/src/trellis/stores/lancedb/__init__.py +5 -0
  165. trellis_ai-0.3.2/src/trellis/stores/lancedb/store.py +236 -0
  166. trellis_ai-0.3.2/src/trellis/stores/local/__init__.py +5 -0
  167. trellis_ai-0.3.2/src/trellis/stores/local/blob.py +71 -0
  168. trellis_ai-0.3.2/src/trellis/stores/pgvector/__init__.py +5 -0
  169. trellis_ai-0.3.2/src/trellis/stores/pgvector/store.py +205 -0
  170. trellis_ai-0.3.2/src/trellis/stores/policy_store.py +79 -0
  171. trellis_ai-0.3.2/src/trellis/stores/postgres/__init__.py +13 -0
  172. trellis_ai-0.3.2/src/trellis/stores/postgres/base.py +39 -0
  173. trellis_ai-0.3.2/src/trellis/stores/postgres/document.py +287 -0
  174. trellis_ai-0.3.2/src/trellis/stores/postgres/event_log.py +214 -0
  175. trellis_ai-0.3.2/src/trellis/stores/postgres/graph.py +862 -0
  176. trellis_ai-0.3.2/src/trellis/stores/postgres/trace.py +191 -0
  177. trellis_ai-0.3.2/src/trellis/stores/registry.py +604 -0
  178. trellis_ai-0.3.2/src/trellis/stores/s3/__init__.py +5 -0
  179. trellis_ai-0.3.2/src/trellis/stores/s3/blob.py +142 -0
  180. trellis_ai-0.3.2/src/trellis/stores/sqlite/__init__.py +15 -0
  181. trellis_ai-0.3.2/src/trellis/stores/sqlite/base.py +35 -0
  182. trellis_ai-0.3.2/src/trellis/stores/sqlite/document.py +297 -0
  183. trellis_ai-0.3.2/src/trellis/stores/sqlite/event_log.py +177 -0
  184. trellis_ai-0.3.2/src/trellis/stores/sqlite/graph.py +943 -0
  185. trellis_ai-0.3.2/src/trellis/stores/sqlite/trace.py +173 -0
  186. trellis_ai-0.3.2/src/trellis/stores/sqlite/vector.py +182 -0
  187. trellis_ai-0.3.2/src/trellis/stores/trace.py +6 -0
  188. trellis_ai-0.3.2/src/trellis/stores/vector.py +6 -0
  189. trellis_ai-0.3.2/src/trellis_api/__init__.py +1 -0
  190. trellis_ai-0.3.2/src/trellis_api/app.py +89 -0
  191. trellis_ai-0.3.2/src/trellis_api/deps.py +37 -0
  192. trellis_ai-0.3.2/src/trellis_api/models.py +269 -0
  193. trellis_ai-0.3.2/src/trellis_api/py.typed +0 -0
  194. trellis_ai-0.3.2/src/trellis_api/routes/__init__.py +1 -0
  195. trellis_ai-0.3.2/src/trellis_api/routes/admin.py +263 -0
  196. trellis_ai-0.3.2/src/trellis_api/routes/curate.py +164 -0
  197. trellis_ai-0.3.2/src/trellis_api/routes/ingest.py +320 -0
  198. trellis_ai-0.3.2/src/trellis_api/routes/mutations.py +82 -0
  199. trellis_ai-0.3.2/src/trellis_api/routes/policies.py +98 -0
  200. trellis_ai-0.3.2/src/trellis_api/routes/retrieve.py +285 -0
  201. trellis_ai-0.3.2/src/trellis_api/static/index.html +2112 -0
  202. trellis_ai-0.3.2/src/trellis_cli/__init__.py +1 -0
  203. trellis_ai-0.3.2/src/trellis_cli/admin.py +857 -0
  204. trellis_ai-0.3.2/src/trellis_cli/analyze.py +494 -0
  205. trellis_ai-0.3.2/src/trellis_cli/claude_integration.py +64 -0
  206. trellis_ai-0.3.2/src/trellis_cli/config.py +45 -0
  207. trellis_ai-0.3.2/src/trellis_cli/curate.py +217 -0
  208. trellis_ai-0.3.2/src/trellis_cli/demo.py +1273 -0
  209. trellis_ai-0.3.2/src/trellis_cli/ingest.py +308 -0
  210. trellis_ai-0.3.2/src/trellis_cli/main.py +36 -0
  211. trellis_ai-0.3.2/src/trellis_cli/output.py +93 -0
  212. trellis_ai-0.3.2/src/trellis_cli/policy.py +198 -0
  213. trellis_ai-0.3.2/src/trellis_cli/py.typed +0 -0
  214. trellis_ai-0.3.2/src/trellis_cli/retrieve.py +275 -0
  215. trellis_ai-0.3.2/src/trellis_cli/stores.py +60 -0
  216. trellis_ai-0.3.2/src/trellis_sdk/__init__.py +6 -0
  217. trellis_ai-0.3.2/src/trellis_sdk/async_client.py +352 -0
  218. trellis_ai-0.3.2/src/trellis_sdk/client.py +422 -0
  219. trellis_ai-0.3.2/src/trellis_sdk/py.typed +0 -0
  220. trellis_ai-0.3.2/src/trellis_sdk/skills.py +183 -0
  221. trellis_ai-0.3.2/src/trellis_workers/__init__.py +1 -0
  222. trellis_ai-0.3.2/src/trellis_workers/engine/__init__.py +1 -0
  223. trellis_ai-0.3.2/src/trellis_workers/engine/thinking.py +299 -0
  224. trellis_ai-0.3.2/src/trellis_workers/enrichment/__init__.py +13 -0
  225. trellis_ai-0.3.2/src/trellis_workers/enrichment/service.py +259 -0
  226. trellis_ai-0.3.2/src/trellis_workers/extract/__init__.py +19 -0
  227. trellis_ai-0.3.2/src/trellis_workers/extract/dbt_manifest.py +143 -0
  228. trellis_ai-0.3.2/src/trellis_workers/extract/openlineage.py +166 -0
  229. trellis_ai-0.3.2/src/trellis_workers/learning/__init__.py +1 -0
  230. trellis_ai-0.3.2/src/trellis_workers/learning/miner.py +262 -0
  231. trellis_ai-0.3.2/src/trellis_workers/maintenance/__init__.py +1 -0
  232. trellis_ai-0.3.2/src/trellis_workers/maintenance/retention.py +179 -0
  233. trellis_ai-0.3.2/src/trellis_workers/py.typed +0 -0
  234. trellis_ai-0.3.2/tests/__init__.py +0 -0
  235. trellis_ai-0.3.2/tests/integration/__init__.py +1 -0
  236. trellis_ai-0.3.2/tests/integration/obsidian/__init__.py +1 -0
  237. trellis_ai-0.3.2/tests/integration/obsidian/test_indexer.py +221 -0
  238. trellis_ai-0.3.2/tests/integration/obsidian/test_vault.py +230 -0
  239. trellis_ai-0.3.2/tests/unit/__init__.py +0 -0
  240. trellis_ai-0.3.2/tests/unit/api/__init__.py +0 -0
  241. trellis_ai-0.3.2/tests/unit/api/test_routes.py +545 -0
  242. trellis_ai-0.3.2/tests/unit/classify/__init__.py +0 -0
  243. trellis_ai-0.3.2/tests/unit/classify/dedup/__init__.py +0 -0
  244. trellis_ai-0.3.2/tests/unit/classify/dedup/test_minhash.py +141 -0
  245. trellis_ai-0.3.2/tests/unit/classify/test_classifiers.py +264 -0
  246. trellis_ai-0.3.2/tests/unit/classify/test_feedback_loop.py +83 -0
  247. trellis_ai-0.3.2/tests/unit/classify/test_graph_neighbor.py +170 -0
  248. trellis_ai-0.3.2/tests/unit/classify/test_importance.py +69 -0
  249. trellis_ai-0.3.2/tests/unit/classify/test_llm_classifier.py +155 -0
  250. trellis_ai-0.3.2/tests/unit/classify/test_pipeline.py +331 -0
  251. trellis_ai-0.3.2/tests/unit/cli/__init__.py +1 -0
  252. trellis_ai-0.3.2/tests/unit/cli/conftest.py +28 -0
  253. trellis_ai-0.3.2/tests/unit/cli/test_admin.py +216 -0
  254. trellis_ai-0.3.2/tests/unit/cli/test_analyze.py +209 -0
  255. trellis_ai-0.3.2/tests/unit/cli/test_curate.py +171 -0
  256. trellis_ai-0.3.2/tests/unit/cli/test_graph_health.py +160 -0
  257. trellis_ai-0.3.2/tests/unit/cli/test_ingest.py +219 -0
  258. trellis_ai-0.3.2/tests/unit/cli/test_policy.py +212 -0
  259. trellis_ai-0.3.2/tests/unit/cli/test_quickstart.py +248 -0
  260. trellis_ai-0.3.2/tests/unit/cli/test_retrieve.py +125 -0
  261. trellis_ai-0.3.2/tests/unit/core/__init__.py +0 -0
  262. trellis_ai-0.3.2/tests/unit/core/test_base.py +43 -0
  263. trellis_ai-0.3.2/tests/unit/core/test_ids.py +36 -0
  264. trellis_ai-0.3.2/tests/unit/extract/__init__.py +0 -0
  265. trellis_ai-0.3.2/tests/unit/extract/prompts/__init__.py +0 -0
  266. trellis_ai-0.3.2/tests/unit/extract/prompts/test_base.py +139 -0
  267. trellis_ai-0.3.2/tests/unit/extract/test_alias_match.py +193 -0
  268. trellis_ai-0.3.2/tests/unit/extract/test_base.py +83 -0
  269. trellis_ai-0.3.2/tests/unit/extract/test_commands.py +118 -0
  270. trellis_ai-0.3.2/tests/unit/extract/test_dispatcher.py +189 -0
  271. trellis_ai-0.3.2/tests/unit/extract/test_hybrid.py +496 -0
  272. trellis_ai-0.3.2/tests/unit/extract/test_json_rules.py +541 -0
  273. trellis_ai-0.3.2/tests/unit/extract/test_llm.py +420 -0
  274. trellis_ai-0.3.2/tests/unit/extract/test_registry.py +97 -0
  275. trellis_ai-0.3.2/tests/unit/extract/test_save_memory.py +159 -0
  276. trellis_ai-0.3.2/tests/unit/feedback/__init__.py +0 -0
  277. trellis_ai-0.3.2/tests/unit/feedback/test_feedback.py +496 -0
  278. trellis_ai-0.3.2/tests/unit/learning/__init__.py +0 -0
  279. trellis_ai-0.3.2/tests/unit/learning/test_scoring.py +529 -0
  280. trellis_ai-0.3.2/tests/unit/llm/__init__.py +0 -0
  281. trellis_ai-0.3.2/tests/unit/llm/test_anthropic_provider.py +213 -0
  282. trellis_ai-0.3.2/tests/unit/llm/test_openai_provider.py +241 -0
  283. trellis_ai-0.3.2/tests/unit/llm/test_protocol.py +97 -0
  284. trellis_ai-0.3.2/tests/unit/llm/test_types.py +64 -0
  285. trellis_ai-0.3.2/tests/unit/mcp/__init__.py +0 -0
  286. trellis_ai-0.3.2/tests/unit/mcp/test_server.py +614 -0
  287. trellis_ai-0.3.2/tests/unit/mutate/__init__.py +0 -0
  288. trellis_ai-0.3.2/tests/unit/mutate/test_commands.py +155 -0
  289. trellis_ai-0.3.2/tests/unit/mutate/test_executor.py +196 -0
  290. trellis_ai-0.3.2/tests/unit/mutate/test_handlers.py +193 -0
  291. trellis_ai-0.3.2/tests/unit/mutate/test_policy_gate.py +177 -0
  292. trellis_ai-0.3.2/tests/unit/retrieve/__init__.py +0 -0
  293. trellis_ai-0.3.2/tests/unit/retrieve/rerankers/__init__.py +0 -0
  294. trellis_ai-0.3.2/tests/unit/retrieve/rerankers/test_mmr.py +115 -0
  295. trellis_ai-0.3.2/tests/unit/retrieve/rerankers/test_rrf.py +95 -0
  296. trellis_ai-0.3.2/tests/unit/retrieve/test_advisory_generator.py +326 -0
  297. trellis_ai-0.3.2/tests/unit/retrieve/test_budget_config.py +260 -0
  298. trellis_ai-0.3.2/tests/unit/retrieve/test_effectiveness.py +653 -0
  299. trellis_ai-0.3.2/tests/unit/retrieve/test_formatters.py +328 -0
  300. trellis_ai-0.3.2/tests/unit/retrieve/test_pack_builder.py +799 -0
  301. trellis_ai-0.3.2/tests/unit/retrieve/test_pack_sections.py +119 -0
  302. trellis_ai-0.3.2/tests/unit/retrieve/test_strategies.py +356 -0
  303. trellis_ai-0.3.2/tests/unit/retrieve/test_tier_mapping.py +117 -0
  304. trellis_ai-0.3.2/tests/unit/retrieve/test_token_tracker.py +252 -0
  305. trellis_ai-0.3.2/tests/unit/schemas/__init__.py +0 -0
  306. trellis_ai-0.3.2/tests/unit/schemas/test_advisory.py +103 -0
  307. trellis_ai-0.3.2/tests/unit/schemas/test_classification.py +158 -0
  308. trellis_ai-0.3.2/tests/unit/schemas/test_entity.py +233 -0
  309. trellis_ai-0.3.2/tests/unit/schemas/test_evidence.py +56 -0
  310. trellis_ai-0.3.2/tests/unit/schemas/test_extraction.py +129 -0
  311. trellis_ai-0.3.2/tests/unit/schemas/test_graph.py +41 -0
  312. trellis_ai-0.3.2/tests/unit/schemas/test_pack.py +284 -0
  313. trellis_ai-0.3.2/tests/unit/schemas/test_policy.py +37 -0
  314. trellis_ai-0.3.2/tests/unit/schemas/test_precedent.py +39 -0
  315. trellis_ai-0.3.2/tests/unit/schemas/test_trace.py +151 -0
  316. trellis_ai-0.3.2/tests/unit/schemas/test_trace_builder.py +313 -0
  317. trellis_ai-0.3.2/tests/unit/sdk/__init__.py +0 -0
  318. trellis_ai-0.3.2/tests/unit/sdk/test_async_client.py +163 -0
  319. trellis_ai-0.3.2/tests/unit/sdk/test_client.py +92 -0
  320. trellis_ai-0.3.2/tests/unit/sdk/test_skills.py +92 -0
  321. trellis_ai-0.3.2/tests/unit/stores/__init__.py +0 -0
  322. trellis_ai-0.3.2/tests/unit/stores/test_advisory_store.py +126 -0
  323. trellis_ai-0.3.2/tests/unit/stores/test_document_store.py +217 -0
  324. trellis_ai-0.3.2/tests/unit/stores/test_event_log.py +104 -0
  325. trellis_ai-0.3.2/tests/unit/stores/test_graph_store.py +293 -0
  326. trellis_ai-0.3.2/tests/unit/stores/test_lancedb_store.py +122 -0
  327. trellis_ai-0.3.2/tests/unit/stores/test_pgvector.py +112 -0
  328. trellis_ai-0.3.2/tests/unit/stores/test_policy_store.py +85 -0
  329. trellis_ai-0.3.2/tests/unit/stores/test_postgres_stores.py +393 -0
  330. trellis_ai-0.3.2/tests/unit/stores/test_registry_llm.py +326 -0
  331. trellis_ai-0.3.2/tests/unit/stores/test_s3_blob.py +206 -0
  332. trellis_ai-0.3.2/tests/unit/stores/test_temporal_graph.py +403 -0
  333. trellis_ai-0.3.2/tests/unit/stores/test_trace_store.py +129 -0
  334. trellis_ai-0.3.2/tests/unit/stores/test_vector_store.py +81 -0
  335. trellis_ai-0.3.2/tests/unit/test_errors.py +44 -0
  336. trellis_ai-0.3.2/tests/unit/workers/__init__.py +0 -0
  337. trellis_ai-0.3.2/tests/unit/workers/engine/__init__.py +0 -0
  338. trellis_ai-0.3.2/tests/unit/workers/engine/test_thinking.py +349 -0
  339. trellis_ai-0.3.2/tests/unit/workers/enrichment/__init__.py +0 -0
  340. trellis_ai-0.3.2/tests/unit/workers/enrichment/test_service.py +290 -0
  341. trellis_ai-0.3.2/tests/unit/workers/learning/__init__.py +0 -0
  342. trellis_ai-0.3.2/tests/unit/workers/learning/test_miner.py +391 -0
  343. trellis_ai-0.3.2/tests/unit/workers/maintenance/__init__.py +0 -0
  344. trellis_ai-0.3.2/tests/unit/workers/maintenance/test_retention.py +282 -0
  345. trellis_ai-0.3.2/tests/unit/workers/test_ingestion.py +256 -0
@@ -0,0 +1,24 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+
8
+ # Virtual environments
9
+ .venv/
10
+ venv/
11
+
12
+ # Tools
13
+ .mypy_cache/
14
+ .ruff_cache/
15
+ .pytest_cache/
16
+
17
+ # Data
18
+ data/
19
+ *.db
20
+
21
+ # Environment
22
+ .env
23
+ pytest-of-*
24
+ tmp*
@@ -0,0 +1,109 @@
1
+ # Changelog
2
+
3
+ All notable changes to Trellis will be documented in this file.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.3.2] - 2026-04-17
8
+
9
+ ### Fixed
10
+
11
+ - Publish workflow's `publish` job failed at `actions/checkout` with "repository not found" because the explicit `permissions: id-token: write` block implicitly set `contents: none`. Added `contents: read` alongside the OIDC token permission.
12
+
13
+ ## [0.3.1] - 2026-04-17
14
+
15
+ ### Fixed
16
+
17
+ - `mypy` error in [`src/trellis_sdk/async_client.py`](src/trellis_sdk/async_client.py) that blocked the `test` job in the publish workflow. The `type: ignore[arg-type]` was on the wrong line inside a multi-line `httpx.AsyncClient(...)` call. The initial `v0.3.0` tag never produced a PyPI artifact — this is the first actual release.
18
+
19
+ ## [0.3.0] - 2026-04-17
20
+
21
+ ### Breaking changes
22
+
23
+ - **Removed `trellis-mcp-legacy` entry point** and deleted `src/trellis/mcp_server.py`. The current MCP server lives at `src/trellis/mcp/server.py` and is exposed as `trellis-mcp`. Anyone invoking `trellis-mcp-legacy` should switch to `trellis-mcp`.
24
+ - **Removed `[langgraph]` optional extra.** The LangGraph integration is no longer shipped in the wheel — it lives in [`examples/integrations/langgraph/`](examples/integrations/langgraph/) as a copy-paste reference template. Install `langgraph` and `langchain-core` directly in your project and copy `tools.py` in.
25
+ - **Moved `integrations/` to `examples/integrations/`.** None of the integrations (LangGraph, Obsidian, OpenClaw) ship in the wheel. They are reference templates you copy into your project. Test imports updated from `integrations.obsidian.*` to `examples.integrations.obsidian.*`.
26
+
27
+ ### Added
28
+
29
+ - **PyPI publishing pipeline**: trusted-publisher (OIDC) workflow, `make build`/`verify-wheel`/`publish-check` targets, `workflow_dispatch` re-run path, `twine check` step, [RELEASING.md](RELEASING.md) runbook.
30
+ - **Examples directory** ([`examples/`](examples/)): SDK local + remote demos, retrieve→act→record loop, custom extractor, custom classifier, LangGraph agent, batch ingest script, and an MCP-from-Claude-Code walkthrough.
31
+ - **Skill templates** ([`skills/`](skills/)): drop-in Claude Code skills for `retrieve-before-task`, `record-after-task`, `link-evidence`.
32
+ - **MCP setup guides** for Claude Code, Cursor, and Claude Desktop in [`docs/getting-started/`](docs/getting-started/).
33
+ - **GitHub repo hygiene**: issue templates (bug, feature, config), PR template.
34
+ - **Python 3.13 support** added to CI matrix and PyPI classifiers.
35
+ - **`py.typed` markers** for `trellis_cli`, `trellis_sdk`, `trellis_api`, `trellis_workers` so type checkers see them as typed (`trellis` already had one).
36
+
37
+ ### Changed
38
+
39
+ - **MCP server documentation now lists 11 tools, not 8.** The three sectioned-context tools (`get_objective_context`, `get_task_context`, `get_sectioned_context`) were already in the server but missing from every doc surface. Updated [docs/agent-guide/operations.md](docs/agent-guide/operations.md), [examples/integrations/openclaw/SKILL.md](examples/integrations/openclaw/SKILL.md), [README.md](README.md), and the IDE setup guides.
40
+ - **README links rewritten to absolute URLs** so they render correctly on PyPI.
41
+
42
+ ## [0.2.0] - 2026-04-01
43
+
44
+ ### Added
45
+
46
+ - **Classification Layer**: Hybrid deterministic + LLM tagging pipeline for all ingested content
47
+ - Four orthogonal tag facets: `domain`, `content_type`, `scope`, `signal_quality`
48
+ - Four deterministic classifiers: `StructuralClassifier`, `KeywordDomainClassifier`, `SourceSystemClassifier`, `GraphNeighborClassifier`
49
+ - `LLMFacetClassifier` for async enrichment of ambiguous items (fires only when confidence < threshold)
50
+ - `ClassifierPipeline` with two modes: ingestion (deterministic-only, microseconds) and enrichment (+ LLM fallback)
51
+ - `compute_importance()` combining tags with LLM base scores for relevance ranking
52
+ - `apply_noise_tags()` feedback loop: effectiveness analysis flags low-value items as noise, excluding them from future packs
53
+ - Tag-based pre-filtering in `PackBuilder` (noise items excluded by default)
54
+
55
+ - **Web UI Foundation**: Dashboard served at `/ui` when running `trellis admin serve`
56
+ - Live store stats (traces, documents, nodes, edges, events)
57
+ - Store health status
58
+ - Placeholder views for Graph Explorer, Evolution, Traces, and Precedents
59
+ - Static files bundled in the PyPI wheel — no separate install needed
60
+
61
+ - **UI Design Documents**: Comprehensive design for full interactive UI
62
+ - Graph Explorer with force-directed layout and time-travel slider
63
+ - Evolution View: learning curve chart, pack composition drift, item lifecycle, domain generations
64
+ - Trace Timeline, Improvement Dashboard, Precedent Library
65
+ - ASCII wireframes, data flow diagrams, backend schema proposals
66
+ - Demo scenario specification (8-week improvement arc from 40% to 85% success rate)
67
+
68
+ - **Package extras**: `all` convenience extra (`pip install trellis-ai[all]`)
69
+
70
+ ### Changed
71
+
72
+ - FastAPI app version bumped to 0.2.0
73
+ - Fallback version updated to 0.2.0
74
+
75
+ ### Fixed
76
+
77
+ - 22 code review issues across correctness, efficiency, and quality
78
+ - `json_each` JOIN for multi-label domain filtering in SQLite stores
79
+ - `get_node_history` ordering (DESC by `valid_from` for newest-first)
80
+ - `StoreRegistry.close()` safety for partially initialized registries
81
+ - `_emit_telemetry` exception handling in PackBuilder
82
+ - Bounded idempotency cache (10K max) in MutationExecutor
83
+ - `Content-Type` validation in API ingest routes
84
+ - Defensive keyword extraction in `KeywordDomainClassifier`
85
+ - `classification_version` default set to `"1"` in ContentTags
86
+
87
+ ## [0.1.0] - 2025-12-15
88
+
89
+ ### Added
90
+
91
+ - Initial release
92
+ - Core library (`trellis`): schemas, stores, mutation executor, retrieval, MCP server
93
+ - CLI (`trellis`): admin, ingest, retrieve, curate, analyze commands
94
+ - REST API (`trellis-api`): FastAPI server on port 8420
95
+ - Python SDK (`trellis_sdk`): dual-mode client (local or remote via httpx)
96
+ - Background workers (`trellis_workers`): ingestion (dbt, OpenLineage), maintenance
97
+ - Six store ABCs: TraceStore, DocumentStore, GraphStore, VectorStore, EventLog, BlobStore
98
+ - SQLite default backends with PostgreSQL cloud backends
99
+ - SCD Type 2 temporal versioning on graph nodes (time-travel via `as_of`)
100
+ - 13 edge types for entity relationships
101
+ - Governed mutation pipeline: validate, policy check, idempotency, execute, emit
102
+ - Context pack builder with keyword, semantic, graph, and recency search strategies
103
+ - Token-budgeted retrieval with two-stage limits (max_items, max_tokens)
104
+ - MCP server with 8 macro tools for Claude and other MCP clients
105
+ - OpenClaw skill for Claude Code integration
106
+ - LangGraph integration
107
+ - Obsidian vault indexer
108
+ - Effectiveness analysis and feedback loop
109
+ - Token usage tracking and telemetry
@@ -0,0 +1,52 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, caste, color, religion, or sexual
10
+ identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to a positive environment:
15
+
16
+ - Using welcoming and inclusive language
17
+ - Being respectful of differing viewpoints and experiences
18
+ - Gracefully accepting constructive criticism
19
+ - Focusing on what is best for the community
20
+ - Showing empathy towards other community members
21
+
22
+ Examples of unacceptable behavior:
23
+
24
+ - The use of sexualized language or imagery, and sexual attention or advances of any kind
25
+ - Trolling, insulting or derogatory comments, and personal or political attacks
26
+ - Public or private harassment
27
+ - Publishing others' private information without explicit permission
28
+ - Other conduct which could reasonably be considered inappropriate in a professional setting
29
+
30
+ ## Enforcement Responsibilities
31
+
32
+ Community leaders are responsible for clarifying and enforcing our standards of
33
+ acceptable behavior and will take appropriate and fair corrective action in
34
+ response to any behavior that they deem inappropriate, threatening, offensive,
35
+ or harmful.
36
+
37
+ ## Scope
38
+
39
+ This Code of Conduct applies within all community spaces, and also applies when
40
+ an individual is officially representing the community in public spaces.
41
+
42
+ ## Enforcement
43
+
44
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
45
+ reported to the project maintainers at the email address listed in SECURITY.md.
46
+ All complaints will be reviewed and investigated promptly and fairly.
47
+
48
+ ## Attribution
49
+
50
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/),
51
+ version 2.1, available at
52
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).
@@ -0,0 +1,92 @@
1
+ # Contributing to Trellis
2
+
3
+ Thanks for your interest in contributing! This guide covers the essentials.
4
+
5
+ ## Development Setup
6
+
7
+ ```bash
8
+ # Clone and install with dev dependencies
9
+ git clone https://github.com/ronsse/trellis-ai.git
10
+ cd trellis-ai
11
+ uv pip install -e ".[dev]"
12
+
13
+ # Initialize stores (needed for integration-style tests)
14
+ trellis admin init
15
+ ```
16
+
17
+ ## Quality Checks
18
+
19
+ Run all checks before submitting a PR:
20
+
21
+ ```bash
22
+ make format # Auto-format with ruff
23
+ make lint # Lint check
24
+ make typecheck # mypy strict type checking
25
+ make test # Full test suite
26
+ ```
27
+
28
+ Or run them individually:
29
+
30
+ ```bash
31
+ ruff format src/ tests/ # Format
32
+ ruff check src/ tests/ # Lint
33
+ mypy src/ # Type check
34
+ pytest tests/ -v # Tests
35
+ pytest tests/unit/stores/ -v # Single directory
36
+ ```
37
+
38
+ ## Project Structure
39
+
40
+ ```
41
+ src/
42
+ trellis/ # Core library (schemas, stores, mutations, retrieval, MCP)
43
+ trellis_cli/ # CLI (trellis command)
44
+ trellis_api/ # REST API (FastAPI)
45
+ trellis_sdk/ # Client SDK (local or remote)
46
+ trellis_workers/ # Background workers (classification, ingestion)
47
+ tests/
48
+ unit/ # Mirrors src/ layout
49
+ docs/
50
+ agent-guide/ # Operational reference for AI agents
51
+ ```
52
+
53
+ ## How to Add a Store Backend
54
+
55
+ 1. Create `src/trellis/stores/<backend>/` with implementations for the ABCs in `stores/base/` (TraceStore, DocumentStore, GraphStore, VectorStore, EventLog, BlobStore).
56
+ 2. Register the backend in `stores/registry.py` so `StoreRegistry.from_config_dir()` can instantiate it from config.
57
+ 3. Add tests in `tests/unit/stores/` using `tmp_path` fixtures.
58
+
59
+ ## How to Add a Search Strategy
60
+
61
+ 1. Subclass `SearchStrategy` in `src/trellis/retrieve/strategies.py` (or a new module under `retrieve/`).
62
+ 2. Implement `name` property and `search()` method returning `list[PackItem]`.
63
+ 3. Wire it into `build_strategies()` or document how users can add it to `PackBuilder`.
64
+
65
+ ## How to Extend Classification
66
+
67
+ 1. Implement the `Classifier` protocol in `src/trellis/classify/`.
68
+ 2. Register it in `ClassifierPipeline` — deterministic classifiers run inline at ingest time.
69
+ 3. Add tests with synthetic items covering each classification decision.
70
+
71
+ ## Pull Request Process
72
+
73
+ 1. Branch from `main`. Use descriptive branch names (`feat/reranker-protocol`, `fix/session-dedup`).
74
+ 2. All PRs run lint, typecheck, and test workflows automatically.
75
+ 3. Keep PRs focused — one feature or fix per PR.
76
+ 4. Write tests for new functionality. Target the existing test style: unit-scoped, `tmp_path` for stores, `MagicMock(spec=...)` for protocols.
77
+ 5. Update `docs/agent-guide/` if your change affects the agent-facing API.
78
+
79
+ ## AI-Assisted Development
80
+
81
+ This project uses Claude Code for development. The `CLAUDE.md` file at the repo root provides context and rules for AI-assisted work. PRs authored or co-authored by AI are welcome — just include the `Co-Authored-By` trailer.
82
+
83
+ ## Code Style
84
+
85
+ - **Type hints** on all public APIs.
86
+ - **`structlog`** for logging (never `print()` in library code).
87
+ - **`extra="forbid"`** on all Pydantic models (via `TrellisModel` base).
88
+ - **Ruff** for formatting and linting — the pre-commit hook enforces this.
89
+
90
+ ## Questions?
91
+
92
+ Open a [GitHub Discussion](https://github.com/ronsse/trellis-ai/discussions) or file an issue.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nathan Ronsse
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,45 @@
1
+ .DEFAULT_GOAL := help
2
+
3
+ .PHONY: help install install-dev lint format typecheck test check clean build publish-check verify-wheel
4
+
5
+ help: ## Show this help message
6
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'
7
+
8
+ install: ## Install package
9
+ uv pip install -e .
10
+
11
+ install-dev: ## Install package with dev dependencies
12
+ uv pip install -e ".[dev]"
13
+ python -m pre_commit install
14
+
15
+ lint: ## Run linting
16
+ ruff check src/ tests/
17
+
18
+ format: ## Format code
19
+ ruff format src/ tests/
20
+ ruff check --fix src/ tests/
21
+
22
+ typecheck: ## Run type checking
23
+ mypy src/
24
+
25
+ test: ## Run tests
26
+ pytest tests/ -v
27
+
28
+ check: lint typecheck test ## Run all checks (lint + typecheck + test)
29
+
30
+ clean: ## Clean build artifacts
31
+ rm -rf dist/ build/ *.egg-info .mypy_cache .ruff_cache .pytest_cache
32
+ find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
33
+
34
+ build: clean ## Build sdist + wheel into dist/
35
+ python -m build
36
+
37
+ verify-wheel: build ## Build and inspect wheel contents (sanity-check before tagging)
38
+ @echo "--- wheel contents ---"
39
+ @unzip -l dist/*.whl
40
+ @echo
41
+ @echo "--- sdist contents ---"
42
+ @tar -tzf dist/*.tar.gz | head -50
43
+
44
+ publish-check: build ## Build and run twine check on the artifacts
45
+ python -m twine check dist/*