datacharter 0.2.0__tar.gz → 0.3.1__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.
- {datacharter-0.2.0 → datacharter-0.3.1}/.github/workflows/banned-terms.yml +1 -1
- {datacharter-0.2.0 → datacharter-0.3.1}/.github/workflows/release.yml +5 -5
- {datacharter-0.2.0 → datacharter-0.3.1}/.github/workflows/test.yml +22 -9
- {datacharter-0.2.0 → datacharter-0.3.1}/CHANGELOG.md +77 -0
- datacharter-0.3.1/CODE_OF_CONDUCT.md +72 -0
- datacharter-0.3.1/CONTRIBUTING.md +124 -0
- datacharter-0.3.1/PKG-INFO +159 -0
- datacharter-0.3.1/README.md +115 -0
- datacharter-0.3.1/SECURITY.md +38 -0
- datacharter-0.3.1/THIRD-PARTY-NOTICES.md +56 -0
- datacharter-0.3.1/brand/demo.gif +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/_config.yml +2 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/about.md +1 -1
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/agent.md +1 -1
- datacharter-0.3.1/docs/assets/add-source.gif +0 -0
- datacharter-0.3.1/docs/assets/drag-drop.gif +0 -0
- datacharter-0.3.1/docs/assets/snapshot.gif +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/charter-yaml.md +19 -1
- datacharter-0.3.1/docs/cli.md +75 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/faq.md +1 -1
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/index.html +2 -0
- datacharter-0.3.1/docs/mcp.md +68 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/quickstart.md +37 -1
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/sources.md +9 -1
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/workspace.md +9 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/__init__.py +1 -1
- datacharter-0.3.1/src/datacharter/agent/cache.py +56 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/agent/loop.py +36 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/agent/tools.py +2 -0
- datacharter-0.3.1/src/datacharter/cli.py +701 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/contracts/loader.py +26 -2
- datacharter-0.3.1/src/datacharter/contracts/metrics.py +51 -0
- datacharter-0.3.1/src/datacharter/contracts/pii.py +81 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/contracts/writer.py +22 -1
- datacharter-0.3.1/src/datacharter/engine/provenance.py +132 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/engine/session.py +93 -1
- datacharter-0.3.1/src/datacharter/engine/statekey.py +31 -0
- datacharter-0.3.1/src/datacharter/mcp/__init__.py +5 -0
- datacharter-0.3.1/src/datacharter/mcp/server.py +119 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/models.py +20 -1
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/app.py +25 -49
- datacharter-0.3.1/src/datacharter/server/security.py +56 -0
- datacharter-0.3.1/src/datacharter/server/static/assets/index-CX4OWOHb.css +1 -0
- datacharter-0.3.1/src/datacharter/server/static/assets/index-CuaSFI7T.js +295 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/index.html +2 -2
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/agent/test_agent.py +6 -4
- datacharter-0.3.1/tests/agent/test_cache.py +73 -0
- datacharter-0.3.1/tests/contracts/test_metrics.py +60 -0
- datacharter-0.3.1/tests/contracts/test_pii.py +83 -0
- datacharter-0.3.1/tests/engine/test_diff.py +74 -0
- datacharter-0.3.1/tests/engine/test_provenance.py +101 -0
- datacharter-0.3.1/tests/mcp/test_mcp_server.py +127 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/server/test_api.py +3 -3
- datacharter-0.3.1/tests/server/test_offline.py +40 -0
- datacharter-0.3.1/tests/server/test_security.py +52 -0
- datacharter-0.3.1/tests/test_agent_vidaimock_e2e.py +142 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/test_cli_init.py +3 -3
- datacharter-0.3.1/tests/test_drift.py +31 -0
- datacharter-0.3.1/tests/test_explain.py +14 -0
- datacharter-0.3.1/tests/test_sample.py +23 -0
- datacharter-0.3.1/tests/test_snapshot_recheck.py +30 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/App.tsx +55 -9
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/api.ts +6 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/components/ChartPanel.tsx +4 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/components/ChatPanel.tsx +8 -1
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/components/ResultsGrid.tsx +35 -7
- datacharter-0.3.1/ui/src/components/SourceTree.tsx +143 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/components/Tutorial.tsx +16 -12
- datacharter-0.3.1/ui/src/lib/caption.ts +20 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/styles.css +97 -4
- datacharter-0.2.0/.impeccable/hook.cache.json +0 -1
- datacharter-0.2.0/CLAUDE.md +0 -103
- datacharter-0.2.0/PKG-INFO +0 -116
- datacharter-0.2.0/README.md +0 -72
- datacharter-0.2.0/docs/DESIGN.md +0 -259
- datacharter-0.2.0/docs/PLAN.md +0 -126
- datacharter-0.2.0/docs/PROGRESS.md +0 -283
- datacharter-0.2.0/docs/SECURITY_AUDIT.md +0 -526
- datacharter-0.2.0/docs/TUTORIAL_MODE.md +0 -104
- datacharter-0.2.0/docs/superpowers/plans/2026-07-24-source-management-ui.md +0 -1232
- datacharter-0.2.0/docs/superpowers/specs/2026-07-24-source-management-ui-design.md +0 -193
- datacharter-0.2.0/src/datacharter/cli.py +0 -226
- datacharter-0.2.0/src/datacharter/server/static/assets/index-BT6qaEDg.css +0 -1
- datacharter-0.2.0/src/datacharter/server/static/assets/index-VhjZo8cS.js +0 -295
- datacharter-0.2.0/ui/.impeccable/hook.cache.json +0 -1
- datacharter-0.2.0/ui/src/components/SourceTree.tsx +0 -108
- {datacharter-0.2.0 → datacharter-0.3.1}/.gitignore +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/LICENSE +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/TRADEMARKS.md +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/brand/README.md +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/brand/hero.png +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/brand/mark.svg +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/brand/screenshot-m4-agent.png +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/brand/screenshot-m5-complete.png +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/brand/screenshot-m5-core.png +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/brand/screenshot-m5-features.png +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/compose.yaml +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/assets/hero.png +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/assets/screenshot.png +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/docs/security.md +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/pyproject.toml +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/scripts/build_ui.sh +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/agent/__init__.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/agent/llm.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/contracts/__init__.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/contracts/resolve.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/contracts/secrets.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/engine/__init__.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/engine/aggregate.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/engine/guard.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/engine/pushdown.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/engine/scrub.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/engine/snowflake.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/engine/sources.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/__init__.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/llm_admin.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/source_admin.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/abap-DLDM7-KI.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/apex-DNDY2TF8.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/azcli-Y6nb8tq_.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/bat-BwHxbl9M.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/bicep-CFznDFnq.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/cameligo-Bf6VGUru.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/clojure-Dnu-v4kV.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/codicon-Brq4_Ui5.ttf +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/coffee-Bd8akH9Z.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/cpp-BbWJElDN.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/csharp-Co3qMtFm.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/csp-D-4FJmMZ.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/css-DdJfP1eB.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/css.worker-CqwWTjeG.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/cssMode-BuAVOLr4.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/cypher-cTPe9QuQ.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/dart-BOtBlQCF.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/dockerfile-BG73LgW2.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/ecl-BEgZUVRK.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/editor.worker-DCKwvLbM.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/elixir-BkW5O-1t.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/flow9-BeJ5waoc.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/freemarker2-DM0thzwF.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/fsharp-PahG7c26.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/go-acbASCJo.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/graphql-BxJiqAUM.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/handlebars-BkMf3Qj4.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/hcl-DtV1sZF8.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/html-KeNy2AFd.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/html.worker-DhJ4VZMp.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/htmlMode-CN5rSB9p.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/ini-Kd9XrMLS.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/java-CXBNlu9o.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/javascript-CZu1iw4q.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/json.worker-BF9eV5mS.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/jsonMode-BtMXpE2Q.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/julia-cl7-CwDS.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/kotlin-s7OhZKlX.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/less-9HpZscsL.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/lexon-OrD6JF1K.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/liquid-mhqehfbE.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/lspLanguageFeatures-D1NXFkgg.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/lua-Cyyb5UIc.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/m3-B8OfTtLu.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/markdown-BFxVWTOG.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/mdx-69yOd9f1.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/mips-CiqrrVzr.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/monaco-CB2SckMT.css +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/monaco-DNze5gXB.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/msdax-DmeGPVcC.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/mysql-C_tMU-Nz.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/objective-c-BDtDVThU.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/pascal-vHIfCaH5.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/pascaligo-DtZ0uQbO.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/perl-Ub6l9XKa.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/pgsql-BlNEE0v7.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/php-BBUBE1dy.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/pla-DSh2-awV.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/postiats-CocnycG-.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/powerquery-tScXyioY.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/powershell-COWaemsV.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/protobuf-Brw8urJB.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/pug-8SOpv6rk.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/python-C5qpjWC4.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/qsharp-Bw9ernYp.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/r-j7ic8hl3.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/razor-fg0l3XC9.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/redis-Bu5POkcn.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/redshift-Bs9aos_-.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/restructuredtext-CqXO7rUv.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/ruby-zBfavPgS.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/rust-BzKRNQWT.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/sb-BBc9UKZt.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/scala-D9hQfWCl.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/scheme-BPhDTwHR.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/scss-CBJaRo0y.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/shell-DiJ1NA_G.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/solidity-Db0IVjzk.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/sophia-CnS9iZB_.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/sparql-CJmd_6j2.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/sql-ClhHkBeG.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/st-CHwy0fLd.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/swift-Bqt4WxQ4.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/systemverilog-Bs9z6M-B.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/tcl-Dm6ycUr_.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/ts.worker-DTZAwq0V.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/tsMode-CaXNdXrQ.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/twig-Csy3S7wG.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/typescript-CCbVPqil.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/typespec-Btyra-wh.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/vb-Db0cS2oM.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/wgsl-BTesnYfV.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/workers-CwEVRSMl.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/xml-CIpcyvha.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/src/datacharter/server/static/assets/yaml-CiikAWeE.js +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/agent/test_llm_wire.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/contracts/test_loader.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/contracts/test_secrets_store.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/contracts/test_writer.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/engine/test_aggregate.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/engine/test_federation.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/engine/test_guard.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/engine/test_pushdown.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/engine/test_scrub.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/engine/test_session.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/engine/test_source_lifecycle.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/engine/test_sources.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/integration/seed/mysql.sql +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/integration/seed/postgres.sql +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/integration/test_live_sources.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/server/test_llm_admin.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/server/test_source_admin.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/server/test_sources_api.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/test_packaging_e2e.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/test_scaffold.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/tests/test_secrets_cli.py +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/index.html +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/package-lock.json +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/package.json +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/components/HelpModal.tsx +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/components/LLMConfig.tsx +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/components/QueryFiles.tsx +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/components/SourceForm.tsx +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/components/SourcesView.tsx +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/lib/chartSpec.ts +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/lib/columns.ts +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/lib/useResize.ts +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/main.tsx +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/monaco.ts +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/src/vite-env.d.ts +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/tsconfig.json +0 -0
- {datacharter-0.2.0 → datacharter-0.3.1}/ui/vite.config.ts +0 -0
|
@@ -17,20 +17,20 @@ jobs:
|
|
|
17
17
|
build:
|
|
18
18
|
runs-on: ubuntu-latest
|
|
19
19
|
steps:
|
|
20
|
-
- uses: actions/checkout@
|
|
21
|
-
- uses: actions/setup-node@
|
|
20
|
+
- uses: actions/checkout@v5
|
|
21
|
+
- uses: actions/setup-node@v5
|
|
22
22
|
with:
|
|
23
23
|
node-version: 22
|
|
24
24
|
cache: npm
|
|
25
25
|
cache-dependency-path: ui/package-lock.json
|
|
26
|
-
- uses: astral-sh/setup-uv@
|
|
26
|
+
- uses: astral-sh/setup-uv@v7
|
|
27
27
|
- name: Build UI into the package
|
|
28
28
|
run: ./scripts/build_ui.sh
|
|
29
29
|
- name: Build sdist + wheel
|
|
30
30
|
run: uv build
|
|
31
31
|
- name: Validate metadata and README rendering
|
|
32
32
|
run: uvx twine check dist/*
|
|
33
|
-
- uses: actions/upload-artifact@
|
|
33
|
+
- uses: actions/upload-artifact@v7
|
|
34
34
|
with:
|
|
35
35
|
name: dist
|
|
36
36
|
path: dist/
|
|
@@ -44,7 +44,7 @@ jobs:
|
|
|
44
44
|
permissions:
|
|
45
45
|
id-token: write # OIDC token for PyPI Trusted Publishing
|
|
46
46
|
steps:
|
|
47
|
-
- uses: actions/download-artifact@
|
|
47
|
+
- uses: actions/download-artifact@v8
|
|
48
48
|
with:
|
|
49
49
|
name: dist
|
|
50
50
|
path: dist/
|
|
@@ -8,8 +8,8 @@ jobs:
|
|
|
8
8
|
test:
|
|
9
9
|
runs-on: ubuntu-latest
|
|
10
10
|
steps:
|
|
11
|
-
- uses: actions/checkout@
|
|
12
|
-
- uses: astral-sh/setup-uv@
|
|
11
|
+
- uses: actions/checkout@v5
|
|
12
|
+
- uses: astral-sh/setup-uv@v7
|
|
13
13
|
- name: Install
|
|
14
14
|
run: uv venv && uv pip install -e ".[dev]"
|
|
15
15
|
- name: Lint
|
|
@@ -44,8 +44,8 @@ jobs:
|
|
|
44
44
|
--health-cmd "mysqladmin ping -h 127.0.0.1 -pcharter_test_pw -ucharter"
|
|
45
45
|
--health-interval 2s --health-timeout 2s --health-retries 60
|
|
46
46
|
steps:
|
|
47
|
-
- uses: actions/checkout@
|
|
48
|
-
- uses: astral-sh/setup-uv@
|
|
47
|
+
- uses: actions/checkout@v5
|
|
48
|
+
- uses: astral-sh/setup-uv@v7
|
|
49
49
|
- name: Install
|
|
50
50
|
run: uv venv && uv pip install -e ".[dev]"
|
|
51
51
|
- name: Seed databases
|
|
@@ -61,8 +61,8 @@ jobs:
|
|
|
61
61
|
ui:
|
|
62
62
|
runs-on: ubuntu-latest
|
|
63
63
|
steps:
|
|
64
|
-
- uses: actions/checkout@
|
|
65
|
-
- uses: actions/setup-node@
|
|
64
|
+
- uses: actions/checkout@v5
|
|
65
|
+
- uses: actions/setup-node@v5
|
|
66
66
|
with:
|
|
67
67
|
node-version: 22
|
|
68
68
|
cache: npm
|
|
@@ -75,15 +75,28 @@ jobs:
|
|
|
75
75
|
package:
|
|
76
76
|
runs-on: ubuntu-latest
|
|
77
77
|
steps:
|
|
78
|
-
- uses: actions/checkout@
|
|
79
|
-
- uses: actions/setup-node@
|
|
78
|
+
- uses: actions/checkout@v5
|
|
79
|
+
- uses: actions/setup-node@v5
|
|
80
80
|
with:
|
|
81
81
|
node-version: 22
|
|
82
82
|
cache: npm
|
|
83
83
|
cache-dependency-path: ui/package-lock.json
|
|
84
|
-
- uses: astral-sh/setup-uv@
|
|
84
|
+
- uses: astral-sh/setup-uv@v7
|
|
85
85
|
- name: Build UI into package
|
|
86
86
|
run: ./scripts/build_ui.sh
|
|
87
|
+
- name: Fetch VidaiMock (e2e mock LLM; Apache-2.0, checksum-pinned)
|
|
88
|
+
run: |
|
|
89
|
+
ver=v0.2.9
|
|
90
|
+
base="https://github.com/vidaiUK/VidaiMock/releases/download/$ver"
|
|
91
|
+
curl -fsSL -o vm.tar.gz "$base/vidaimock-linux-x64.tar.gz"
|
|
92
|
+
curl -fsSL -o vm.sha256 "$base/vidaimock-linux-x64.sha256"
|
|
93
|
+
got=$(sha256sum vm.tar.gz | awk '{print $1}')
|
|
94
|
+
want=$(awk '{print $1}' vm.sha256)
|
|
95
|
+
test "$got" = "$want" || { echo "VidaiMock checksum mismatch: $got != $want"; exit 1; }
|
|
96
|
+
mkdir -p vidaimock-bin && tar -xzf vm.tar.gz -C vidaimock-bin
|
|
97
|
+
bin=$(find "$PWD/vidaimock-bin" -type f -name vidaimock | head -1)
|
|
98
|
+
chmod +x "$bin"
|
|
99
|
+
echo "VIDAIMOCK_BIN=$bin" >> "$GITHUB_ENV"
|
|
87
100
|
- name: Install + e2e
|
|
88
101
|
run: |
|
|
89
102
|
uv venv
|
|
@@ -5,6 +5,83 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.3.1] - 2026-07-24
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Internal: extracted the origin/host request guard (DC-SEC-006) from the
|
|
13
|
+
server into an importable `datacharter.server.security` module. No behavior
|
|
14
|
+
change; the existing anti-DNS-rebinding / cross-origin protections are intact.
|
|
15
|
+
|
|
16
|
+
## [0.3.0] - 2026-07-24
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Agent view: a toggle on the results grid that masks the contract's PII columns
|
|
21
|
+
in place, showing exactly what the agent and MCP server see (the model never
|
|
22
|
+
sees raw PII) — right in the SQL editor, no LLM required.
|
|
23
|
+
- Source tree: collapsible `+`/`−` disclosure on every source and table, and
|
|
24
|
+
expand a table to see its columns inline.
|
|
25
|
+
- Instant SQL preview: results update live a beat after you stop typing (row-capped,
|
|
26
|
+
and errors stay silent until you press Run) — no Run click needed to see output.
|
|
27
|
+
- Chart captions: auto-detected charts (results) and agent-emitted charts (chat)
|
|
28
|
+
now show a one-line plain-language caption of what they show — e.g. "bar of
|
|
29
|
+
revenue by customer_id".
|
|
30
|
+
- `datacharter explain <sql>` — show a query's plan and row estimates without
|
|
31
|
+
running it: a pre-flight cost check that surfaces per-source scans and what
|
|
32
|
+
would push down.
|
|
33
|
+
- `datacharter sample <relation>` — print a PII-masked CSV sample of a relation
|
|
34
|
+
(columns marked PII in the contract come back as `•••`), safe to paste into a
|
|
35
|
+
bug ticket or share.
|
|
36
|
+
- Contract-scoped metrics: declare named `metrics:` in `charter.yaml` (a base
|
|
37
|
+
relation + an aggregate expression + optional dimensions); `datacharter metric
|
|
38
|
+
<name> [--by cols]` resolves each to one governed SELECT and runs it, so a
|
|
39
|
+
certified `revenue` always means the same thing. Joins across sources and time
|
|
40
|
+
grains are a later refinement.
|
|
41
|
+
- NL→SQL cache: when the agent answers via a query, its SQL is cached against a
|
|
42
|
+
contract fingerprint; a repeat or normalized-reworded question re-runs the
|
|
43
|
+
cached SQL on current data and skips the LLM round-trip (fresh data, no stale
|
|
44
|
+
answers). Embedding-based semantic similarity is a follow-up.
|
|
45
|
+
- `datacharter serve --offline` — no-egress mode: the LLM agent is disabled (no
|
|
46
|
+
data can reach any model endpoint) and connecting one at runtime is refused. It
|
|
47
|
+
prints and writes a no-egress attestation to `.datacharter/attestation.json`.
|
|
48
|
+
- `datacharter snapshot <name> <sql>` and `datacharter recheck <name>` — save a
|
|
49
|
+
query's result as `local.<name>` alongside its SQL, then later re-run it and
|
|
50
|
+
diff against the saved result to answer "did this number change?". `recheck`
|
|
51
|
+
exits non-zero when the result has changed.
|
|
52
|
+
- `datacharter drift` — report schema drift between the charter and the live
|
|
53
|
+
sources: declared tables or PII columns that no longer exist. A missing PII
|
|
54
|
+
column is a silent masking gap, so this is caught explicitly. Exits non-zero
|
|
55
|
+
when drift is found, for use in CI.
|
|
56
|
+
- `datacharter scan` — introspect the configured sources and suggest PII columns
|
|
57
|
+
for `charter.yaml`, both by column name and by sampled values (catches an
|
|
58
|
+
email/SSN/IP column whose name gives nothing away). Turns "author a contract"
|
|
59
|
+
into "review a generated one" for the PII map. Prints suggestions, or `--write`
|
|
60
|
+
merges them into `charter.yaml` (round-trip; credential refs left untouched).
|
|
61
|
+
- `datacharter diff <left> <right>` and `Engine.diff` — a full-row set difference
|
|
62
|
+
between two relations, across sources (postgres vs a file, prod vs staging, …)
|
|
63
|
+
via the federation engine. Reports rows only in each side plus the common count,
|
|
64
|
+
through the read-only guard. With `--key`, rows are matched by key and changed
|
|
65
|
+
rows (same key, differing values) are counted separately.
|
|
66
|
+
- Per-query provenance: query results (API, agent tool results) now report the
|
|
67
|
+
source relations and columns the query read — plus column lineage, mapping each
|
|
68
|
+
output column to the input columns that feed it — parsed from the same AST the
|
|
69
|
+
read-only guard uses. This is the trust signal for an agent answer: it shows
|
|
70
|
+
which real columns an answer came from.
|
|
71
|
+
- `datacharter mcp` — an MCP (Model Context Protocol) server over stdio that
|
|
72
|
+
exposes the four governed query tools (`list_sources`, `list_tables`,
|
|
73
|
+
`describe_table`, `query`) to any MCP client. The read-only guard, PII masking,
|
|
74
|
+
and credential scrubbing are inherited from the same toolbox the agent uses, so
|
|
75
|
+
an external agent can explore your data without seeing raw PII or being able to
|
|
76
|
+
write. Hand-rolled JSON-RPC 2.0, no new dependency.
|
|
77
|
+
|
|
78
|
+
### Changed
|
|
79
|
+
|
|
80
|
+
- Toolbar: **Snapshot** moved next to the query actions (away from the export
|
|
81
|
+
format menu); hover tooltips on Run/Snapshot/Export/Explain.
|
|
82
|
+
- Demo workspace: bundled as one sqlite `store` contract holding `customers`
|
|
83
|
+
and `orders`, so the sidebar reads contract → table → columns.
|
|
84
|
+
|
|
8
85
|
## [0.2.0] - 2026-07-24
|
|
9
86
|
|
|
10
87
|
### Added
|
|
@@ -0,0 +1,72 @@
|
|
|
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, religion, or sexual identity and
|
|
10
|
+
orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment for our
|
|
18
|
+
community include:
|
|
19
|
+
|
|
20
|
+
- Demonstrating empathy and kindness toward other people
|
|
21
|
+
- Being respectful of differing opinions, viewpoints, and experiences
|
|
22
|
+
- Giving and gracefully accepting constructive feedback
|
|
23
|
+
- Accepting responsibility and apologizing to those affected by our mistakes,
|
|
24
|
+
and learning from the experience
|
|
25
|
+
- Focusing on what is best not just for us as individuals, but for the overall
|
|
26
|
+
community
|
|
27
|
+
|
|
28
|
+
Examples of unacceptable behavior include:
|
|
29
|
+
|
|
30
|
+
- The use of sexualized language or imagery, and sexual attention or advances of
|
|
31
|
+
any kind
|
|
32
|
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
|
33
|
+
- Public or private harassment
|
|
34
|
+
- Publishing others' private information, such as a physical or email address,
|
|
35
|
+
without their explicit permission
|
|
36
|
+
- Other conduct which could reasonably be considered inappropriate in a
|
|
37
|
+
professional setting
|
|
38
|
+
|
|
39
|
+
## Enforcement Responsibilities
|
|
40
|
+
|
|
41
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
42
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
43
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
44
|
+
or harmful.
|
|
45
|
+
|
|
46
|
+
Community leaders have the right and responsibility to remove, edit, or reject
|
|
47
|
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
48
|
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
49
|
+
decisions when appropriate.
|
|
50
|
+
|
|
51
|
+
## Scope
|
|
52
|
+
|
|
53
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
54
|
+
an individual is officially representing the community in public spaces.
|
|
55
|
+
|
|
56
|
+
## Enforcement
|
|
57
|
+
|
|
58
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
59
|
+
reported to the maintainers privately through GitHub's private reporting on the
|
|
60
|
+
repository (Security → Advisories, or a direct message to a maintainer). All
|
|
61
|
+
complaints will be reviewed and investigated promptly and fairly.
|
|
62
|
+
|
|
63
|
+
All community leaders are obligated to respect the privacy and security of the
|
|
64
|
+
reporter of any incident.
|
|
65
|
+
|
|
66
|
+
## Attribution
|
|
67
|
+
|
|
68
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
69
|
+
version 2.1, available at
|
|
70
|
+
https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
|
71
|
+
|
|
72
|
+
[homepage]: https://www.contributor-covenant.org
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Contributing to DataCharter
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in DataCharter. Contributions of all kinds — bug
|
|
4
|
+
reports, docs, tests, and code — are welcome. The project is licensed under
|
|
5
|
+
[Apache-2.0](LICENSE); contributions are accepted under the same license.
|
|
6
|
+
|
|
7
|
+
## Ways to contribute
|
|
8
|
+
|
|
9
|
+
- **Report a bug or request a feature** — open an issue with steps to reproduce
|
|
10
|
+
or a clear description of the use case.
|
|
11
|
+
- **Improve docs** — fixes to the guides under `docs/` and the README are always
|
|
12
|
+
welcome.
|
|
13
|
+
- **Send a pull request** — for anything beyond a trivial fix, open (or comment
|
|
14
|
+
on) an issue first so we can agree on the approach before you invest the work.
|
|
15
|
+
|
|
16
|
+
## Development setup
|
|
17
|
+
|
|
18
|
+
DataCharter is one Python package with a bundled web UI. You need Python 3.11+
|
|
19
|
+
and [uv](https://docs.astral.sh/uv/); UI work additionally needs Node.
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
# Python environment (creates .venv)
|
|
23
|
+
uv sync
|
|
24
|
+
|
|
25
|
+
# Run the app from source
|
|
26
|
+
uv run datacharter serve
|
|
27
|
+
|
|
28
|
+
# Web UI (only if you're changing the frontend)
|
|
29
|
+
cd ui && npm ci && npm run build
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Tests and linting
|
|
33
|
+
|
|
34
|
+
Every change lands with tests, and the working tree must be lint-clean. These
|
|
35
|
+
are the same commands CI runs:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
uv run pytest -q # unit tests (fast; the default set)
|
|
39
|
+
uv run pytest -m integration -q # integration tests (require Docker)
|
|
40
|
+
uv run pytest -m e2e -q # end-to-end (see below)
|
|
41
|
+
uv run ruff check . # lint
|
|
42
|
+
cd ui && npm run build # type-check + build the UI
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The end-to-end agent test drives a real
|
|
46
|
+
[VidaiMock](https://github.com/vidaiUK/VidaiMock) server (an Apache-2.0 mock LLM);
|
|
47
|
+
it skips unless `VIDAIMOCK_BIN` points at the binary or `vidaimock` is on `PATH`.
|
|
48
|
+
|
|
49
|
+
Write tests that describe behavior, keep unit tests fast, and put anything that
|
|
50
|
+
needs Docker or a live server behind the `integration` / `e2e` markers so the
|
|
51
|
+
default run stays quick.
|
|
52
|
+
|
|
53
|
+
## Commit and pull-request conventions
|
|
54
|
+
|
|
55
|
+
- **[Conventional Commits](https://www.conventionalcommits.org/)**:
|
|
56
|
+
`feat:`, `fix:`, `docs:`, `chore:`, `test:`, `refactor:`. Keep the subject
|
|
57
|
+
under ~72 characters, imperative mood.
|
|
58
|
+
- Small, focused commits over large omnibus ones. Every commit should build and
|
|
59
|
+
pass tests so history stays bisectable.
|
|
60
|
+
- Never commit secrets, tokens, or real hostnames — in code, tests, or fixtures.
|
|
61
|
+
- Keep the PR scoped to one change; describe the "why," not just the "what."
|
|
62
|
+
|
|
63
|
+
## Developer Certificate of Origin (sign-off required)
|
|
64
|
+
|
|
65
|
+
DataCharter uses the **Developer Certificate of Origin (DCO)** instead of a CLA.
|
|
66
|
+
Every commit must be signed off, certifying that you wrote the change (or
|
|
67
|
+
otherwise have the right to submit it under Apache-2.0). This is a lightweight,
|
|
68
|
+
one-time habit — no separate agreement to sign.
|
|
69
|
+
|
|
70
|
+
Add the sign-off automatically with the `-s` flag:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
git commit -s -m "fix: correct off-by-one in row cap"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
That appends a line matching your configured `git` name and email:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Signed-off-by: Jane Developer <jane@example.com>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Use your real name and a valid email. If you forget the sign-off on your last
|
|
83
|
+
commit, amend it with `git commit --amend -s`; for a whole branch, use
|
|
84
|
+
`git rebase --signoff <base>`. PRs whose commits are not signed off cannot be
|
|
85
|
+
merged.
|
|
86
|
+
|
|
87
|
+
By signing off, you agree to the DCO, version 1.1:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
Developer Certificate of Origin
|
|
91
|
+
Version 1.1
|
|
92
|
+
|
|
93
|
+
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
|
94
|
+
|
|
95
|
+
Everyone is permitted to copy and distribute verbatim copies of this
|
|
96
|
+
license document, but changing it is not allowed.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
Developer's Certificate of Origin 1.1
|
|
100
|
+
|
|
101
|
+
By making a contribution to this project, I certify that:
|
|
102
|
+
|
|
103
|
+
(a) The contribution was created in whole or in part by me and I
|
|
104
|
+
have the right to submit it under the open source license
|
|
105
|
+
indicated in the file; or
|
|
106
|
+
|
|
107
|
+
(b) The contribution is based upon previous work that, to the best
|
|
108
|
+
of my knowledge, is covered under an appropriate open source
|
|
109
|
+
license and I have the right under that license to submit that
|
|
110
|
+
work with modifications, whether created in whole or in part
|
|
111
|
+
by me, under the same open source license (unless I am
|
|
112
|
+
permitted to submit under a different license), as indicated
|
|
113
|
+
in the file; or
|
|
114
|
+
|
|
115
|
+
(c) The contribution was provided directly to me by some other
|
|
116
|
+
person who certified (a), (b) or (c) and I have not modified
|
|
117
|
+
it.
|
|
118
|
+
|
|
119
|
+
(d) I understand and agree that this project and the contribution
|
|
120
|
+
are public and that a record of the contribution (including all
|
|
121
|
+
personal information I submit with it, including my sign-off) is
|
|
122
|
+
maintained indefinitely and may be redistributed consistent with
|
|
123
|
+
this project or the open source license(s) involved.
|
|
124
|
+
```
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: datacharter
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Charter your data — contract-governed local data exploration, powered by DuckDB
|
|
5
|
+
Project-URL: Homepage, https://github.com/datacharter/datacharter
|
|
6
|
+
Project-URL: Repository, https://github.com/datacharter/datacharter
|
|
7
|
+
Project-URL: Documentation, https://datacharter.github.io/datacharter/
|
|
8
|
+
Project-URL: Changelog, https://github.com/datacharter/datacharter/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Issues, https://github.com/datacharter/datacharter/issues
|
|
10
|
+
Author: DataCharter
|
|
11
|
+
License-Expression: Apache-2.0
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: data-contracts,data-exploration,duckdb,federation,local-first,sql
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Environment :: Web Environment
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Intended Audience :: Information Technology
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Database
|
|
24
|
+
Classifier: Topic :: Database :: Front-Ends
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
26
|
+
Requires-Python: >=3.11
|
|
27
|
+
Requires-Dist: duckdb>=1.5
|
|
28
|
+
Requires-Dist: fastapi>=0.115
|
|
29
|
+
Requires-Dist: httpx>=0.27
|
|
30
|
+
Requires-Dist: keyring>=25.0
|
|
31
|
+
Requires-Dist: pydantic>=2.7
|
|
32
|
+
Requires-Dist: python-dotenv>=1.0
|
|
33
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
34
|
+
Requires-Dist: pyyaml>=6.0
|
|
35
|
+
Requires-Dist: ruamel-yaml>=0.18
|
|
36
|
+
Requires-Dist: uvicorn>=0.30
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
41
|
+
Provides-Extra: snowflake
|
|
42
|
+
Requires-Dist: snowflake-connector-python>=3.12; extra == 'snowflake'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# DataCharter
|
|
46
|
+
|
|
47
|
+
> Explore all your data locally, in one place — contract-governed data exploration, powered by DuckDB
|
|
48
|
+
|
|
49
|
+
[](https://pypi.org/project/datacharter/)
|
|
50
|
+
[](https://pypi.org/project/datacharter/)
|
|
51
|
+
[](LICENSE)
|
|
52
|
+
|
|
53
|
+
Contract-governed local data exploration, **powered by [DuckDB](https://duckdb.org)**.
|
|
54
|
+
Define your sources as data contracts
|
|
55
|
+
([ODCS](https://bitol-io.github.io/open-data-contract-standard/)-compatible YAML),
|
|
56
|
+
query them through DuckDB's SQL federation engine with real source pushdowns,
|
|
57
|
+
and explore in a local web UI — SQL editor with live preview, auto-charts,
|
|
58
|
+
profiling. Every answer shows which source columns it read; ask questions in
|
|
59
|
+
plain language or serve the whole thing to an AI agent over [MCP](docs/mcp.md),
|
|
60
|
+
with PII masked from the model — all on your machine.
|
|
61
|
+
|
|
62
|
+
## What you can do
|
|
63
|
+
|
|
64
|
+
- **Drop a file, query it instantly.** Drag a CSV, Parquet, or JSON onto the window and run SQL on it right away — no import, no schema setup.
|
|
65
|
+
- **Join across sources — no pipelines.** Query and JOIN a Postgres table, a Parquet file, and a Snowflake table in a *single* SQL statement. No ETL, no copying everything into a warehouse first.
|
|
66
|
+
- **Connect all your data.** Postgres, MySQL, SQLite, SQL Server, BigQuery, Snowflake, files on S3/GCS/Azure, and Iceberg/Delta tables — all through one engine.
|
|
67
|
+
- **See answers as you type.** Live results preview while you write SQL, one-click auto-charts, and a profiling panel (missing values, distributions, outliers) — no separate BI tool.
|
|
68
|
+
- **Ask in plain English (optional).** Turn a question into SQL and an answer with the built-in agent — bring your own model, or run one fully local with no API key.
|
|
69
|
+
- **Keep sensitive data away from the AI.** Mark PII columns once; the agent and any connected AI see masked values (`•••`) while you still see the real data locally. Flip **Agent view** to see exactly what the model sees.
|
|
70
|
+
- **Safe by design.** The engine is read-only by construction — no query can write, delete, or touch the filesystem — so pointing an AI (or a teammate) at your real databases can't do damage.
|
|
71
|
+
- **Point AI tools at your data, safely.** A governed MCP server exposes read-only, PII-masked query tools to Cursor, Cline, or your own agent.
|
|
72
|
+
- **Trust every answer.** Each result shows exactly which source columns it read — so you always know where a number came from.
|
|
73
|
+
- **Save, reuse, export.** Snapshot a result as a reusable local table; export to CSV, Parquet, JSON, or XLSX.
|
|
74
|
+
- **Governance you can automate.** Catch schema/PII drift in CI, auto-detect PII columns, diff data across sources, and define certified metrics — from the command line.
|
|
75
|
+
|
|
76
|
+

|
|
77
|
+
|
|
78
|
+
**Status: pre-release.** V1 in development.
|
|
79
|
+
|
|
80
|
+
## Quick start
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
# Try it instantly on generated demo data — no install, no config:
|
|
84
|
+
uvx datacharter serve # needs `uv` → https://astral.sh/uv
|
|
85
|
+
# → serves at http://127.0.0.1:8321 (open it in your browser)
|
|
86
|
+
|
|
87
|
+
# Or install it:
|
|
88
|
+
pip install datacharter # Python 3.11+
|
|
89
|
+
|
|
90
|
+
# Start your own workspace:
|
|
91
|
+
datacharter init # scaffolds charter.yaml, queries/, .env.example
|
|
92
|
+
# → add a source: edit charter.yaml, or use the "Sources" panel in the UI
|
|
93
|
+
datacharter serve # → http://127.0.0.1:8321
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Then, once it's running, **drag a CSV, Parquet, or JSON file onto the window** to
|
|
97
|
+
query it instantly — no config needed.
|
|
98
|
+
|
|
99
|
+
**Optional natural-language agent** — point it at any OpenAI-compatible endpoint:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
export OPENAI_BASE_URL=... # any OpenAI-compatible API
|
|
103
|
+
export OPENAI_API_KEY=...
|
|
104
|
+
datacharter serve
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
…or run **fully local** — no API key, no data leaves your machine (requires
|
|
108
|
+
[Ollama](https://ollama.com)):
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
ollama pull qwen3:8b # once
|
|
112
|
+
datacharter serve --local # qwen3:8b by default (--model to change)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Why DataCharter
|
|
116
|
+
|
|
117
|
+
- **Your contracts are the catalog.** `charter.yaml` describes sources, tables,
|
|
118
|
+
and PII fields — the same contract spec your data team already writes, so
|
|
119
|
+
there's no separate metadata store to maintain.
|
|
120
|
+
- **Real federation, not just a shared connection.** Filters and projections are
|
|
121
|
+
pushed down to each source — even across a cross-source join, every leg is
|
|
122
|
+
filtered where its data lives. (Snowflake runs via connector extract,
|
|
123
|
+
`datacharter[snowflake]`, with the same pushdown into the extract.)
|
|
124
|
+
- **Local-first.** One process, your machine, no cloud dependency. The optional
|
|
125
|
+
`--local` agent runs a small open model via Ollama — no API key, no data leaves
|
|
126
|
+
your machine.
|
|
127
|
+
- **The workspace is a directory.** `charter.yaml` + `queries/*.sql` +
|
|
128
|
+
`.env.example` — commit it, clone it, `datacharter serve`. Your team's whole
|
|
129
|
+
exploration environment travels as a repo; secrets and local state never do.
|
|
130
|
+
|
|
131
|
+
DataCharter governs and audits your data, not just displays it. The full command
|
|
132
|
+
set (`drift`, `scan`, `diff`, `metric`, `mcp`, and more) is in the
|
|
133
|
+
[CLI reference](docs/cli.md); the security model is in [security](docs/security.md).
|
|
134
|
+
|
|
135
|
+
## Built on
|
|
136
|
+
|
|
137
|
+
DataCharter stands on excellent open-source foundations:
|
|
138
|
+
|
|
139
|
+
- **[DuckDB](https://duckdb.org)** — the analytical engine at our core:
|
|
140
|
+
federation (`ATTACH`), file formats, Iceberg/Delta, encryption, autocomplete.
|
|
141
|
+
- **[Open Data Contract Standard](https://bitol-io.github.io/open-data-contract-standard/)** /
|
|
142
|
+
[datacontract.com](https://datacontract-specification.com/) — the contract format `charter.yaml` speaks.
|
|
143
|
+
- **[Model Context Protocol](https://modelcontextprotocol.io)** — the open protocol
|
|
144
|
+
the `datacharter mcp` server speaks to agents and MCP clients.
|
|
145
|
+
- **[Vega-Lite](https://vega.github.io/vega-lite/)** — declarative charting.
|
|
146
|
+
- **[Monaco Editor](https://microsoft.github.io/monaco-editor/)** — the SQL editor.
|
|
147
|
+
- **[TanStack Table & Virtual](https://tanstack.com/)** — the virtualized results grid.
|
|
148
|
+
- And the Python & React ecosystems — FastAPI, pydantic, httpx, keyring, and
|
|
149
|
+
ruamel.yaml on the backend; React and Vite on the front.
|
|
150
|
+
|
|
151
|
+
Testing uses **[VidaiMock](https://github.com/vidaiUK/VidaiMock)**, an
|
|
152
|
+
Apache-2.0 mock LLM server, as the offline agent endpoint in CI.
|
|
153
|
+
|
|
154
|
+
DuckDB is a trademark of the DuckDB Foundation. DataCharter is an independent
|
|
155
|
+
project and is not affiliated with or endorsed by the DuckDB Foundation.
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
[Apache-2.0](LICENSE)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# DataCharter
|
|
2
|
+
|
|
3
|
+
> Explore all your data locally, in one place — contract-governed data exploration, powered by DuckDB
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/datacharter/)
|
|
6
|
+
[](https://pypi.org/project/datacharter/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
Contract-governed local data exploration, **powered by [DuckDB](https://duckdb.org)**.
|
|
10
|
+
Define your sources as data contracts
|
|
11
|
+
([ODCS](https://bitol-io.github.io/open-data-contract-standard/)-compatible YAML),
|
|
12
|
+
query them through DuckDB's SQL federation engine with real source pushdowns,
|
|
13
|
+
and explore in a local web UI — SQL editor with live preview, auto-charts,
|
|
14
|
+
profiling. Every answer shows which source columns it read; ask questions in
|
|
15
|
+
plain language or serve the whole thing to an AI agent over [MCP](docs/mcp.md),
|
|
16
|
+
with PII masked from the model — all on your machine.
|
|
17
|
+
|
|
18
|
+
## What you can do
|
|
19
|
+
|
|
20
|
+
- **Drop a file, query it instantly.** Drag a CSV, Parquet, or JSON onto the window and run SQL on it right away — no import, no schema setup.
|
|
21
|
+
- **Join across sources — no pipelines.** Query and JOIN a Postgres table, a Parquet file, and a Snowflake table in a *single* SQL statement. No ETL, no copying everything into a warehouse first.
|
|
22
|
+
- **Connect all your data.** Postgres, MySQL, SQLite, SQL Server, BigQuery, Snowflake, files on S3/GCS/Azure, and Iceberg/Delta tables — all through one engine.
|
|
23
|
+
- **See answers as you type.** Live results preview while you write SQL, one-click auto-charts, and a profiling panel (missing values, distributions, outliers) — no separate BI tool.
|
|
24
|
+
- **Ask in plain English (optional).** Turn a question into SQL and an answer with the built-in agent — bring your own model, or run one fully local with no API key.
|
|
25
|
+
- **Keep sensitive data away from the AI.** Mark PII columns once; the agent and any connected AI see masked values (`•••`) while you still see the real data locally. Flip **Agent view** to see exactly what the model sees.
|
|
26
|
+
- **Safe by design.** The engine is read-only by construction — no query can write, delete, or touch the filesystem — so pointing an AI (or a teammate) at your real databases can't do damage.
|
|
27
|
+
- **Point AI tools at your data, safely.** A governed MCP server exposes read-only, PII-masked query tools to Cursor, Cline, or your own agent.
|
|
28
|
+
- **Trust every answer.** Each result shows exactly which source columns it read — so you always know where a number came from.
|
|
29
|
+
- **Save, reuse, export.** Snapshot a result as a reusable local table; export to CSV, Parquet, JSON, or XLSX.
|
|
30
|
+
- **Governance you can automate.** Catch schema/PII drift in CI, auto-detect PII columns, diff data across sources, and define certified metrics — from the command line.
|
|
31
|
+
|
|
32
|
+

|
|
33
|
+
|
|
34
|
+
**Status: pre-release.** V1 in development.
|
|
35
|
+
|
|
36
|
+
## Quick start
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
# Try it instantly on generated demo data — no install, no config:
|
|
40
|
+
uvx datacharter serve # needs `uv` → https://astral.sh/uv
|
|
41
|
+
# → serves at http://127.0.0.1:8321 (open it in your browser)
|
|
42
|
+
|
|
43
|
+
# Or install it:
|
|
44
|
+
pip install datacharter # Python 3.11+
|
|
45
|
+
|
|
46
|
+
# Start your own workspace:
|
|
47
|
+
datacharter init # scaffolds charter.yaml, queries/, .env.example
|
|
48
|
+
# → add a source: edit charter.yaml, or use the "Sources" panel in the UI
|
|
49
|
+
datacharter serve # → http://127.0.0.1:8321
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Then, once it's running, **drag a CSV, Parquet, or JSON file onto the window** to
|
|
53
|
+
query it instantly — no config needed.
|
|
54
|
+
|
|
55
|
+
**Optional natural-language agent** — point it at any OpenAI-compatible endpoint:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
export OPENAI_BASE_URL=... # any OpenAI-compatible API
|
|
59
|
+
export OPENAI_API_KEY=...
|
|
60
|
+
datacharter serve
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
…or run **fully local** — no API key, no data leaves your machine (requires
|
|
64
|
+
[Ollama](https://ollama.com)):
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
ollama pull qwen3:8b # once
|
|
68
|
+
datacharter serve --local # qwen3:8b by default (--model to change)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Why DataCharter
|
|
72
|
+
|
|
73
|
+
- **Your contracts are the catalog.** `charter.yaml` describes sources, tables,
|
|
74
|
+
and PII fields — the same contract spec your data team already writes, so
|
|
75
|
+
there's no separate metadata store to maintain.
|
|
76
|
+
- **Real federation, not just a shared connection.** Filters and projections are
|
|
77
|
+
pushed down to each source — even across a cross-source join, every leg is
|
|
78
|
+
filtered where its data lives. (Snowflake runs via connector extract,
|
|
79
|
+
`datacharter[snowflake]`, with the same pushdown into the extract.)
|
|
80
|
+
- **Local-first.** One process, your machine, no cloud dependency. The optional
|
|
81
|
+
`--local` agent runs a small open model via Ollama — no API key, no data leaves
|
|
82
|
+
your machine.
|
|
83
|
+
- **The workspace is a directory.** `charter.yaml` + `queries/*.sql` +
|
|
84
|
+
`.env.example` — commit it, clone it, `datacharter serve`. Your team's whole
|
|
85
|
+
exploration environment travels as a repo; secrets and local state never do.
|
|
86
|
+
|
|
87
|
+
DataCharter governs and audits your data, not just displays it. The full command
|
|
88
|
+
set (`drift`, `scan`, `diff`, `metric`, `mcp`, and more) is in the
|
|
89
|
+
[CLI reference](docs/cli.md); the security model is in [security](docs/security.md).
|
|
90
|
+
|
|
91
|
+
## Built on
|
|
92
|
+
|
|
93
|
+
DataCharter stands on excellent open-source foundations:
|
|
94
|
+
|
|
95
|
+
- **[DuckDB](https://duckdb.org)** — the analytical engine at our core:
|
|
96
|
+
federation (`ATTACH`), file formats, Iceberg/Delta, encryption, autocomplete.
|
|
97
|
+
- **[Open Data Contract Standard](https://bitol-io.github.io/open-data-contract-standard/)** /
|
|
98
|
+
[datacontract.com](https://datacontract-specification.com/) — the contract format `charter.yaml` speaks.
|
|
99
|
+
- **[Model Context Protocol](https://modelcontextprotocol.io)** — the open protocol
|
|
100
|
+
the `datacharter mcp` server speaks to agents and MCP clients.
|
|
101
|
+
- **[Vega-Lite](https://vega.github.io/vega-lite/)** — declarative charting.
|
|
102
|
+
- **[Monaco Editor](https://microsoft.github.io/monaco-editor/)** — the SQL editor.
|
|
103
|
+
- **[TanStack Table & Virtual](https://tanstack.com/)** — the virtualized results grid.
|
|
104
|
+
- And the Python & React ecosystems — FastAPI, pydantic, httpx, keyring, and
|
|
105
|
+
ruamel.yaml on the backend; React and Vite on the front.
|
|
106
|
+
|
|
107
|
+
Testing uses **[VidaiMock](https://github.com/vidaiUK/VidaiMock)**, an
|
|
108
|
+
Apache-2.0 mock LLM server, as the offline agent endpoint in CI.
|
|
109
|
+
|
|
110
|
+
DuckDB is a trademark of the DuckDB Foundation. DataCharter is an independent
|
|
111
|
+
project and is not affiliated with or endorsed by the DuckDB Foundation.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
[Apache-2.0](LICENSE)
|