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.
Files changed (135) hide show
  1. {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/package-installer-smoke.yml +2 -2
  2. {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/pages.yml +1 -1
  3. {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/pre-commit.yml +1 -1
  4. {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/publish-mcp.yml +1 -1
  5. {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/publish.yml +1 -1
  6. {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/release.yml +3 -3
  7. datoon-2.0.0/.github/workflows/tests.yml +24 -0
  8. {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/validate-artifacts.yml +2 -2
  9. {datoon-1.9.0 → datoon-2.0.0}/.github/workflows/workflow-lint.yml +2 -2
  10. {datoon-1.9.0 → datoon-2.0.0}/CHANGELOG.md +27 -0
  11. {datoon-1.9.0 → datoon-2.0.0}/CLAUDE.md +4 -4
  12. {datoon-1.9.0 → datoon-2.0.0}/CONTRIBUTING.md +2 -8
  13. {datoon-1.9.0 → datoon-2.0.0}/INSTALL.md +4 -17
  14. {datoon-1.9.0 → datoon-2.0.0}/PKG-INFO +9 -10
  15. {datoon-1.9.0 → datoon-2.0.0}/README.md +7 -9
  16. {datoon-1.9.0/plugins/datoon/skills/datoon → datoon-2.0.0}/SKILL.md +1 -1
  17. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/run.py +2 -1
  18. {datoon-1.9.0 → datoon-2.0.0/datoon}/SKILL.md +1 -1
  19. datoon-2.0.0/datoon.skill +0 -0
  20. {datoon-1.9.0 → datoon-2.0.0}/docs/index.html +2 -3
  21. {datoon-1.9.0 → datoon-2.0.0/plugins/datoon}/skills/datoon/SKILL.md +1 -1
  22. {datoon-1.9.0 → datoon-2.0.0}/pyproject.toml +3 -4
  23. {datoon-1.9.0 → datoon-2.0.0}/setup.sh +5 -15
  24. {datoon-1.9.0 → datoon-2.0.0}/skills/datoon/README.md +1 -2
  25. {datoon-1.9.0 → datoon-2.0.0/skills}/datoon/SKILL.md +1 -1
  26. {datoon-1.9.0 → datoon-2.0.0}/smithery.yaml +1 -2
  27. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/_version.py +3 -3
  28. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/cli.py +0 -7
  29. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/converter.py +11 -30
  30. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/mcp_server.py +1 -5
  31. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/models.py +0 -3
  32. {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/PKG-INFO +9 -10
  33. {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/SOURCES.txt +2 -1
  34. {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/requires.txt +1 -0
  35. {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/scm_file_list.json +97 -96
  36. datoon-2.0.0/src/datoon.egg-info/scm_version.json +8 -0
  37. datoon-2.0.0/tests/integration/test_toon_roundtrip.py +56 -0
  38. datoon-2.0.0/tests/unit/test_benchmark_readme.py +28 -0
  39. {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_cli.py +18 -18
  40. {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_converter_policy.py +80 -39
  41. {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_mcp_server.py +17 -18
  42. {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_models.py +0 -7
  43. {datoon-1.9.0 → datoon-2.0.0}/uv.lock +288 -223
  44. datoon-1.9.0/.github/workflows/tests.yml +0 -43
  45. datoon-1.9.0/datoon.skill +0 -0
  46. datoon-1.9.0/src/datoon.egg-info/scm_version.json +0 -8
  47. datoon-1.9.0/tests/integration/test_toon_cli_integration.py +0 -68
  48. {datoon-1.9.0 → datoon-2.0.0}/.agents/plugins/marketplace.json +0 -0
  49. {datoon-1.9.0 → datoon-2.0.0}/.claude-plugin/marketplace.json +0 -0
  50. {datoon-1.9.0 → datoon-2.0.0}/.claude-plugin/plugin.json +0 -0
  51. {datoon-1.9.0 → datoon-2.0.0}/.editorconfig +0 -0
  52. {datoon-1.9.0 → datoon-2.0.0}/.gitattributes +0 -0
  53. {datoon-1.9.0 → datoon-2.0.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  54. {datoon-1.9.0 → datoon-2.0.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  55. {datoon-1.9.0 → datoon-2.0.0}/.github/dependabot.yml +0 -0
  56. {datoon-1.9.0 → datoon-2.0.0}/.gitignore +0 -0
  57. {datoon-1.9.0 → datoon-2.0.0}/.pre-commit-config.yaml +0 -0
  58. {datoon-1.9.0 → datoon-2.0.0}/.releaserc.yaml +0 -0
  59. {datoon-1.9.0 → datoon-2.0.0}/LICENSE +0 -0
  60. {datoon-1.9.0 → datoon-2.0.0}/MARKETPLACES.md +0 -0
  61. {datoon-1.9.0 → datoon-2.0.0}/SECURITY.md +0 -0
  62. {datoon-1.9.0 → datoon-2.0.0}/assets/datoon-banner.svg +0 -0
  63. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/REPORT.md +0 -0
  64. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/agent_results.json +0 -0
  65. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/expected_answers.json +0 -0
  66. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/generate_payloads.py +0 -0
  67. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/1_large.json +0 -0
  68. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/1_medium.json +0 -0
  69. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/1_small.json +0 -0
  70. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/2_large.json +0 -0
  71. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/2_medium.json +0 -0
  72. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/2_small.json +0 -0
  73. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/3_large.json +0 -0
  74. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/3_medium.json +0 -0
  75. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/payloads/3_small.json +0 -0
  76. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/1_large.report.json +0 -0
  77. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/1_medium.report.json +0 -0
  78. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/1_small.report.json +0 -0
  79. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/2_large.report.json +0 -0
  80. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/2_medium.report.json +0 -0
  81. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/2_small.report.json +0 -0
  82. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/3_large.report.json +0 -0
  83. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/3_medium.report.json +0 -0
  84. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/reports/3_small.report.json +0 -0
  85. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/scored_agent_results.json +0 -0
  86. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/1_large.toon +0 -0
  87. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/1_medium.toon +0 -0
  88. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/1_small.toon +0 -0
  89. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/2_large.toon +0 -0
  90. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/2_medium.toon +0 -0
  91. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/2_small.toon +0 -0
  92. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/3_large.toon +0 -0
  93. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/3_medium.toon +0 -0
  94. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/agent_skill_eval/toon/3_small.toon +0 -0
  95. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/payloads.json +0 -0
  96. {datoon-1.9.0 → datoon-2.0.0}/benchmarks/results/.gitkeep +0 -0
  97. {datoon-1.9.0 → datoon-2.0.0}/docs/.nojekyll +0 -0
  98. {datoon-1.9.0 → datoon-2.0.0}/docs/app.js +0 -0
  99. {datoon-1.9.0 → datoon-2.0.0}/docs/assets/datoon-banner.svg +0 -0
  100. {datoon-1.9.0 → datoon-2.0.0}/docs/styles.css +0 -0
  101. {datoon-1.9.0 → datoon-2.0.0}/glama.json +0 -0
  102. {datoon-1.9.0 → datoon-2.0.0}/install.sh +0 -0
  103. {datoon-1.9.0 → datoon-2.0.0}/plugins/datoon/.codex-plugin/plugin.json +0 -0
  104. {datoon-1.9.0 → datoon-2.0.0}/scripts/ab_skill_benchmark.py +0 -0
  105. {datoon-1.9.0 → datoon-2.0.0}/scripts/install.py +0 -0
  106. {datoon-1.9.0 → datoon-2.0.0}/scripts/summarize_agent_skill_eval.py +0 -0
  107. {datoon-1.9.0 → datoon-2.0.0}/scripts/validate_plugin_metadata.py +0 -0
  108. {datoon-1.9.0 → datoon-2.0.0}/scripts/validate_skill_sync.py +0 -0
  109. {datoon-1.9.0 → datoon-2.0.0}/server.json +0 -0
  110. {datoon-1.9.0 → datoon-2.0.0}/setup.cfg +0 -0
  111. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/__init__.py +0 -0
  112. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/analyzer.py +0 -0
  113. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/errors.py +0 -0
  114. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/py.typed +0 -0
  115. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/__init__.py +0 -0
  116. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/_coerce.py +0 -0
  117. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/_tabular.py +0 -0
  118. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/columnar.py +0 -0
  119. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/csv.py +0 -0
  120. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/excel.py +0 -0
  121. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/jsonl.py +0 -0
  122. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/numbers.py +0 -0
  123. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/xml.py +0 -0
  124. {datoon-1.9.0 → datoon-2.0.0}/src/datoon/readers/yaml.py +0 -0
  125. {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/dependency_links.txt +0 -0
  126. {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/entry_points.txt +0 -0
  127. {datoon-1.9.0 → datoon-2.0.0}/src/datoon.egg-info/top_level.txt +0 -0
  128. {datoon-1.9.0 → datoon-2.0.0}/tests/fixtures/users.expected.toon +0 -0
  129. {datoon-1.9.0 → datoon-2.0.0}/tests/fixtures/users.json +0 -0
  130. {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_analyzer.py +0 -0
  131. {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_errors.py +0 -0
  132. {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_installer.py +0 -0
  133. {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_readers.py +0 -0
  134. {datoon-1.9.0 → datoon-2.0.0}/tests/unit/test_tabular_rows.py +0 -0
  135. {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@v6
21
+ uses: actions/setup-python@v7
22
22
  with:
23
23
  python-version: "3.12"
24
24
 
@@ -26,7 +26,7 @@ jobs:
26
26
  runs-on: ubuntu-latest
27
27
  steps:
28
28
  - name: Checkout
29
- uses: actions/checkout@v7
29
+ uses: actions/checkout@v7.0.1
30
30
 
31
31
  - name: Setup Pages
32
32
  id: setup_pages
@@ -15,7 +15,7 @@ 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 uv
21
21
  uses: astral-sh/setup-uv@v7
@@ -26,7 +26,7 @@ jobs:
26
26
  || github.event.workflow_run.conclusion == 'success'
27
27
  runs-on: ubuntu-latest
28
28
  steps:
29
- - uses: actions/checkout@v7
29
+ - uses: actions/checkout@v7.0.1
30
30
  with:
31
31
  ref: main
32
32
  fetch-depth: 0
@@ -24,7 +24,7 @@ jobs:
24
24
  outputs:
25
25
  version: ${{ steps.ver.outputs.version }}
26
26
  steps:
27
- - uses: actions/checkout@v7
27
+ - uses: actions/checkout@v7.0.1
28
28
  with:
29
29
  ref: main
30
30
  fetch-depth: 0
@@ -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@v6
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@v6
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@v6
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@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6
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@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6
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 CLI call, policy gating
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
- - Missing `npx` must not break auto mode; fallback to JSON unless `force=True`.
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
- Integration tests require Node.js and `npx`.
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`, and TOON conversion through `npx --yes @toon-format/cli@2` when conversion actually runs.
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
- Integration tests need Node.js and `npx`, because conversion uses the official TOON CLI.
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 missing npx
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` calls the official TOON CLI through `npx`.
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
- Required for conversion:
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
- - Node.js or `npx` is unavailable, or the TOON CLI fails.
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 mentions the TOON dependency, install Node.js and confirm `npx` is available:
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: 1.9.0
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 Node.js call. No silent corruption.
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 requires Node.js with `npx` in PATH — analysis and format reading work without it.
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 CLI call; no Node.js overhead
256
- 1. **Convert + estimate** — TOON CLI runs, token savings calculated
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 (no Node.js required):**
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 Node.js needed |
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 -m "not integration" # unit only (102 tests)
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 Node.js call. No silent corruption.
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 requires Node.js with `npx` in PATH — analysis and format reading work without it.
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 CLI call; no Node.js overhead
196
- 1. **Convert + estimate** — TOON CLI runs, token savings calculated
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 (no Node.js required):**
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 Node.js needed |
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 -m "not integration" # unit only (102 tests)
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 CLI dependency is unavailable, keep JSON and report fallback reason.
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
- return f"{before}\n{replacement}\n{after}"
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 CLI dependency is unavailable, keep JSON and report fallback reason.
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+ and Node.js for TOON CLI
187
- execution through
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 CLI dependency is unavailable, keep JSON and report fallback reason.
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. Node.js (optional — needed for TOON CLI conversion) ───────────────────
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
- # ── 5. Register datoon CLI globally via uv tool ───────────────────────────────
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
- # ── 6. Ensure CLI is on PATH ──────────────────────────────────────────────────
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
- # ── 7. Verify ─────────────────────────────────────────────────────────────────
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 -m 'not integration'"
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 conversion is unavailable, auto mode keeps JSON and reports the fallback reason.
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 CLI dependency is unavailable, keep JSON and report fallback reason.
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
- # Node.js (npx) is required only when conversion actually runs; structure
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 = '1.9.0'
22
- __version_tuple__ = version_tuple = (1, 9, 0)
21
+ __version__ = version = '2.0.0'
22
+ __version_tuple__ = version_tuple = (2, 0, 0)
23
23
 
24
- __commit_id__ = commit_id = 'g412011b90'
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