dacli 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. dacli-0.2.0/PKG-INFO +515 -0
  2. dacli-0.2.0/README.md +472 -0
  3. dacli-0.2.0/pyproject.toml +141 -0
  4. dacli-0.2.0/setup.cfg +4 -0
  5. dacli-0.2.0/src/dacli/__init__.py +7 -0
  6. dacli-0.2.0/src/dacli/config/__init__.py +34 -0
  7. dacli-0.2.0/src/dacli/config/policy.yaml +120 -0
  8. dacli-0.2.0/src/dacli/config/settings.py +765 -0
  9. dacli-0.2.0/src/dacli/connectors/__init__.py +17 -0
  10. dacli-0.2.0/src/dacli/connectors/airflow/SKILL.md +31 -0
  11. dacli-0.2.0/src/dacli/connectors/airflow/__init__.py +0 -0
  12. dacli-0.2.0/src/dacli/connectors/airflow/connector.py +270 -0
  13. dacli-0.2.0/src/dacli/connectors/airflow/manifest.yaml +13 -0
  14. dacli-0.2.0/src/dacli/connectors/base.py +196 -0
  15. dacli-0.2.0/src/dacli/connectors/bigquery/SKILL.md +31 -0
  16. dacli-0.2.0/src/dacli/connectors/bigquery/__init__.py +0 -0
  17. dacli-0.2.0/src/dacli/connectors/bigquery/connector.py +306 -0
  18. dacli-0.2.0/src/dacli/connectors/bigquery/manifest.yaml +13 -0
  19. dacli-0.2.0/src/dacli/connectors/cli_base.py +174 -0
  20. dacli-0.2.0/src/dacli/connectors/dagster/SKILL.md +28 -0
  21. dacli-0.2.0/src/dacli/connectors/dagster/__init__.py +0 -0
  22. dacli-0.2.0/src/dacli/connectors/dagster/connector.py +216 -0
  23. dacli-0.2.0/src/dacli/connectors/dagster/manifest.yaml +13 -0
  24. dacli-0.2.0/src/dacli/connectors/databricks/SKILL.md +28 -0
  25. dacli-0.2.0/src/dacli/connectors/databricks/__init__.py +0 -0
  26. dacli-0.2.0/src/dacli/connectors/databricks/connector.py +221 -0
  27. dacli-0.2.0/src/dacli/connectors/databricks/manifest.yaml +13 -0
  28. dacli-0.2.0/src/dacli/connectors/dbt/SKILL.md +39 -0
  29. dacli-0.2.0/src/dacli/connectors/dbt/__init__.py +0 -0
  30. dacli-0.2.0/src/dacli/connectors/dbt/connector.py +260 -0
  31. dacli-0.2.0/src/dacli/connectors/dbt/manifest.yaml +13 -0
  32. dacli-0.2.0/src/dacli/connectors/dispatcher.py +301 -0
  33. dacli-0.2.0/src/dacli/connectors/dod.py +210 -0
  34. dacli-0.2.0/src/dacli/connectors/dynamodb/SKILL.md +34 -0
  35. dacli-0.2.0/src/dacli/connectors/dynamodb/__init__.py +0 -0
  36. dacli-0.2.0/src/dacli/connectors/dynamodb/connector.py +301 -0
  37. dacli-0.2.0/src/dacli/connectors/dynamodb/manifest.yaml +13 -0
  38. dacli-0.2.0/src/dacli/connectors/gcs/SKILL.md +30 -0
  39. dacli-0.2.0/src/dacli/connectors/gcs/__init__.py +0 -0
  40. dacli-0.2.0/src/dacli/connectors/gcs/connector.py +242 -0
  41. dacli-0.2.0/src/dacli/connectors/gcs/manifest.yaml +13 -0
  42. dacli-0.2.0/src/dacli/connectors/github/SKILL.md +30 -0
  43. dacli-0.2.0/src/dacli/connectors/github/__init__.py +3 -0
  44. dacli-0.2.0/src/dacli/connectors/github/connector.py +1032 -0
  45. dacli-0.2.0/src/dacli/connectors/github/manifest.yaml +13 -0
  46. dacli-0.2.0/src/dacli/connectors/http_base.py +123 -0
  47. dacli-0.2.0/src/dacli/connectors/mcp_bridge/SKILL.md +39 -0
  48. dacli-0.2.0/src/dacli/connectors/mcp_bridge/__init__.py +0 -0
  49. dacli-0.2.0/src/dacli/connectors/mcp_bridge/connector.py +295 -0
  50. dacli-0.2.0/src/dacli/connectors/mcp_bridge/manifest.yaml +15 -0
  51. dacli-0.2.0/src/dacli/connectors/mongodb/SKILL.md +34 -0
  52. dacli-0.2.0/src/dacli/connectors/mongodb/__init__.py +0 -0
  53. dacli-0.2.0/src/dacli/connectors/mongodb/connector.py +300 -0
  54. dacli-0.2.0/src/dacli/connectors/mongodb/manifest.yaml +13 -0
  55. dacli-0.2.0/src/dacli/connectors/mysql/SKILL.md +30 -0
  56. dacli-0.2.0/src/dacli/connectors/mysql/__init__.py +0 -0
  57. dacli-0.2.0/src/dacli/connectors/mysql/connector.py +275 -0
  58. dacli-0.2.0/src/dacli/connectors/mysql/manifest.yaml +13 -0
  59. dacli-0.2.0/src/dacli/connectors/pinecone/SKILL.md +26 -0
  60. dacli-0.2.0/src/dacli/connectors/pinecone/__init__.py +3 -0
  61. dacli-0.2.0/src/dacli/connectors/pinecone/connector.py +257 -0
  62. dacli-0.2.0/src/dacli/connectors/pinecone/manifest.yaml +13 -0
  63. dacli-0.2.0/src/dacli/connectors/postgres/SKILL.md +30 -0
  64. dacli-0.2.0/src/dacli/connectors/postgres/__init__.py +0 -0
  65. dacli-0.2.0/src/dacli/connectors/postgres/connector.py +279 -0
  66. dacli-0.2.0/src/dacli/connectors/postgres/manifest.yaml +13 -0
  67. dacli-0.2.0/src/dacli/connectors/registry.py +493 -0
  68. dacli-0.2.0/src/dacli/connectors/s3/SKILL.md +31 -0
  69. dacli-0.2.0/src/dacli/connectors/s3/__init__.py +0 -0
  70. dacli-0.2.0/src/dacli/connectors/s3/connector.py +245 -0
  71. dacli-0.2.0/src/dacli/connectors/s3/manifest.yaml +13 -0
  72. dacli-0.2.0/src/dacli/connectors/shell/__init__.py +13 -0
  73. dacli-0.2.0/src/dacli/connectors/shell/connector.py +257 -0
  74. dacli-0.2.0/src/dacli/connectors/snowflake/SKILL.md +32 -0
  75. dacli-0.2.0/src/dacli/connectors/snowflake/__init__.py +3 -0
  76. dacli-0.2.0/src/dacli/connectors/snowflake/connector.py +627 -0
  77. dacli-0.2.0/src/dacli/connectors/snowflake/manifest.yaml +15 -0
  78. dacli-0.2.0/src/dacli/connectors/system/__init__.py +3 -0
  79. dacli-0.2.0/src/dacli/connectors/system/connector.py +510 -0
  80. dacli-0.2.0/src/dacli/connectors/templates/README.md +25 -0
  81. dacli-0.2.0/src/dacli/connectors/templates/cli_connector_template.py +77 -0
  82. dacli-0.2.0/src/dacli/connectors/templates/manifest_template.yaml +25 -0
  83. dacli-0.2.0/src/dacli/connectors/templates/rest_connector_template.py +124 -0
  84. dacli-0.2.0/src/dacli/context/__init__.py +16 -0
  85. dacli-0.2.0/src/dacli/context/assembler.py +303 -0
  86. dacli-0.2.0/src/dacli/context/budget.py +119 -0
  87. dacli-0.2.0/src/dacli/context/compaction.py +125 -0
  88. dacli-0.2.0/src/dacli/context/disclosure.py +101 -0
  89. dacli-0.2.0/src/dacli/context/pipeline.py +102 -0
  90. dacli-0.2.0/src/dacli/context/sources/__init__.py +13 -0
  91. dacli-0.2.0/src/dacli/context/sources/dbt_manifest.py +176 -0
  92. dacli-0.2.0/src/dacli/context/sources/terminal.py +185 -0
  93. dacli-0.2.0/src/dacli/context/spill.py +155 -0
  94. dacli-0.2.0/src/dacli/context/tokenizer.py +136 -0
  95. dacli-0.2.0/src/dacli/core/__init__.py +38 -0
  96. dacli-0.2.0/src/dacli/core/agent.py +723 -0
  97. dacli-0.2.0/src/dacli/core/atomicio.py +71 -0
  98. dacli-0.2.0/src/dacli/core/blackboard.py +274 -0
  99. dacli-0.2.0/src/dacli/core/connect_flow.py +241 -0
  100. dacli-0.2.0/src/dacli/core/connector_config.py +66 -0
  101. dacli-0.2.0/src/dacli/core/connector_generator.py +585 -0
  102. dacli-0.2.0/src/dacli/core/connector_index.py +184 -0
  103. dacli-0.2.0/src/dacli/core/connector_workflow.py +336 -0
  104. dacli-0.2.0/src/dacli/core/crypto.py +196 -0
  105. dacli-0.2.0/src/dacli/core/export_run.py +133 -0
  106. dacli-0.2.0/src/dacli/core/fastjson.py +46 -0
  107. dacli-0.2.0/src/dacli/core/headless.py +287 -0
  108. dacli-0.2.0/src/dacli/core/kernel.py +354 -0
  109. dacli-0.2.0/src/dacli/core/logging_setup.py +132 -0
  110. dacli-0.2.0/src/dacli/core/loop.py +316 -0
  111. dacli-0.2.0/src/dacli/core/memory.py +475 -0
  112. dacli-0.2.0/src/dacli/core/plan_preview.py +185 -0
  113. dacli-0.2.0/src/dacli/core/planner.py +324 -0
  114. dacli-0.2.0/src/dacli/core/pricing.py +309 -0
  115. dacli-0.2.0/src/dacli/core/router.py +335 -0
  116. dacli-0.2.0/src/dacli/core/setup_wizard.py +473 -0
  117. dacli-0.2.0/src/dacli/core/store.py +273 -0
  118. dacli-0.2.0/src/dacli/core/subagent.py +262 -0
  119. dacli-0.2.0/src/dacli/core/test_mode.py +107 -0
  120. dacli-0.2.0/src/dacli/core/timeutils.py +19 -0
  121. dacli-0.2.0/src/dacli/core/verify.py +477 -0
  122. dacli-0.2.0/src/dacli/eval/__init__.py +41 -0
  123. dacli-0.2.0/src/dacli/eval/__main__.py +95 -0
  124. dacli-0.2.0/src/dacli/eval/calibration.py +112 -0
  125. dacli-0.2.0/src/dacli/eval/dashboard.py +109 -0
  126. dacli-0.2.0/src/dacli/eval/golden/__init__.py +34 -0
  127. dacli-0.2.0/src/dacli/eval/golden/connectors.py +211 -0
  128. dacli-0.2.0/src/dacli/eval/golden/spine.py +218 -0
  129. dacli-0.2.0/src/dacli/eval/golden/terminal.py +346 -0
  130. dacli-0.2.0/src/dacli/eval/harness.py +147 -0
  131. dacli-0.2.0/src/dacli/eval/passk.py +153 -0
  132. dacli-0.2.0/src/dacli/eval/regression.py +145 -0
  133. dacli-0.2.0/src/dacli/eval/report.py +194 -0
  134. dacli-0.2.0/src/dacli/eval/selfimprove.py +146 -0
  135. dacli-0.2.0/src/dacli/eval/sim/__init__.py +36 -0
  136. dacli-0.2.0/src/dacli/eval/sim/cli.py +69 -0
  137. dacli-0.2.0/src/dacli/eval/sim/platforms.py +102 -0
  138. dacli-0.2.0/src/dacli/eval/sim/shell.py +321 -0
  139. dacli-0.2.0/src/dacli/eval/types.py +125 -0
  140. dacli-0.2.0/src/dacli/governance/__init__.py +68 -0
  141. dacli-0.2.0/src/dacli/governance/audit.py +168 -0
  142. dacli-0.2.0/src/dacli/governance/classifier.py +312 -0
  143. dacli-0.2.0/src/dacli/governance/command_classifier.py +472 -0
  144. dacli-0.2.0/src/dacli/governance/governor.py +409 -0
  145. dacli-0.2.0/src/dacli/governance/permissions.py +133 -0
  146. dacli-0.2.0/src/dacli/governance/policy_engine.py +203 -0
  147. dacli-0.2.0/src/dacli/governance/rollback.py +367 -0
  148. dacli-0.2.0/src/dacli/governance/shadow.py +120 -0
  149. dacli-0.2.0/src/dacli/governance/vocab.py +88 -0
  150. dacli-0.2.0/src/dacli/memory/__init__.py +60 -0
  151. dacli-0.2.0/src/dacli/memory/catalog.py +289 -0
  152. dacli-0.2.0/src/dacli/memory/episodic.py +71 -0
  153. dacli-0.2.0/src/dacli/memory/priors.py +162 -0
  154. dacli-0.2.0/src/dacli/memory/procedural.py +48 -0
  155. dacli-0.2.0/src/dacli/memory/retrieval.py +125 -0
  156. dacli-0.2.0/src/dacli/memory/semantic.py +45 -0
  157. dacli-0.2.0/src/dacli/memory/store.py +251 -0
  158. dacli-0.2.0/src/dacli/memory/verify.py +160 -0
  159. dacli-0.2.0/src/dacli/prompts/GUIDELINES.md +27 -0
  160. dacli-0.2.0/src/dacli/prompts/__init__.py +15 -0
  161. dacli-0.2.0/src/dacli/prompts/fragments/core.md +97 -0
  162. dacli-0.2.0/src/dacli/prompts/fragments/github.md +7 -0
  163. dacli-0.2.0/src/dacli/prompts/fragments/snowflake.md +11 -0
  164. dacli-0.2.0/src/dacli/prompts/system_prompt.py +91 -0
  165. dacli-0.2.0/src/dacli/reasoning/__init__.py +16 -0
  166. dacli-0.2.0/src/dacli/reasoning/llm.py +207 -0
  167. dacli-0.2.0/src/dacli/reasoning/model_router.py +234 -0
  168. dacli-0.2.0/src/dacli/reasoning/providers.py +376 -0
  169. dacli-0.2.0/src/dacli/reasoning/scripted.py +79 -0
  170. dacli-0.2.0/src/dacli/sandbox/__init__.py +25 -0
  171. dacli-0.2.0/src/dacli/sandbox/_worker.py +148 -0
  172. dacli-0.2.0/src/dacli/sandbox/bridge.py +102 -0
  173. dacli-0.2.0/src/dacli/sandbox/connector.py +121 -0
  174. dacli-0.2.0/src/dacli/sandbox/docker/worker.py +184 -0
  175. dacli-0.2.0/src/dacli/sandbox/docker_runtime.py +277 -0
  176. dacli-0.2.0/src/dacli/sandbox/factory.py +63 -0
  177. dacli-0.2.0/src/dacli/sandbox/policy.py +116 -0
  178. dacli-0.2.0/src/dacli/sandbox/runtime.py +203 -0
  179. dacli-0.2.0/src/dacli/sandbox/sdk.py +182 -0
  180. dacli-0.2.0/src/dacli/sandbox/shells/__init__.py +42 -0
  181. dacli-0.2.0/src/dacli/sandbox/shells/base.py +159 -0
  182. dacli-0.2.0/src/dacli/sandbox/shells/powershell.py +41 -0
  183. dacli-0.2.0/src/dacli/sandbox/shells/transports.py +257 -0
  184. dacli-0.2.0/src/dacli/sandbox/shells/windows_cmd.py +20 -0
  185. dacli-0.2.0/src/dacli/sandbox/shells/wsl.py +22 -0
  186. dacli-0.2.0/src/dacli/sandbox/shells/zsh.py +20 -0
  187. dacli-0.2.0/src/dacli/sandbox/terminal.py +341 -0
  188. dacli-0.2.0/src/dacli/sandbox/workspace.py +124 -0
  189. dacli-0.2.0/src/dacli/scripts/__init__.py +1 -0
  190. dacli-0.2.0/src/dacli/scripts/clean.py +73 -0
  191. dacli-0.2.0/src/dacli/scripts/cli.py +1556 -0
  192. dacli-0.2.0/src/dacli/scripts/smoke_connector_lifecycle.py +295 -0
  193. dacli-0.2.0/src/dacli/skills/__init__.py +12 -0
  194. dacli-0.2.0/src/dacli/skills/connector.py +73 -0
  195. dacli-0.2.0/src/dacli/skills/data_diff/SKILL.md +57 -0
  196. dacli-0.2.0/src/dacli/skills/data_diff/__init__.py +0 -0
  197. dacli-0.2.0/src/dacli/skills/data_diff/skill.py +270 -0
  198. dacli-0.2.0/src/dacli/skills/diagram_mermaid/SKILL.md +41 -0
  199. dacli-0.2.0/src/dacli/skills/diagram_mermaid/__init__.py +5 -0
  200. dacli-0.2.0/src/dacli/skills/diagram_mermaid/skill.py +203 -0
  201. dacli-0.2.0/src/dacli/skills/registry.py +141 -0
  202. dacli-0.2.0/src/dacli/skills/spec.py +85 -0
  203. dacli-0.2.0/src/dacli/tui/__init__.py +21 -0
  204. dacli-0.2.0/src/dacli/tui/design.py +153 -0
  205. dacli-0.2.0/src/dacli/tui/theme.py +329 -0
  206. dacli-0.2.0/src/dacli/tui/ui.py +1718 -0
  207. dacli-0.2.0/src/dacli.egg-info/PKG-INFO +515 -0
  208. dacli-0.2.0/src/dacli.egg-info/SOURCES.txt +262 -0
  209. dacli-0.2.0/src/dacli.egg-info/dependency_links.txt +1 -0
  210. dacli-0.2.0/src/dacli.egg-info/entry_points.txt +2 -0
  211. dacli-0.2.0/src/dacli.egg-info/requires.txt +36 -0
  212. dacli-0.2.0/src/dacli.egg-info/top_level.txt +1 -0
  213. dacli-0.2.0/tests/test_atomicio.py +93 -0
  214. dacli-0.2.0/tests/test_cli_init.py +101 -0
  215. dacli-0.2.0/tests/test_connector_dod.py +119 -0
  216. dacli-0.2.0/tests/test_context_phase3.py +352 -0
  217. dacli-0.2.0/tests/test_cost_governance.py +196 -0
  218. dacli-0.2.0/tests/test_crypto.py +91 -0
  219. dacli-0.2.0/tests/test_data_diff_skill.py +234 -0
  220. dacli-0.2.0/tests/test_eval_report.py +87 -0
  221. dacli-0.2.0/tests/test_golden_transcript.py +224 -0
  222. dacli-0.2.0/tests/test_governance_phase5.py +508 -0
  223. dacli-0.2.0/tests/test_governance_vocab.py +66 -0
  224. dacli-0.2.0/tests/test_headless.py +301 -0
  225. dacli-0.2.0/tests/test_initialize_and_sessions_p04.py +157 -0
  226. dacli-0.2.0/tests/test_kernel_logging.py +78 -0
  227. dacli-0.2.0/tests/test_llm_google.py +63 -0
  228. dacli-0.2.0/tests/test_llm_retry.py +165 -0
  229. dacli-0.2.0/tests/test_logging_setup.py +80 -0
  230. dacli-0.2.0/tests/test_memory_phase2.py +328 -0
  231. dacli-0.2.0/tests/test_orchestration_phase6.py +299 -0
  232. dacli-0.2.0/tests/test_orchestration_wiring_p08.py +241 -0
  233. dacli-0.2.0/tests/test_p11_catalog_cli.py +132 -0
  234. dacli-0.2.0/tests/test_p11_ci_scenarios.py +63 -0
  235. dacli-0.2.0/tests/test_p11_connector_install.py +170 -0
  236. dacli-0.2.0/tests/test_p11_dbt_context.py +189 -0
  237. dacli-0.2.0/tests/test_p11_export_run.py +152 -0
  238. dacli-0.2.0/tests/test_p11_mcp_bridge.py +211 -0
  239. dacli-0.2.0/tests/test_p12_docs_and_help.py +65 -0
  240. dacli-0.2.0/tests/test_p12_lazy_connectors.py +67 -0
  241. dacli-0.2.0/tests/test_p12_orjson.py +114 -0
  242. dacli-0.2.0/tests/test_p12_pricing_offline.py +70 -0
  243. dacli-0.2.0/tests/test_p12_prompt_single_source.py +56 -0
  244. dacli-0.2.0/tests/test_p12_timeutils.py +65 -0
  245. dacli-0.2.0/tests/test_perf_p05.py +172 -0
  246. dacli-0.2.0/tests/test_phase7_wave1.py +340 -0
  247. dacli-0.2.0/tests/test_phase7_wave2.py +270 -0
  248. dacli-0.2.0/tests/test_phase7_wave3.py +195 -0
  249. dacli-0.2.0/tests/test_phase8_eval.py +273 -0
  250. dacli-0.2.0/tests/test_plan_command.py +114 -0
  251. dacli-0.2.0/tests/test_provider_protocol.py +136 -0
  252. dacli-0.2.0/tests/test_quality_p07.py +145 -0
  253. dacli-0.2.0/tests/test_sandbox_docker.py +246 -0
  254. dacli-0.2.0/tests/test_sandbox_retention.py +71 -0
  255. dacli-0.2.0/tests/test_security_p06.py +171 -0
  256. dacli-0.2.0/tests/test_settings.py +73 -0
  257. dacli-0.2.0/tests/test_skills_phase4.py +361 -0
  258. dacli-0.2.0/tests/test_store_logging.py +44 -0
  259. dacli-0.2.0/tests/test_terminal_phase1.py +695 -0
  260. dacli-0.2.0/tests/test_tool_result.py +40 -0
  261. dacli-0.2.0/tests/test_tui.py +408 -0
  262. dacli-0.2.0/tests/test_tui_ux_p08.py +227 -0
  263. dacli-0.2.0/tests/test_tui_visual.py +706 -0
  264. dacli-0.2.0/tests/test_usage.py +223 -0
dacli-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,515 @@
1
+ Metadata-Version: 2.4
2
+ Name: dacli
3
+ Version: 0.2.0
4
+ Summary: Your autonomous data engineering CLI agent
5
+ Author-email: Mouad Jaouhari <github@mj-dev.net>
6
+ Project-URL: Homepage, https://github.com/mouadja02/dacli
7
+ Keywords: data engineering,autonomous agent,data engineering CLI
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: anthropic<1,>=0.40
18
+ Requires-Dist: openai<3,>=1.40
19
+ Requires-Dist: click<9,>=8
20
+ Requires-Dist: rich<16,>=13
21
+ Requires-Dist: prompt-toolkit<4,>=3
22
+ Requires-Dist: pydantic<3,>=2.5
23
+ Requires-Dist: pyyaml<7,>=6
24
+ Requires-Dist: python-dotenv<2,>=1
25
+ Requires-Dist: httpx<1,>=0.27
26
+ Requires-Dist: cryptography<49,>=42
27
+ Requires-Dist: tiktoken<1,>=0.7
28
+ Provides-Extra: snowflake
29
+ Requires-Dist: snowflake-connector-python<5,>=3.5; extra == "snowflake"
30
+ Provides-Extra: pinecone
31
+ Requires-Dist: pinecone<10,>=4; extra == "pinecone"
32
+ Provides-Extra: pty
33
+ Requires-Dist: pywinpty<3,>=2; sys_platform == "win32" and extra == "pty"
34
+ Requires-Dist: ptyprocess<1,>=0.7; sys_platform != "win32" and extra == "pty"
35
+ Provides-Extra: mcp
36
+ Requires-Dist: mcp<2,>=1; extra == "mcp"
37
+ Provides-Extra: dev
38
+ Requires-Dist: pytest<10,>=8; extra == "dev"
39
+ Requires-Dist: ruff<0.16,>=0.15; extra == "dev"
40
+ Requires-Dist: vulture<3,>=2; extra == "dev"
41
+ Provides-Extra: all
42
+ Requires-Dist: dacli[pinecone,snowflake]; extra == "all"
43
+
44
+ <div align="center">
45
+
46
+ # dacli
47
+
48
+ **An autonomous, reliability-first data-engineering agent for your terminal.**
49
+
50
+ *Talk to your data stack in plain language — dacli plans, runs SQL, moves files, builds pipelines,
51
+ orchestrates jobs, and draws diagrams across 14 platforms, with governance and verification on every action.*
52
+
53
+ [![CI](https://github.com/mouadja02/dacli/actions/workflows/ci.yml/badge.svg)](https://github.com/mouadja02/dacli/actions/workflows/ci.yml)
54
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
55
+ [![Tests](https://img.shields.io/badge/tests-605-brightgreen.svg)](#testing)
56
+ [![Reliability](https://img.shields.io/badge/reliability-pass%5Ek-orange.svg)](docs/EVALUATION.md)
57
+ [![Architecture](https://img.shields.io/badge/architecture-six--component%20harness-8A2BE2.svg)](docs/ARCHITECTURE.md)
58
+
59
+ [Quick start](#quick-start) · [Architecture](docs/ARCHITECTURE.md) · [Connectors](docs/CONNECTORS.md) · [Governance](docs/GOVERNANCE.md) · [Evaluation](docs/EVALUATION.md)
60
+
61
+ </div>
62
+
63
+ ---
64
+
65
+ ## Table of contents
66
+
67
+ - [Why dacli](#why-dacli)
68
+ - [Highlights](#highlights)
69
+ - [How it works](#how-it-works)
70
+ - [Supported platforms](#supported-platforms)
71
+ - [Installation](#installation)
72
+ - [Configuration](#configuration)
73
+ - [Quick start](#quick-start)
74
+ - [Command reference](#command-reference)
75
+ - [Reliability: the environment is the oracle](#reliability-the-environment-is-the-oracle)
76
+ - [Project layout](#project-layout)
77
+ - [Extending dacli](#extending-dacli)
78
+ - [Testing](#testing)
79
+ - [Documentation](#documentation)
80
+ - [Status](#status)
81
+ - [Contributing](#contributing)
82
+ - [License](#license)
83
+
84
+ ---
85
+
86
+ ## Why dacli
87
+
88
+ Most "AI for data" tools are a chat window that gives *advice*. dacli is an **agent that operates your stack**:
89
+ it reasons over a real, connected toolset — warehouses, lakes, operational databases, transformation,
90
+ orchestration, and diagramming — and carries tasks through to a verified result.
91
+
92
+ The hard problem with autonomous data agents is not capability, it is **reliability**. A 95%-reliable
93
+ `DROP`-guard is a catastrophe waiting for its 1-in-20. dacli is built on a simple thesis, drawn from
94
+ *["From Model Scaling to System Scaling"](https://arxiv.org/abs/2605.26112)*:
95
+
96
+ > **Agent reliability is a property of the *system around the model*, not the model.**
97
+ > Stale memory, diluted context, unchecked tool output, and missing governance are *system failures* that
98
+ > survive every model upgrade.
99
+
100
+ So dacli is engineered as a **six-component harness** (ℛ Reasoning · ℳ Memory · 𝒞 Context · 𝒮 Skills ·
101
+ 𝒪 Orchestration · 𝒢 Governance), and its signature idea is **"the environment is the oracle"** — verification
102
+ and rollback are anchored to native platform features (transactions, Time Travel/`UNDROP`, `EXPLAIN`/`dry_run`,
103
+ zero-copy clones, `dbt test`, row counts) rather than to the model's own say-so.
104
+
105
+ > Built **from scratch** — no agent frameworks (no LangChain/LangGraph) and an **MCP-free core**. Tools are
106
+ > plain Python/CLI the agent composes as code, which keeps context lean and execution auditable. (An opt-in
107
+ > **MCP client bridge** can proxy one external MCP server's tools through the same governed dispatch path —
108
+ > the core itself never speaks MCP.)
109
+
110
+ ---
111
+
112
+ ## Highlights
113
+
114
+ | | |
115
+ |---|---|
116
+ | 🧠 **Conversational data ops** | Describe the goal; dacli plans a DAG, routes each step, acts, observes, and verifies — iterating until the outcome is provably correct. |
117
+ | 🔌 **14 platform connectors** | Each platform is a self-describing plugin discovered from a `manifest.yaml`. Adding one is "drop in a folder", never "edit the agent". |
118
+ | 🛡️ **Governance on every action** | A blast-radius classifier tiers each action `safe → write → risky → irreversible`, then a policy engine gates it: auto, verify, confirm, or dry-run + verified-rollback + approval. |
119
+ | ✅ **Verified, not just fluent** | Every operation declares **environment-anchored post-conditions**; a result is "done" only when the platform confirms it (row counts, `bq show`, statement state, `dbt` artifacts). |
120
+ | 🧪 **Code-execution sandbox** | Complex/multi-step/cross-platform jobs run as governed code; large results stay **on disk**, out of the model's context. |
121
+ | 📒 **Trustworthy memory** | Typed facts with confidence, recency, and provenance; retrieval penalizes staleness; trust is a **runtime decision** — re-verified against the live system before acting. |
122
+ | 🧭 **Multi-agent orchestration** | A lead fans breadth-first work out to isolated-context sub-agents with contradiction detection and de-duplication. |
123
+ | 📊 **pass^k reliability eval** | An offline golden suite measures consistency across *repeated* rollouts (not single-shot luck), with regression detection and a reliability dashboard. |
124
+ | 🔍 **Fully auditable** | Append-only ledgers record every classification, policy decision, rollback plan, approval, and post-condition verdict — `dacli audit` reconstructs *why* the agent acted. |
125
+ | 🤖 **Multi-provider LLM** | OpenAI, Anthropic, or OpenRouter (Google Gemini planned), with cheap/strong **model tiering** and confidence-aware escalation. |
126
+ | 🎨 **Elite terminal UX** | Pure Rich + prompt-toolkit: live formatted Markdown streaming, tier-colored tool cards, a real context gauge, a first-class approval panel, and seven themes — fully accessible (`NO_COLOR`, ASCII glyphs, reduced motion, high contrast) and scrollback-native. |
127
+
128
+ ---
129
+
130
+ ## How it works
131
+
132
+ ```mermaid
133
+ flowchart TD
134
+ U[CLI / TUI] --> K[Orchestration Kernel 𝒪<br/>plan → act → observe → verify]
135
+ K --> R[Reasoning ℛ<br/>model tiering + escalation]
136
+ K --> C[Context 𝒞<br/>priors + JIT + live search]
137
+ K --> M[Memory ℳ<br/>confidence · staleness · provenance]
138
+ K --> S[Skill Router 𝒮<br/>tool tier vs. sandbox tier]
139
+ K --> G[Governance 𝒢<br/>classify → policy → rollback → audit]
140
+
141
+ S --> TOOL[Tool tier<br/>direct typed connector call]
142
+ S --> SBX[Sandbox tier<br/>governed code execution<br/>results stay on disk]
143
+ G -. gates every action .-> TOOL
144
+ G -. gates every action .-> SBX
145
+
146
+ TOOL --> CONN[Connector layer · plugins]
147
+ SBX --> CONN
148
+ CONN --> P[(Snowflake · BigQuery · Databricks · dbt<br/>S3 · GCS · Postgres · MySQL · Mongo · DynamoDB<br/>Airflow · Dagster · GitHub · Pinecone)]
149
+ ```
150
+
151
+ Every state-changing action flows through one governed dispatch path — so the tool tier *and* the
152
+ code-execution sandbox are governed and verified identically. See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
153
+ for the full design.
154
+
155
+ ---
156
+
157
+ ## Supported platforms
158
+
159
+ dacli ships **14 platform connectors** plus a diagram-as-code skill. Each connector declares its operations,
160
+ risk tiers, environment-anchored post-conditions, and a native rollback primitive (the "Definition of Done",
161
+ enforced in CI — see [docs/CONNECTORS.md](docs/CONNECTORS.md)).
162
+
163
+ | Category | Connector | Highlights | Native rollback primitive |
164
+ |---|---|---|---|
165
+ | **Warehouses** | ❄️ Snowflake | SQL, context introspection, catalog | Time Travel / `UNDROP`, zero-copy clone |
166
+ | | 🔷 BigQuery | SQL, `dry_run` cost preview, `bq show` oracle | table snapshot / time travel |
167
+ | | 🧱 Databricks | SQL warehouse, statement-state oracle | Delta time travel / shallow clone |
168
+ | **Transformation** | 🔧 dbt | `run`/`build`/`test`, manifest lineage | git-versioned transform + target snapshot |
169
+ | **Object storage** | 🪣 Amazon S3 | list/read/put/delete, head-object oracle | versioned copy-aside |
170
+ | | ☁️ Google Cloud Storage | list/read/put/delete, `ls` oracle | object versioning |
171
+ | **Operational DBs** | 🐘 PostgreSQL | SQL via `psql`, transactional DDL | transaction / `pg_dump` |
172
+ | | 🐬 MySQL | SQL via `mysql` | transaction / `mysqldump` |
173
+ | | 🍃 MongoDB | queries via `mongosh`, schema inference | `mongodump` copy-aside |
174
+ | | ⚡ DynamoDB | item/table ops via `aws dynamodb` | point-in-time recovery |
175
+ | **Orchestration** | 🌬️ Airflow | trigger/monitor DAGs (REST API) | unpause / gated (no native undo) |
176
+ | | 🧩 Dagster | launch/monitor runs (GraphQL) | gated (terminate run) |
177
+ | **DevOps / docs** | 🐙 GitHub | repo files, Actions workflows, logs | revert commit / restore blob by SHA |
178
+ | | 📚 Pinecone | semantic search over your knowledge base | n/a (read-mostly) |
179
+ | **Diagramming** | 🎨 Mermaid *(skill)* | diagram-as-code from the live catalog | n/a |
180
+
181
+ CLI-first connectors (BigQuery, Databricks, dbt, S3, GCS, Postgres, MySQL, MongoDB, DynamoDB) shell out to
182
+ the platform's **first-class CLI** rather than bundling SDKs — install the CLIs you actually use.
183
+
184
+ ---
185
+
186
+ ## Installation
187
+
188
+ **Requirements:** Python **3.10+** (CI runs 3.10–3.12).
189
+
190
+ ```bash
191
+ git clone https://github.com/mouadja02/dacli.git
192
+ cd dacli
193
+
194
+ python -m venv .venv
195
+ # Windows
196
+ .venv\Scripts\activate
197
+ # macOS / Linux
198
+ source .venv/bin/activate
199
+
200
+ pip install -e . # one command — dependencies come from pyproject.toml
201
+ ```
202
+
203
+ Optional extras:
204
+
205
+ ```bash
206
+ pip install -e ".[all]" # + every Python-SDK connector (snowflake, pinecone)
207
+ pip install -e ".[dev]" # contributors: pytest, ruff, vulture
208
+ pip install -e ".[mcp]" # the opt-in MCP client bridge
209
+ pip install -e ".[pty]" # faithful TTY for the governed terminal
210
+ ```
211
+
212
+ > Use the **editable** install (`-e`). A plain `pip install .` copies the
213
+ > sources into `site-packages`, so the `dacli` command then runs that frozen
214
+ > copy and silently diverges from your working tree as you edit.
215
+
216
+ > For a byte-for-byte reproducible environment (what CI uses), install the pinned closure instead:
217
+ > `pip install -r requirements.lock && pip install -e . --no-deps`. Once dacli is published to PyPI,
218
+ > `pipx install dacli` / `uv tool install dacli` will be the primary one-line install.
219
+
220
+ For CLI-first connectors, install the relevant platform CLIs and authenticate them as you normally would:
221
+
222
+ | Connector | CLI to install |
223
+ |---|---|
224
+ | BigQuery / GCS | Google Cloud SDK (`bq`, `gcloud`) |
225
+ | Databricks | Databricks CLI (`databricks`) |
226
+ | S3 / DynamoDB | AWS CLI (`aws`) |
227
+ | dbt | `dbt-core` + the relevant adapter (e.g. `dbt-snowflake`) |
228
+ | Postgres / MySQL / Mongo | `psql` / `mysql` / `mongosh` |
229
+
230
+ ---
231
+
232
+ ## Configuration
233
+
234
+ **There is nothing to configure by hand.** The first `dacli` run launches the setup wizard: pick a
235
+ provider and model, paste an API key, choose connectors — secrets are encrypted at rest into
236
+ `.dacli/dacli.json` (see the [security model](#security-model)). No `config.yaml`, no `.env` needed.
237
+
238
+ ```bash
239
+ dacli # first run → wizard → chatting
240
+ ```
241
+
242
+ ### Advanced: file-based configuration (power users & CI)
243
+
244
+ dacli also reads a `config.yaml` (searched at `./config.yaml`, then `~/.dacli/config.yaml`) and
245
+ substitutes secrets from environment variables (`${VAR}` placeholders), which you can supply via a
246
+ `.env` file. Credentials never live in the config file.
247
+
248
+ ```bash
249
+ cp config_template.yaml config.yaml # set provider/model + account identifiers
250
+ cp .env.example .env # fill in your secrets
251
+ ```
252
+
253
+ ```dotenv
254
+ # .env
255
+ LLM_API_KEY=...
256
+ GITHUB_TOKEN=...
257
+ SNOWFLAKE_PASSWORD=...
258
+ PINECONE_API_KEY=...
259
+ OPENAI_API_KEY=... # used for Pinecone embeddings
260
+ ```
261
+
262
+ > `config.yaml`, `.env`, and the wizard-generated `config/connectors.yaml` are git-ignored.
263
+ > Full reference: **[docs/CONFIGURATION.md](docs/CONFIGURATION.md)**.
264
+
265
+ > **State durability & sessions.** Session state, encrypted secrets, memory, and
266
+ > usage live under `.dacli/` and are written **atomically** (temp file → `fsync`
267
+ > → `os.replace`), so a crash or `Ctrl-C` mid-write can never truncate or wipe a
268
+ > state file — a reader always sees the complete old or new file. There is **no
269
+ > cross-process lock**, so run **one dacli session per project directory at a
270
+ > time**; two sessions sharing the same `.dacli/` can overwrite each other's
271
+ > last-write-wins state.
272
+
273
+ ### Security model
274
+
275
+ Secrets entered through the wizard or `/connect` are encrypted at rest with **Fernet**; the encryption key
276
+ lives in `.dacli/.key` (git-ignored), next to the ciphertext in `.dacli/dacli.json`. Be clear about what
277
+ that buys you:
278
+
279
+ - **Protects against:** accidentally committing secrets to git, and casual inspection (screen-shares,
280
+ shoulder-surfing, grepping a backup of the repo).
281
+ - **Does not protect against:** a local attacker with filesystem access — the key and the ciphertext are
282
+ co-located, so anyone who can read one can read both. The `chmod 600` on the key file is best-effort and
283
+ a no-op on Windows.
284
+
285
+ If you want the key off-disk, set the `DACLI_ENCRYPTION_KEY` environment variable (e.g. from a secret
286
+ manager); it takes priority over `.dacli/.key` and accepts either a raw Fernet key or a password (derived
287
+ into one via PBKDF2). This is appropriate for a local single-user tool; it is not a substitute for an
288
+ OS keychain or a vault.
289
+
290
+ ---
291
+
292
+ ## Quick start
293
+
294
+ ```bash
295
+ dacli # first run launches the setup wizard, then drops into chat
296
+ dacli setup # (re)configure which connectors/operations are enabled
297
+ dacli validate # live-test every enabled connector's credentials
298
+ dacli eval --quick # run the offline reliability suite (pass^k) against simulated platforms
299
+
300
+ # …or without installing the command:
301
+ python run.py
302
+ ```
303
+
304
+ On first run the **setup wizard** walks you through provider, model, and API key, then asks which
305
+ connectors to enable — validating each with a live health check. Then just describe what you want:
306
+
307
+ > *"Stand up a Bronze→Silver pipeline for the CRM source in Snowflake, then run the dbt models and confirm
308
+ > every test passes."*
309
+
310
+ dacli decomposes the goal into an inspectable plan, asks for approval where the blast radius warrants it,
311
+ executes step by step, and verifies each step against the platform before moving on.
312
+
313
+ ---
314
+
315
+ ## Command reference
316
+
317
+ ### CLI subcommands
318
+
319
+ | Command | Description |
320
+ |---|---|
321
+ | `dacli` · `dacli chat` | Start the interactive chat (default). |
322
+ | `dacli plan "<goal>"` | Preview the decomposed plan + per-step blast radius, policy decision and rollback primitive — **without executing** (no LLM, no network). |
323
+ | `dacli diff <connector> <a> <b> [--sample N]` | Read-only data diff: row-count delta, per-column null rates over a bounded sample, sampled value comparison. The agent-side `data_diff` skill adds an approval-gated `mode=promote`. |
324
+ | `dacli setup [--profile <name>]` | Connector setup wizard. Profiles: `full`, `none`, `<connector>_only`. |
325
+ | `dacli validate` | Live-test every enabled connector's credentials. |
326
+ | `dacli eval [--quick] [--regression] [--calibrate] [--json] [--report <path>.md\|.html]` | Run the pass^k reliability suite + dashboard; `--report` writes a shareable Markdown/HTML scorecard. |
327
+ | `dacli audit [--session <id>] [--full]` | Reconstruct governance decisions ("why did it act?"). |
328
+ | `dacli context [--task <t>] [--explain]` | Inspect the assembled context (sources, tokens, budget). |
329
+ | `dacli catalog [--connector <id>]` | List known data objects from the catalog cache. |
330
+ | `dacli schema <object>` | Show cached columns / row count for one object. |
331
+ | `dacli run "<message>" [--json] [--approve approve\|deny] [--llm-script <file>]` | One headless agent turn with a machine-readable JSON result and a stable exit-code contract. |
332
+ | `dacli replay <scenario.json> [--json]` | Replay a scenario file (ordered user turns + optional scripted LLM) headlessly — what the [CI gate](#extending-dacli) runs. |
333
+ | `dacli connector install <name> --index <path\|url> [--force]` | Fetch a shared connector from an index, validate it in a sandboxed subprocess, register it **disabled**. |
334
+ | `dacli export-run [--session <id>] [--out <zip>]` | Export a session as a compliance bundle: transcript + audit slice + usage, secrets redacted. |
335
+ | `dacli sessions` · `dacli load <id>` | List / resume previous sessions. |
336
+ | `dacli init` | Write a fresh default `config.yaml`. |
337
+ | `dacli prompt` | View the active system prompt. |
338
+ | `dacli chat` | Start the interactive chat explicitly (same as bare `dacli`). |
339
+ | `dacli --version` | Show the version. |
340
+
341
+ ### In-chat slash commands
342
+
343
+ `/help` · `/keys` · `/init` · `/status` · `/usage` · `/context` · `/audit` · `/tools` · `/connect [tool]` ·
344
+ `/new-connector` · `/testmode [tool]` · `/import-connector` · `/push-connector` · `/debug-connector <name>` ·
345
+ `/setup` · `/history` · `/sessions` · `/catalog [connector]` · `/schema <object>` · `/load <id>` · `/export` ·
346
+ `/config` · `/theme <name>` · `/prompt` · `/clear` · `/cls` · `/reset` · `/exit`
347
+
348
+ ---
349
+
350
+ ## Reliability: the environment is the oracle
351
+
352
+ dacli refuses to ask the model *"did that work?"* — it asks the platform. This shows up everywhere:
353
+
354
+ - **Pre-conditions** — `EXPLAIN`, BigQuery `dry_run`, `dbt compile` validate before anything runs.
355
+ - **Post-conditions** — a `CREATE` is confirmed by `bq show`; a put is confirmed by `head-object`; a `dbt run`
356
+ is confirmed by `run_results.json`. Fluent success is never accepted as proof.
357
+ - **Rollback** — irreversible actions are **blocked unless a native undo path is *verified to exist***
358
+ (versioning enabled, retention window open, snapshot taken) — not merely assumed.
359
+ - **Cost as blast radius** — set `governance.cost_confirm_usd` and any action whose connector-estimated
360
+ cost (e.g. BigQuery `dry_run` bytes) exceeds it requires a human confirm, with the estimate shown in
361
+ the approval panel.
362
+ - **pass^k** — reliability is measured as success across *k repeated* rollouts, not a single lucky run.
363
+ The destructive-action gate is held to the highest bar.
364
+
365
+ ```text
366
+ $ dacli eval --quick
367
+ Reliability dashboard — suite: sim
368
+ ----------------------------------------------------------------------------------------------
369
+ connector tasks pass@1 pass^k succ esc corr gov unguard tok ms
370
+ ----------------------------------------------------------------------------------------------
371
+ bigquery 3 1.00 1.00 1.00 0.00 0.00 0.00 0 0 0.1
372
+ s3 3 1.00 1.00 1.00 0.00 0.00 0.00 0 0 0.1
373
+ shell 7 1.00 1.00 1.00 0.00 0.00 0.29 0 0 19.5
374
+ spine 5 1.00 1.00 1.00 0.00 0.20 0.20 0 0 1.0
375
+ ...
376
+ OVERALL 34 1.00 1.00 1.00 0.00 0.03 0.09 0 0 11.0
377
+ ----------------------------------------------------------------------------------------------
378
+ ✓ zero unguarded destructive executions.
379
+ ```
380
+
381
+ Details: **[docs/GOVERNANCE.md](docs/GOVERNANCE.md)** and **[docs/EVALUATION.md](docs/EVALUATION.md)**.
382
+
383
+ ---
384
+
385
+ ## Project layout
386
+
387
+ ```text
388
+ dacli/
389
+ ├── scripts/cli.py # CLI entry point (the `dacli` command)
390
+ ├── core/ # 𝒪 orchestration: kernel, planner (DAG), plan-act-observe-verify loop,
391
+ │ # blackboard, sub-agents, memory facade, pricing/usage, store
392
+ ├── reasoning/ # ℛ multi-provider LLM client + cheap/strong model router
393
+ ├── context/ # 𝒞 context constructor: assembler, budget, compaction, disclosure, spill
394
+ ├── memory/ # ℳ trust-aware store, retrieval (staleness), catalog cache, episodic/procedural
395
+ ├── connectors/ # 𝒮 microkernel plugin layer
396
+ │ ├── base.py # Connector ABC · OperationSpec · ToolResult · Risk
397
+ │ ├── registry.py # manifest discovery + tool definitions + resolver
398
+ │ ├── dispatcher.py # one governed dispatch path (verify + audit)
399
+ │ ├── dod.py # Definition-of-Done gate (CI-enforced)
400
+ │ └── <platform>/ # connector.py + manifest.yaml + SKILL.md (×14)
401
+ ├── governance/ # 𝒢 classifier, policy engine, permissions, rollback, shadow, audit ledger
402
+ ├── sandbox/ # governed code-execution runtime (results stay on disk)
403
+ ├── skills/ # contracted skills (e.g. diagram_mermaid) with mandatory post-conditions
404
+ ├── eval/ # pass^k harness, simulated platforms, golden suites, regression, dashboard
405
+ ├── prompts/ # system message + guidelines + loaders
406
+ ├── config/ # typed pydantic settings + env-var substitution
407
+ └── tui/ # themed terminal UI
408
+ ```
409
+
410
+ ---
411
+
412
+ ## Extending dacli
413
+
414
+ Adding a platform never touches `core/`, `reasoning/`, or `governance/`. Drop a folder:
415
+
416
+ ```text
417
+ connectors/myplatform/
418
+ ├── connector.py # subclass Connector: operations(), invoke(), health() (+ verify_rollback for irreversible ops)
419
+ ├── manifest.yaml # id, class, required_config, default_scope, golden_task
420
+ └── SKILL.md # progressive-disclosure doc
421
+ ```
422
+
423
+ A connector only ships when it passes the **Definition of Done** (enforced by CI): operations with JSON
424
+ schemas, ≥1 **environment-anchored** post-condition per mutating op, a registered rollback strategy,
425
+ an introspection op, a least-privilege scope, and a verifiable golden task. Full guide:
426
+ **[docs/CONNECTORS.md](docs/CONNECTORS.md)**.
427
+
428
+ ### Ecosystem surfaces
429
+
430
+ - **Install shared connectors** — `dacli connector install <name> --index <path-or-url>` fetches a
431
+ connector from a community index, validates it in a sandboxed subprocess, and registers it
432
+ **disabled**; enable it with `/connect <name>` and a restart.
433
+ - **Bridge an MCP server** — the opt-in `mcp_bridge` connector (`pip install -e ".[mcp]"` + an `mcp:`
434
+ config section) proxies one external MCP server's tools through the same classify → policy → audit
435
+ path as every native tool; proxied tools default to the conservative `risky` tier.
436
+ - **Gate your own CI** — the `.github/actions/dacli-gate` composite action replays a scenario file
437
+ headlessly (`dacli replay`) and fails the build on a non-zero exit (`2` = governance block). See
438
+ `scenarios/ci_governance_gate.json` for a scripted, secret-free example.
439
+ - **Export a run for compliance** — `dacli export-run` zips a session's transcript, audit-ledger slice
440
+ and usage summary, with secret-keyed values redacted.
441
+
442
+ ---
443
+
444
+ ## Testing
445
+
446
+ ```bash
447
+ # Full suite (pytest — `unittest discover` silently skips the bare-function tests)
448
+ pytest tests -q
449
+
450
+ # Connector Definition-of-Done gate (governance debt guard)
451
+ python -m unittest tests.test_connector_dod
452
+
453
+ # Offline reliability suite (pass^k) against simulated platforms
454
+ python -m dacli.eval --quick
455
+
456
+ # Docs drift gate (test badge / eval sample / command reference vs. reality)
457
+ python tools/check_docs.py
458
+ ```
459
+
460
+ CI runs ruff, the DoD gate, the full suite (Python 3.10–3.12), the pass^k sim suite, a headless
461
+ end-to-end smoke, and the docs drift gate on every pull request.
462
+
463
+ ---
464
+
465
+ ## Documentation
466
+
467
+ | Doc | What's inside |
468
+ |---|---|
469
+ | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | The six-component harness, the microkernel, and the two execution tiers. |
470
+ | [docs/CONNECTORS.md](docs/CONNECTORS.md) | The connector catalog, the Definition of Done, and how to add a platform. |
471
+ | [docs/GOVERNANCE.md](docs/GOVERNANCE.md) | Blast-radius tiers, policy, rollback, the audit ledger, permissions, and the sandbox. |
472
+ | [docs/EVALUATION.md](docs/EVALUATION.md) | pass^k, golden suites, regression detection, the dashboard, and self-improvement. |
473
+ | [docs/CONFIGURATION.md](docs/CONFIGURATION.md) | The full `config.yaml` reference, env vars, and connector enablement. |
474
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | Development setup, the DoD checklist, and contribution workflow. |
475
+ | [RELEASING.md](RELEASING.md) | The tag-driven release process: version bump, GitHub Release, and PyPI trusted publishing. |
476
+
477
+ ---
478
+
479
+ ## Status
480
+
481
+ dacli is actively developed, with all six harness components implemented and exercised by the test suite:
482
+
483
+ | Capability area | Component | Status |
484
+ |---|---|---|
485
+ | Microkernel + connector plugin registry | 𝒮 | ✅ |
486
+ | Trust-aware memory (confidence · staleness · provenance) + catalog cache | ℳ | ✅ |
487
+ | Context constructor (budget · provenance · compaction · progressive disclosure) | 𝒞 | ✅ |
488
+ | Skill routing with mandatory environment-anchored post-conditions | 𝒮 | ✅ |
489
+ | Tiered governance + code-execution sandbox | 𝒢 | ✅ |
490
+ | Plan-act-observe-verify orchestration + multi-agent | 𝒪 / ℛ | ✅ |
491
+ | 14 platform connectors | 𝒮 / 𝒢 | ✅ |
492
+ | pass^k evaluation, regression detection & gated self-improvement | all | ✅ |
493
+ | Accessible Rich/prompt-toolkit TUI (streaming Markdown, gauges, themes, NO_COLOR/ASCII/reduced-motion) | — | ✅ |
494
+
495
+ ---
496
+
497
+ ## Contributing
498
+
499
+ Contributions are welcome — see **[CONTRIBUTING.md](CONTRIBUTING.md)**. The one rule that is non-negotiable:
500
+ **scale skills and governance together.** Every new capability ships with its post-conditions, rollback
501
+ strategy, permission scope, and golden task, or it does not ship — and CI enforces it.
502
+
503
+ ---
504
+
505
+ ## License
506
+
507
+ This project was created by **Mouad Jaouhari**. If a `LICENSE` file is not yet present in the repository,
508
+ please contact the author before reuse or redistribution.
509
+
510
+ ---
511
+
512
+ <div align="center">
513
+ <sub>Grounded in the six-component harness framework — <a href="https://arxiv.org/abs/2605.26112">arXiv:2605.26112</a>.
514
+ Built from scratch: no agent frameworks, an MCP-free core, reliability first.</sub>
515
+ </div>