datoon 1.9.0__tar.gz → 2.0.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.
- {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/package-installer-smoke.yml +2 -2
- {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/pages.yml +1 -1
- {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/pre-commit.yml +1 -1
- {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/publish-mcp.yml +1 -1
- {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/publish.yml +1 -1
- {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/release.yml +3 -3
- datoon-2.0.0/.github/workflows/tests.yml +24 -0
- {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/validate-artifacts.yml +2 -2
- {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/workflow-lint.yml +2 -2
- {datoon-1.9.0 → datoon-2.0.0}/CHANGELOG.md +27 -0
- {datoon-1.9.0 → datoon-2.0.0}/CLAUDE.md +4 -4
- {datoon-1.9.0 → datoon-2.0.0}/CONTRIBUTING.md +2 -8
- {datoon-1.9.0 → datoon-2.0.0}/INSTALL.md +4 -17
- {datoon-1.9.0 → datoon-2.0.0}/PKG-INFO +9 -10
- {datoon-1.9.0 → datoon-2.0.0}/README.md +7 -9
- {datoon-1.9.0/plugins/datoon/skills/datoon → datoon-2.0.0}/SKILL.md +1 -1
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/run.py +2 -1
- {datoon-1.9.0 → datoon-2.0.0/datoon}/SKILL.md +1 -1
- datoon-2.0.0/datoon.skill +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/docs/index.html +2 -3
- {datoon-1.9.0 → datoon-2.0.0/plugins/datoon}/skills/datoon/SKILL.md +1 -1
- {datoon-1.9.0 → datoon-2.0.0}/pyproject.toml +3 -4
- {datoon-1.9.0 → datoon-2.0.0}/setup.sh +5 -15
- {datoon-1.9.0 → datoon-2.0.0}/skills/datoon/README.md +1 -2
- {datoon-1.9.0 → datoon-2.0.0/skills}/datoon/SKILL.md +1 -1
- {datoon-1.9.0 → datoon-2.0.0}/smithery.yaml +1 -2
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/_version.py +3 -3
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/cli.py +0 -7
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/converter.py +11 -30
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/mcp_server.py +1 -5
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/models.py +0 -3
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/PKG-INFO +9 -10
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/SOURCES.txt +2 -1
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/requires.txt +1 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/scm_file_list.json +97 -96
- datoon-2.0.0/src/datoon.egg-info/scm_version.json +8 -0
- datoon-2.0.0/tests/integration/test_toon_roundtrip.py +56 -0
- datoon-2.0.0/tests/unit/test_benchmark_readme.py +28 -0
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_cli.py +18 -18
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_converter_policy.py +80 -39
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_mcp_server.py +17 -18
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_models.py +0 -7
- {datoon-1.9.0 → datoon-2.0.0}/uv.lock +288 -223
- datoon-1.9.0/.github/workflows/tests.yml +0 -43
- datoon-1.9.0/datoon.skill +0 -0
- datoon-1.9.0/src/datoon.egg-info/scm_version.json +0 -8
- datoon-1.9.0/tests/integration/test_toon_cli_integration.py +0 -68
- {datoon-1.9.0 → datoon-2.0.0}/.agents/plugins/marketplace.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.claude-plugin/marketplace.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.claude-plugin/plugin.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.editorconfig +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.gitattributes +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.github/dependabot.yml +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.gitignore +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.pre-commit-config.yaml +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/.releaserc.yaml +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/LICENSE +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/MARKETPLACES.md +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/SECURITY.md +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/assets/datoon-banner.svg +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/REPORT.md +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/agent_results.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/expected_answers.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/generate_payloads.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/1_large.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/1_medium.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/1_small.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/2_large.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/2_medium.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/2_small.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/3_large.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/3_medium.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/3_small.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/1_large.report.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/1_medium.report.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/1_small.report.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/2_large.report.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/2_medium.report.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/2_small.report.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/3_large.report.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/3_medium.report.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/3_small.report.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/scored_agent_results.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/1_large.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/1_medium.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/1_small.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/2_large.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/2_medium.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/2_small.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/3_large.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/3_medium.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/3_small.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/payloads.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/benchmarks/results/.gitkeep +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/docs/.nojekyll +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/docs/app.js +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/docs/assets/datoon-banner.svg +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/docs/styles.css +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/glama.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/install.sh +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/plugins/datoon/.codex-plugin/plugin.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/scripts/ab_skill_benchmark.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/scripts/install.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/scripts/summarize_agent_skill_eval.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/scripts/validate_plugin_metadata.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/scripts/validate_skill_sync.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/server.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/setup.cfg +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/__init__.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/analyzer.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/errors.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/py.typed +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/__init__.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/_coerce.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/_tabular.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/columnar.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/csv.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/excel.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/jsonl.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/numbers.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/xml.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/yaml.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/dependency_links.txt +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/entry_points.txt +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/top_level.txt +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/tests/fixtures/users.expected.toon +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/tests/fixtures/users.json +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_analyzer.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_errors.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_installer.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_readers.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_tabular_rows.py +0 -0
- {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_tokens.py +0 -0
|
@@ -15,10 +15,10 @@ jobs:
|
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
16
|
steps:
|
|
17
17
|
- name: Checkout
|
|
18
|
-
uses: actions/checkout@v7
|
|
18
|
+
uses: actions/checkout@v7.0.1
|
|
19
19
|
|
|
20
20
|
- name: Setup Python
|
|
21
|
-
uses: actions/setup-python@
|
|
21
|
+
uses: actions/setup-python@v7
|
|
22
22
|
with:
|
|
23
23
|
python-version: "3.12"
|
|
24
24
|
|
|
@@ -15,17 +15,17 @@ jobs:
|
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
16
|
steps:
|
|
17
17
|
- name: Checkout
|
|
18
|
-
uses: actions/checkout@v7
|
|
18
|
+
uses: actions/checkout@v7.0.1
|
|
19
19
|
with:
|
|
20
20
|
fetch-depth: 0
|
|
21
21
|
|
|
22
22
|
- name: Setup Node.js
|
|
23
|
-
uses: actions/setup-node@
|
|
23
|
+
uses: actions/setup-node@v7
|
|
24
24
|
with:
|
|
25
25
|
node-version: "22"
|
|
26
26
|
|
|
27
27
|
- name: Setup Python
|
|
28
|
-
uses: actions/setup-python@
|
|
28
|
+
uses: actions/setup-python@v7
|
|
29
29
|
with:
|
|
30
30
|
python-version: "3.12"
|
|
31
31
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: tests-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
unit-tests:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout
|
|
18
|
+
uses: actions/checkout@v7.0.1
|
|
19
|
+
|
|
20
|
+
- name: Setup uv
|
|
21
|
+
uses: astral-sh/setup-uv@v7
|
|
22
|
+
|
|
23
|
+
- name: Run tests
|
|
24
|
+
run: uv run --with ".[dev]" pytest
|
|
@@ -18,10 +18,10 @@ jobs:
|
|
|
18
18
|
runs-on: ubuntu-latest
|
|
19
19
|
steps:
|
|
20
20
|
- name: Checkout
|
|
21
|
-
uses: actions/checkout@v7
|
|
21
|
+
uses: actions/checkout@v7.0.1
|
|
22
22
|
|
|
23
23
|
- name: Setup Python
|
|
24
|
-
uses: actions/setup-python@
|
|
24
|
+
uses: actions/setup-python@v7
|
|
25
25
|
with:
|
|
26
26
|
python-version: "3.12"
|
|
27
27
|
|
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
runs-on: ubuntu-latest
|
|
23
23
|
steps:
|
|
24
24
|
- name: Checkout
|
|
25
|
-
uses: actions/checkout@
|
|
25
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
|
|
26
26
|
with:
|
|
27
27
|
persist-credentials: false
|
|
28
28
|
|
|
@@ -35,7 +35,7 @@ jobs:
|
|
|
35
35
|
runs-on: ubuntu-latest
|
|
36
36
|
steps:
|
|
37
37
|
- name: Checkout
|
|
38
|
-
uses: actions/checkout@
|
|
38
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
|
|
39
39
|
with:
|
|
40
40
|
persist-credentials: false
|
|
41
41
|
|
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
# [2.0.0](https://github.com/andrii-su/datoon/compare/v1.9.1...v2.0.0) (2026-11-11)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
* feat!: encode TOON in pure Python, drop the Node.js CLI ([1bffef7](https://github.com/andrii-su/datoon/commit/1bffef7c068cd3f2a73df80a9348f0af28dd3040))
|
|
5
|
+
* feat!: encode TOON in pure Python, drop the Node.js CLI ([#69](https://github.com/andrii-su/datoon/issues/69)) ([7e28513](https://github.com/andrii-su/datoon/commit/7e28513aa1fb0cf0be315d8e09586eedb0ce6800))
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* `toon-format` is a required dependency; the
|
|
11
|
+
`ConversionConfig.toon_cli_timeout` field, the `--timeout` CLI flag and
|
|
12
|
+
the `timeout` argument of the `convert_json` / `convert_text` MCP tools
|
|
13
|
+
are removed. The skip reason for a failed conversion is now
|
|
14
|
+
"TOON encoding failed; falling back to JSON."
|
|
15
|
+
* `toon-format` is a required dependency; the
|
|
16
|
+
`ConversionConfig.toon_cli_timeout` field, the `--timeout` CLI flag and
|
|
17
|
+
the `timeout` argument of the `convert_json` / `convert_text` MCP tools
|
|
18
|
+
are removed. The skip reason for a failed conversion is now
|
|
19
|
+
"TOON encoding failed; falling back to JSON."
|
|
20
|
+
|
|
21
|
+
## [1.9.1](https://github.com/andrii-su/datoon/compare/v1.9.0...v1.9.1) (2026-07-07)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* **benchmarks:** pad README table block with blank lines for mdformat ([#47](https://github.com/andrii-su/datoon/issues/47)) ([0bef8de](https://github.com/andrii-su/datoon/commit/0bef8de40266d2f026e4ee18e91f599b72a7cbcf))
|
|
27
|
+
|
|
1
28
|
# [1.9.0](https://github.com/andrii-su/datoon/compare/v1.8.0...v1.9.0) (2026-07-07)
|
|
2
29
|
|
|
3
30
|
|
|
@@ -30,7 +30,7 @@ datoon/
|
|
|
30
30
|
│
|
|
31
31
|
├── src/datoon/ # Python package source
|
|
32
32
|
│ ├── analyzer.py # Payload structure suitability checks
|
|
33
|
-
│ ├── converter.py # JSON normalization, TOON
|
|
33
|
+
│ ├── converter.py # JSON normalization, TOON encoder call, policy gating
|
|
34
34
|
│ ├── models.py # Config/report/outcome dataclasses
|
|
35
35
|
│ ├── cli.py # CLI entrypoint
|
|
36
36
|
│ └── mcp_server.py # MCP server tools
|
|
@@ -105,7 +105,7 @@ It runs on pull requests and pushes to `main`. The old auto-sync-on-main flow wa
|
|
|
105
105
|
|
|
106
106
|
- Never change semantic values or key names during conversion.
|
|
107
107
|
- Invalid JSON must fail loudly.
|
|
108
|
-
-
|
|
108
|
+
- An encoder failure must not break auto mode; fallback to JSON unless `force=True`.
|
|
109
109
|
- `--force` is for controlled experiments and should bypass gating, not hide conversion errors.
|
|
110
110
|
- Auto mode skips before conversion when analysis rejects the payload, and skips after conversion when estimated savings are below `min_savings_ratio`.
|
|
111
111
|
- Keep skip reasons user-facing, specific, and stable enough for CLI/MCP troubleshooting.
|
|
@@ -122,7 +122,7 @@ python scripts/validate_plugin_metadata.py
|
|
|
122
122
|
uvx pre-commit run --all-files
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
Conversion is pure Python (`toon-format`); no Node.js is needed for tests.
|
|
126
126
|
|
|
127
127
|
## Benchmark Commands
|
|
128
128
|
|
|
@@ -168,7 +168,7 @@ Config writes must:
|
|
|
168
168
|
- remove only `datoon`-owned entries on uninstall;
|
|
169
169
|
- keep dry-run side-effect free.
|
|
170
170
|
|
|
171
|
-
Security and privacy docs should state that the installer does not read or upload user payloads, but selected targets may call external tooling: Claude Code through `claude plugin ...`, Python package resolution through `uvx
|
|
171
|
+
Security and privacy docs should state that the installer does not read or upload user payloads, but selected targets may call external tooling: Claude Code through `claude plugin ...`, Python package resolution through `uvx`; TOON conversion runs in-process through the `toon-format` package and calls no external tooling.
|
|
172
172
|
|
|
173
173
|
## Known Gaps
|
|
174
174
|
|
|
@@ -15,7 +15,7 @@ python scripts/validate_skill_sync.py
|
|
|
15
15
|
python scripts/validate_plugin_metadata.py
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Conversion is pure Python (the `toon-format` package); no Node.js is required for tests.
|
|
19
19
|
|
|
20
20
|
## What To Edit
|
|
21
21
|
|
|
@@ -67,12 +67,6 @@ Run the full suite:
|
|
|
67
67
|
uv run pytest
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
Run unit tests only:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
uv run pytest -m "not integration"
|
|
74
|
-
```
|
|
75
|
-
|
|
76
70
|
Run pre-commit locally:
|
|
77
71
|
|
|
78
72
|
```bash
|
|
@@ -112,7 +106,7 @@ Use Conventional Commit subjects:
|
|
|
112
106
|
|
|
113
107
|
```text
|
|
114
108
|
feat: add MCP analyze_json tool
|
|
115
|
-
fix: preserve JSON fallback on
|
|
109
|
+
fix: preserve JSON fallback on encoder failure
|
|
116
110
|
docs: clarify Claude Code plugin install
|
|
117
111
|
test: cover non-uniform arrays
|
|
118
112
|
```
|
|
@@ -16,7 +16,6 @@ The setup script:
|
|
|
16
16
|
|
|
17
17
|
- checks for Python 3.12+;
|
|
18
18
|
- installs `uv` if it is missing;
|
|
19
|
-
- warns if Node.js is missing;
|
|
20
19
|
- runs `uv sync --extra dev`;
|
|
21
20
|
- installs the editable `datoon` CLI globally through `uv tool install`.
|
|
22
21
|
|
|
@@ -69,21 +68,16 @@ datoon input.json --force --report-stdout
|
|
|
69
68
|
|
|
70
69
|
## TOON Dependency
|
|
71
70
|
|
|
72
|
-
`datoon`
|
|
71
|
+
`datoon` converts to TOON in pure Python using the official [`toon-format`](https://pypi.org/project/toon-format/) package, which is installed automatically as a dependency. No Node.js is needed.
|
|
73
72
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
- Node.js
|
|
77
|
-
- `npx` in `PATH`
|
|
78
|
-
|
|
79
|
-
Without Node.js, structure analysis still works, but conversion falls back to JSON in auto mode. Forced conversion fails loudly.
|
|
73
|
+
If the encoder fails, auto mode falls back to JSON. Forced conversion fails loudly.
|
|
80
74
|
|
|
81
75
|
In auto mode, `datoon` skips conversion and returns compact JSON when:
|
|
82
76
|
|
|
83
77
|
- the payload has no uniform object array with at least the configured row count;
|
|
84
78
|
- the payload exceeds the configured maximum nesting depth;
|
|
85
79
|
- estimated TOON savings are below `--min-savings`;
|
|
86
|
-
-
|
|
80
|
+
- the TOON encoder fails.
|
|
87
81
|
|
|
88
82
|
Invalid JSON never falls back silently. It raises an error.
|
|
89
83
|
|
|
@@ -232,12 +226,7 @@ echo '{"users":[{"id":1,"name":"Ada"},{"id":2,"name":"Lin"},{"id":3,"name":"Grac
|
|
|
232
226
|
| datoon --report-stdout
|
|
233
227
|
```
|
|
234
228
|
|
|
235
|
-
If the reason
|
|
236
|
-
|
|
237
|
-
```bash
|
|
238
|
-
node --version
|
|
239
|
-
npx --version
|
|
240
|
-
```
|
|
229
|
+
If the reason says TOON encoding failed, rerun with `--force` to see the underlying encoder error.
|
|
241
230
|
|
|
242
231
|
If the reason mentions structure or savings, the skip is expected auto-mode behavior. Use `--force` only for controlled experiments where a failed TOON conversion should fail the command.
|
|
243
232
|
|
|
@@ -264,8 +253,6 @@ python scripts/validate_skill_sync.py
|
|
|
264
253
|
PYTHONPATH=src python benchmarks/run.py --dry-run
|
|
265
254
|
```
|
|
266
255
|
|
|
267
|
-
Full integration tests require Node.js and `npx`.
|
|
268
|
-
|
|
269
256
|
## Uninstall
|
|
270
257
|
|
|
271
258
|
For the editable CLI installed by `setup.sh`:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datoon
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Smart structured-data-to-TOON gateway with pragmatic auto-gating for LLM prompts.
|
|
5
5
|
Author-email: Andrii Suruhov <andrii.suruhov@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -37,6 +37,7 @@ Classifier: Operating System :: OS Independent
|
|
|
37
37
|
Requires-Python: >=3.12
|
|
38
38
|
Description-Content-Type: text/markdown
|
|
39
39
|
License-File: LICENSE
|
|
40
|
+
Requires-Dist: toon-format>=1.2.0
|
|
40
41
|
Provides-Extra: dev
|
|
41
42
|
Requires-Dist: pytest>=9.0.3; extra == "dev"
|
|
42
43
|
Requires-Dist: pre-commit>=4.6.0; extra == "dev"
|
|
@@ -169,7 +170,7 @@ Same result. Zero JSON serialization in your code.
|
|
|
169
170
|
{"decision":"skip","reason":"No uniform object arrays found with at least 3 rows."}
|
|
170
171
|
```
|
|
171
172
|
|
|
172
|
-
No
|
|
173
|
+
No silent corruption.
|
|
173
174
|
|
|
174
175
|
</td>
|
|
175
176
|
</tr>
|
|
@@ -218,7 +219,7 @@ pip install "datoon[mcp]"
|
|
|
218
219
|
pip install "datoon[all]"
|
|
219
220
|
```
|
|
220
221
|
|
|
221
|
-
Requires Python 3.12+. TOON conversion
|
|
222
|
+
Requires Python 3.12+. TOON conversion is pure Python (official [`toon-format`](https://pypi.org/project/toon-format/) encoder, installed automatically) — no Node.js needed.
|
|
222
223
|
|
|
223
224
|
For Claude Code plugin, Codex, and MCP config → [**INSTALL.md**](./INSTALL.md).
|
|
224
225
|
|
|
@@ -252,8 +253,8 @@ For Claude Code plugin, Codex, and MCP config → [**INSTALL.md**](./INSTALL.md)
|
|
|
252
253
|
1. **Detect format** — from `--format` flag, file extension, or default to JSON for stdin
|
|
253
254
|
1. **Read + normalize** — parse source into list of row dicts; serialize to compact JSON
|
|
254
255
|
1. **Analyze structure** — uniform object arrays? acceptable depth? minimum rows?
|
|
255
|
-
1. **Gate early** — non-candidates skip before any
|
|
256
|
-
1. **Convert + estimate** — TOON
|
|
256
|
+
1. **Gate early** — non-candidates skip before any TOON encoding
|
|
257
|
+
1. **Convert + estimate** — TOON encoder runs in-process, token savings calculated
|
|
257
258
|
1. **Gate savings** — below threshold → return JSON; above → return TOON with report
|
|
258
259
|
|
|
259
260
|
Every path returns a `ConversionReport` with `decision`, `reason`, and token estimates. Pipelines never get silent surprises.
|
|
@@ -344,7 +345,7 @@ outcome = convert_json_for_llm(json_text, ConversionConfig())
|
|
|
344
345
|
send_to_model(outcome.payload_text)
|
|
345
346
|
```
|
|
346
347
|
|
|
347
|
-
**Structure-only analysis
|
|
348
|
+
**Structure-only analysis:**
|
|
348
349
|
|
|
349
350
|
```python
|
|
350
351
|
from datoon.analyzer import analyze_payload
|
|
@@ -366,7 +367,7 @@ ______________________________________________________________________
|
|
|
366
367
|
|---|---|
|
|
367
368
|
| `convert_json` | Full JSON conversion with policy gating |
|
|
368
369
|
| `convert_text` | Converts CSV, YAML, XML, or JSONL text with policy gating |
|
|
369
|
-
| `analyze_json` | Structure analysis only — no
|
|
370
|
+
| `analyze_json` | Structure analysis only — no conversion |
|
|
370
371
|
|
|
371
372
|
**Claude Desktop / Cursor / Windsurf config:**
|
|
372
373
|
|
|
@@ -419,7 +420,6 @@ ______________________________________________________________________
|
|
|
419
420
|
| `--min-savings` | `0.15` | Minimum relative token savings required |
|
|
420
421
|
| `--max-depth` | `6` | Maximum nesting depth for auto-conversion |
|
|
421
422
|
| `--min-uniform-rows` | `3` | Minimum rows in uniform object arrays |
|
|
422
|
-
| `--timeout` | `30` | Seconds before TOON CLI call is aborted |
|
|
423
423
|
| `--report <path>` | — | Write JSON conversion report to file |
|
|
424
424
|
| `--report-stdout` | — | Print JSON conversion report to stderr |
|
|
425
425
|
| `-o <path>` | stdout | Output file path |
|
|
@@ -514,8 +514,7 @@ uvx pre-commit install
|
|
|
514
514
|
**Tests:**
|
|
515
515
|
|
|
516
516
|
```bash
|
|
517
|
-
pytest
|
|
518
|
-
pytest # with integration (requires Node.js + npx)
|
|
517
|
+
pytest
|
|
519
518
|
```
|
|
520
519
|
|
|
521
520
|
**Skill sync + plugin metadata:**
|
|
@@ -109,7 +109,7 @@ Same result. Zero JSON serialization in your code.
|
|
|
109
109
|
{"decision":"skip","reason":"No uniform object arrays found with at least 3 rows."}
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
-
No
|
|
112
|
+
No silent corruption.
|
|
113
113
|
|
|
114
114
|
</td>
|
|
115
115
|
</tr>
|
|
@@ -158,7 +158,7 @@ pip install "datoon[mcp]"
|
|
|
158
158
|
pip install "datoon[all]"
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
-
Requires Python 3.12+. TOON conversion
|
|
161
|
+
Requires Python 3.12+. TOON conversion is pure Python (official [`toon-format`](https://pypi.org/project/toon-format/) encoder, installed automatically) — no Node.js needed.
|
|
162
162
|
|
|
163
163
|
For Claude Code plugin, Codex, and MCP config → [**INSTALL.md**](./INSTALL.md).
|
|
164
164
|
|
|
@@ -192,8 +192,8 @@ For Claude Code plugin, Codex, and MCP config → [**INSTALL.md**](./INSTALL.md)
|
|
|
192
192
|
1. **Detect format** — from `--format` flag, file extension, or default to JSON for stdin
|
|
193
193
|
1. **Read + normalize** — parse source into list of row dicts; serialize to compact JSON
|
|
194
194
|
1. **Analyze structure** — uniform object arrays? acceptable depth? minimum rows?
|
|
195
|
-
1. **Gate early** — non-candidates skip before any
|
|
196
|
-
1. **Convert + estimate** — TOON
|
|
195
|
+
1. **Gate early** — non-candidates skip before any TOON encoding
|
|
196
|
+
1. **Convert + estimate** — TOON encoder runs in-process, token savings calculated
|
|
197
197
|
1. **Gate savings** — below threshold → return JSON; above → return TOON with report
|
|
198
198
|
|
|
199
199
|
Every path returns a `ConversionReport` with `decision`, `reason`, and token estimates. Pipelines never get silent surprises.
|
|
@@ -284,7 +284,7 @@ outcome = convert_json_for_llm(json_text, ConversionConfig())
|
|
|
284
284
|
send_to_model(outcome.payload_text)
|
|
285
285
|
```
|
|
286
286
|
|
|
287
|
-
**Structure-only analysis
|
|
287
|
+
**Structure-only analysis:**
|
|
288
288
|
|
|
289
289
|
```python
|
|
290
290
|
from datoon.analyzer import analyze_payload
|
|
@@ -306,7 +306,7 @@ ______________________________________________________________________
|
|
|
306
306
|
|---|---|
|
|
307
307
|
| `convert_json` | Full JSON conversion with policy gating |
|
|
308
308
|
| `convert_text` | Converts CSV, YAML, XML, or JSONL text with policy gating |
|
|
309
|
-
| `analyze_json` | Structure analysis only — no
|
|
309
|
+
| `analyze_json` | Structure analysis only — no conversion |
|
|
310
310
|
|
|
311
311
|
**Claude Desktop / Cursor / Windsurf config:**
|
|
312
312
|
|
|
@@ -359,7 +359,6 @@ ______________________________________________________________________
|
|
|
359
359
|
| `--min-savings` | `0.15` | Minimum relative token savings required |
|
|
360
360
|
| `--max-depth` | `6` | Maximum nesting depth for auto-conversion |
|
|
361
361
|
| `--min-uniform-rows` | `3` | Minimum rows in uniform object arrays |
|
|
362
|
-
| `--timeout` | `30` | Seconds before TOON CLI call is aborted |
|
|
363
362
|
| `--report <path>` | — | Write JSON conversion report to file |
|
|
364
363
|
| `--report-stdout` | — | Print JSON conversion report to stderr |
|
|
365
364
|
| `-o <path>` | stdout | Output file path |
|
|
@@ -454,8 +453,7 @@ uvx pre-commit install
|
|
|
454
453
|
**Tests:**
|
|
455
454
|
|
|
456
455
|
```bash
|
|
457
|
-
pytest
|
|
458
|
-
pytest # with integration (requires Node.js + npx)
|
|
456
|
+
pytest
|
|
459
457
|
```
|
|
460
458
|
|
|
461
459
|
**Skill sync + plugin metadata:**
|
|
@@ -50,7 +50,7 @@ Skip conversion when any condition fails:
|
|
|
50
50
|
|
|
51
51
|
- Never change semantic values or key names.
|
|
52
52
|
- Fail loudly for invalid JSON.
|
|
53
|
-
- If TOON
|
|
53
|
+
- If TOON encoding fails, keep JSON and report fallback reason.
|
|
54
54
|
- Use `--force` only for controlled experiments.
|
|
55
55
|
|
|
56
56
|
## Boundaries
|
|
@@ -316,7 +316,8 @@ def _replace_between_markers(
|
|
|
316
316
|
)
|
|
317
317
|
before = content[: start + len(start_marker)]
|
|
318
318
|
after = content[end:]
|
|
319
|
-
|
|
319
|
+
# Blank lines around the block keep the injected README mdformat-clean.
|
|
320
|
+
return f"{before}\n\n{replacement}\n\n{after}"
|
|
320
321
|
|
|
321
322
|
|
|
322
323
|
def update_readme(table_md: str) -> None:
|
|
@@ -50,7 +50,7 @@ Skip conversion when any condition fails:
|
|
|
50
50
|
|
|
51
51
|
- Never change semantic values or key names.
|
|
52
52
|
- Fail loudly for invalid JSON.
|
|
53
|
-
- If TOON
|
|
53
|
+
- If TOON encoding fails, keep JSON and report fallback reason.
|
|
54
54
|
- Use `--force` only for controlled experiments.
|
|
55
55
|
|
|
56
56
|
## Boundaries
|
|
Binary file
|
|
@@ -183,9 +183,8 @@ echo '{"users":[{"id":1,"name":"Ada"}]}' | datoon --report-stdout
|
|
|
183
183
|
datoon ./input.json -o ./output.toon --report ./report.json</pre>
|
|
184
184
|
</div>
|
|
185
185
|
<p class="note">
|
|
186
|
-
Requires Python 3.12
|
|
187
|
-
|
|
188
|
-
<code>npx --yes @toon-format/cli@2</code>.
|
|
186
|
+
Requires Python 3.12+. TOON conversion is pure Python;
|
|
187
|
+
no Node.js needed.
|
|
189
188
|
</p>
|
|
190
189
|
</div>
|
|
191
190
|
</section>
|
|
@@ -50,7 +50,7 @@ Skip conversion when any condition fails:
|
|
|
50
50
|
|
|
51
51
|
- Never change semantic values or key names.
|
|
52
52
|
- Fail loudly for invalid JSON.
|
|
53
|
-
- If TOON
|
|
53
|
+
- If TOON encoding fails, keep JSON and report fallback reason.
|
|
54
54
|
- Use `--force` only for controlled experiments.
|
|
55
55
|
|
|
56
56
|
## Boundaries
|
|
@@ -20,7 +20,9 @@ classifiers = [
|
|
|
20
20
|
"License :: OSI Approved :: MIT License",
|
|
21
21
|
"Operating System :: OS Independent"
|
|
22
22
|
]
|
|
23
|
-
dependencies = [
|
|
23
|
+
dependencies = [
|
|
24
|
+
"toon-format>=1.2.0",
|
|
25
|
+
]
|
|
24
26
|
|
|
25
27
|
[project.optional-dependencies]
|
|
26
28
|
dev = ["pytest>=9.0.3", "pre-commit>=4.6.0", "pyyaml>=6.0"]
|
|
@@ -60,6 +62,3 @@ local_scheme = "no-local-version"
|
|
|
60
62
|
testpaths = ["tests"]
|
|
61
63
|
pythonpath = ["src"]
|
|
62
64
|
addopts = "-ra"
|
|
63
|
-
markers = [
|
|
64
|
-
"integration: tests that require Node.js and @toon-format/cli access",
|
|
65
|
-
]
|
|
@@ -41,23 +41,13 @@ fi
|
|
|
41
41
|
|
|
42
42
|
_green "uv OK — $(uv --version)"
|
|
43
43
|
|
|
44
|
-
# ── 3.
|
|
45
|
-
_blue "Checking Node.js..."
|
|
46
|
-
|
|
47
|
-
if command -v node &>/dev/null; then
|
|
48
|
-
_green "Node.js OK — $(node --version)"
|
|
49
|
-
else
|
|
50
|
-
_warn "Node.js not found. Install from https://nodejs.org to enable TOON conversion."
|
|
51
|
-
_warn "analyze_json and policy gating work without Node.js; CLI conversion requires it."
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
# ── 4. Dev dependencies ───────────────────────────────────────────────────────
|
|
44
|
+
# ── 3. Dev dependencies ───────────────────────────────────────────────────────
|
|
55
45
|
_blue "Installing dev dependencies via uv sync..."
|
|
56
46
|
cd "$REPO_DIR"
|
|
57
47
|
uv sync --extra dev
|
|
58
48
|
_green "Dev dependencies installed"
|
|
59
49
|
|
|
60
|
-
# ──
|
|
50
|
+
# ── 4. Register datoon CLI globally via uv tool ───────────────────────────────
|
|
61
51
|
_blue "Installing datoon CLI via uv tool..."
|
|
62
52
|
|
|
63
53
|
uv tool install --editable "$REPO_DIR"
|
|
@@ -67,7 +57,7 @@ UV_LOCAL_BIN="$HOME/.local/bin"
|
|
|
67
57
|
|
|
68
58
|
_green "datoon CLI installed"
|
|
69
59
|
|
|
70
|
-
# ──
|
|
60
|
+
# ── 5. Ensure CLI is on PATH ──────────────────────────────────────────────────
|
|
71
61
|
_blue "Checking PATH..."
|
|
72
62
|
|
|
73
63
|
if ! command -v datoon &>/dev/null; then
|
|
@@ -96,7 +86,7 @@ if ! command -v datoon &>/dev/null; then
|
|
|
96
86
|
fi
|
|
97
87
|
fi
|
|
98
88
|
|
|
99
|
-
# ──
|
|
89
|
+
# ── 6. Verify ─────────────────────────────────────────────────────────────────
|
|
100
90
|
if command -v datoon &>/dev/null; then
|
|
101
91
|
_green "datoon CLI ready — $(datoon --help | head -1)"
|
|
102
92
|
fi
|
|
@@ -111,7 +101,7 @@ echo " echo '{\"users\":[{\"id\":1}]}' | datoon --report-stdout"
|
|
|
111
101
|
echo " datoon input.json -o output.toon --report report.json"
|
|
112
102
|
echo ""
|
|
113
103
|
echo " Run tests:"
|
|
114
|
-
echo " pytest
|
|
104
|
+
echo " pytest"
|
|
115
105
|
echo ""
|
|
116
106
|
echo " MCP server (requires datoon[mcp]):"
|
|
117
107
|
echo " uv run --extra mcp datoon-mcp"
|
|
@@ -41,9 +41,8 @@ If policy accepts conversion, the agent should pass the TOON payload forward. If
|
|
|
41
41
|
## Requirements
|
|
42
42
|
|
|
43
43
|
- `datoon` CLI available in `PATH`
|
|
44
|
-
- Node.js and `npx` available for TOON conversion
|
|
45
44
|
|
|
46
|
-
If TOON
|
|
45
|
+
If TOON encoding fails, auto mode keeps JSON and reports the fallback reason.
|
|
47
46
|
|
|
48
47
|
## Source Files
|
|
49
48
|
|
|
@@ -50,7 +50,7 @@ Skip conversion when any condition fails:
|
|
|
50
50
|
|
|
51
51
|
- Never change semantic values or key names.
|
|
52
52
|
- Fail loudly for invalid JSON.
|
|
53
|
-
- If TOON
|
|
53
|
+
- If TOON encoding fails, keep JSON and report fallback reason.
|
|
54
54
|
- Use `--force` only for controlled experiments.
|
|
55
55
|
|
|
56
56
|
## Boundaries
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
# https://smithery.ai/docs/build/project-config
|
|
3
3
|
#
|
|
4
4
|
# datoon runs locally over stdio and needs no API keys or runtime config.
|
|
5
|
-
#
|
|
6
|
-
# analysis works without it.
|
|
5
|
+
# Conversion is pure Python (toon-format), so no Node.js is needed.
|
|
7
6
|
|
|
8
7
|
startCommand:
|
|
9
8
|
type: stdio
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '
|
|
22
|
-
__version_tuple__ = version_tuple = (
|
|
21
|
+
__version__ = version = '2.0.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (2, 0, 0)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g02282b3f8'
|
|
@@ -69,12 +69,6 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
69
69
|
default=3,
|
|
70
70
|
help="Minimum row count for uniform object arrays (default: 3).",
|
|
71
71
|
)
|
|
72
|
-
parser.add_argument(
|
|
73
|
-
"--timeout",
|
|
74
|
-
type=int,
|
|
75
|
-
default=30,
|
|
76
|
-
help="Seconds to wait for the TOON CLI before aborting (default: 30).",
|
|
77
|
-
)
|
|
78
72
|
parser.add_argument(
|
|
79
73
|
"--sheet",
|
|
80
74
|
type=int,
|
|
@@ -178,7 +172,6 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
178
172
|
max_depth=args.max_depth,
|
|
179
173
|
min_uniform_rows=args.min_uniform_rows,
|
|
180
174
|
force=args.force,
|
|
181
|
-
toon_cli_timeout=args.timeout,
|
|
182
175
|
token_encoding=args.encoding,
|
|
183
176
|
)
|
|
184
177
|
|