sheetwright 0.1.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 (156) hide show
  1. sheetwright-0.1.0/.claude/settings.local.json +37 -0
  2. sheetwright-0.1.0/.github/workflows/test.yml +63 -0
  3. sheetwright-0.1.0/.gitignore +23 -0
  4. sheetwright-0.1.0/.python-version +1 -0
  5. sheetwright-0.1.0/CLAUDE.md +51 -0
  6. sheetwright-0.1.0/LICENSE +674 -0
  7. sheetwright-0.1.0/PKG-INFO +92 -0
  8. sheetwright-0.1.0/README.md +76 -0
  9. sheetwright-0.1.0/claude/specs/2026-04-25_sheetwright-design.md +294 -0
  10. sheetwright-0.1.0/docs/README.md +60 -0
  11. sheetwright-0.1.0/docs/getting-started.md +215 -0
  12. sheetwright-0.1.0/docs/reference/calc-engine.md +210 -0
  13. sheetwright-0.1.0/docs/reference/cli.md +264 -0
  14. sheetwright-0.1.0/docs/reference/mcp.md +290 -0
  15. sheetwright-0.1.0/docs/reference/source-format.md +331 -0
  16. sheetwright-0.1.0/docs/reference/testing.md +293 -0
  17. sheetwright-0.1.0/docs/tutorials/escape-hatch.md +167 -0
  18. sheetwright-0.1.0/docs/tutorials/greenfield-project.md +245 -0
  19. sheetwright-0.1.0/docs/tutorials/importing-existing.md +167 -0
  20. sheetwright-0.1.0/docs/tutorials/snapshots.md +156 -0
  21. sheetwright-0.1.0/docs/tutorials/tdd-workflow.md +156 -0
  22. sheetwright-0.1.0/docs/tutorials/windows-setup.md +222 -0
  23. sheetwright-0.1.0/pyproject.toml +65 -0
  24. sheetwright-0.1.0/src/sheetwright/__init__.py +3 -0
  25. sheetwright-0.1.0/src/sheetwright/build_hash.py +41 -0
  26. sheetwright-0.1.0/src/sheetwright/bulk.py +82 -0
  27. sheetwright-0.1.0/src/sheetwright/calc/__init__.py +20 -0
  28. sheetwright-0.1.0/src/sheetwright/calc/base.py +22 -0
  29. sheetwright-0.1.0/src/sheetwright/calc/cache.py +59 -0
  30. sheetwright-0.1.0/src/sheetwright/calc/libreoffice.py +112 -0
  31. sheetwright-0.1.0/src/sheetwright/cli.py +230 -0
  32. sheetwright-0.1.0/src/sheetwright/commands/__init__.py +0 -0
  33. sheetwright-0.1.0/src/sheetwright/commands/build_cmd.py +44 -0
  34. sheetwright-0.1.0/src/sheetwright/commands/check_cmd.py +29 -0
  35. sheetwright-0.1.0/src/sheetwright/commands/diff_cmd.py +29 -0
  36. sheetwright-0.1.0/src/sheetwright/commands/import_cmd.py +96 -0
  37. sheetwright-0.1.0/src/sheetwright/commands/init_cmd.py +52 -0
  38. sheetwright-0.1.0/src/sheetwright/commands/mcp_cmd.py +10 -0
  39. sheetwright-0.1.0/src/sheetwright/commands/recalc_cmd.py +52 -0
  40. sheetwright-0.1.0/src/sheetwright/commands/snapshot_cmd.py +74 -0
  41. sheetwright-0.1.0/src/sheetwright/commands/test_cmd.py +133 -0
  42. sheetwright-0.1.0/src/sheetwright/config.py +111 -0
  43. sheetwright-0.1.0/src/sheetwright/diff/__init__.py +23 -0
  44. sheetwright-0.1.0/src/sheetwright/diff/check.py +177 -0
  45. sheetwright-0.1.0/src/sheetwright/diff/compute.py +165 -0
  46. sheetwright-0.1.0/src/sheetwright/diff/format.py +79 -0
  47. sheetwright-0.1.0/src/sheetwright/diff/loaders.py +77 -0
  48. sheetwright-0.1.0/src/sheetwright/diff/model.py +105 -0
  49. sheetwright-0.1.0/src/sheetwright/exceptions.py +45 -0
  50. sheetwright-0.1.0/src/sheetwright/external_edit.py +44 -0
  51. sheetwright-0.1.0/src/sheetwright/gitutil.py +28 -0
  52. sheetwright-0.1.0/src/sheetwright/mcp/__init__.py +8 -0
  53. sheetwright-0.1.0/src/sheetwright/mcp/errors.py +42 -0
  54. sheetwright-0.1.0/src/sheetwright/mcp/server.py +359 -0
  55. sheetwright-0.1.0/src/sheetwright/mcp/shaping.py +86 -0
  56. sheetwright-0.1.0/src/sheetwright/model/__init__.py +0 -0
  57. sheetwright-0.1.0/src/sheetwright/model/cell.py +36 -0
  58. sheetwright-0.1.0/src/sheetwright/model/comment.py +11 -0
  59. sheetwright-0.1.0/src/sheetwright/model/conditional.py +116 -0
  60. sheetwright-0.1.0/src/sheetwright/model/format.py +45 -0
  61. sheetwright-0.1.0/src/sheetwright/model/table.py +27 -0
  62. sheetwright-0.1.0/src/sheetwright/model/validation.py +25 -0
  63. sheetwright-0.1.0/src/sheetwright/model/workbook.py +66 -0
  64. sheetwright-0.1.0/src/sheetwright/project.py +83 -0
  65. sheetwright-0.1.0/src/sheetwright/reimport/__init__.py +31 -0
  66. sheetwright-0.1.0/src/sheetwright/reimport/flow.py +239 -0
  67. sheetwright-0.1.0/src/sheetwright/reimport/session.py +60 -0
  68. sheetwright-0.1.0/src/sheetwright/security.py +196 -0
  69. sheetwright-0.1.0/src/sheetwright/snapshot.py +88 -0
  70. sheetwright-0.1.0/src/sheetwright/source/__init__.py +0 -0
  71. sheetwright-0.1.0/src/sheetwright/source/markdown.py +169 -0
  72. sheetwright-0.1.0/src/sheetwright/source/reader.py +32 -0
  73. sheetwright-0.1.0/src/sheetwright/source/writer.py +43 -0
  74. sheetwright-0.1.0/src/sheetwright/source/yaml_sidecar.py +408 -0
  75. sheetwright-0.1.0/src/sheetwright/testing/__init__.py +6 -0
  76. sheetwright-0.1.0/src/sheetwright/testing/addresses.py +44 -0
  77. sheetwright-0.1.0/src/sheetwright/testing/model.py +79 -0
  78. sheetwright-0.1.0/src/sheetwright/xlsx/__init__.py +0 -0
  79. sheetwright-0.1.0/src/sheetwright/xlsx/cf_translate.py +219 -0
  80. sheetwright-0.1.0/src/sheetwright/xlsx/flatten.py +96 -0
  81. sheetwright-0.1.0/src/sheetwright/xlsx/reader.py +246 -0
  82. sheetwright-0.1.0/src/sheetwright/xlsx/safe_load.py +88 -0
  83. sheetwright-0.1.0/src/sheetwright/xlsx/writer.py +238 -0
  84. sheetwright-0.1.0/tests/__init__.py +0 -0
  85. sheetwright-0.1.0/tests/fixtures/__init__.py +0 -0
  86. sheetwright-0.1.0/tests/fixtures/external_xlsx.py +49 -0
  87. sheetwright-0.1.0/tests/fixtures/libreoffice.py +13 -0
  88. sheetwright-0.1.0/tests/fixtures/workbooks.py +145 -0
  89. sheetwright-0.1.0/tests/security/__init__.py +0 -0
  90. sheetwright-0.1.0/tests/security/test_bulk_identifier_injection.py +121 -0
  91. sheetwright-0.1.0/tests/security/test_mcp_path_traversal.py +183 -0
  92. sheetwright-0.1.0/tests/security/test_path_containment.py +103 -0
  93. sheetwright-0.1.0/tests/security/test_phase1_acceptance.py +182 -0
  94. sheetwright-0.1.0/tests/security/test_safe_load_workbook.py +266 -0
  95. sheetwright-0.1.0/tests/security/test_security_limits.py +278 -0
  96. sheetwright-0.1.0/tests/test_addresses.py +71 -0
  97. sheetwright-0.1.0/tests/test_build.py +60 -0
  98. sheetwright-0.1.0/tests/test_build_hash.py +62 -0
  99. sheetwright-0.1.0/tests/test_bulk.py +76 -0
  100. sheetwright-0.1.0/tests/test_calc_base.py +46 -0
  101. sheetwright-0.1.0/tests/test_calc_cache.py +61 -0
  102. sheetwright-0.1.0/tests/test_calc_libreoffice.py +101 -0
  103. sheetwright-0.1.0/tests/test_check.py +144 -0
  104. sheetwright-0.1.0/tests/test_check_cmd.py +46 -0
  105. sheetwright-0.1.0/tests/test_cli.py +20 -0
  106. sheetwright-0.1.0/tests/test_config.py +95 -0
  107. sheetwright-0.1.0/tests/test_diff_cmd.py +72 -0
  108. sheetwright-0.1.0/tests/test_diff_compute.py +136 -0
  109. sheetwright-0.1.0/tests/test_diff_format.py +67 -0
  110. sheetwright-0.1.0/tests/test_diff_model.py +77 -0
  111. sheetwright-0.1.0/tests/test_end_to_end.py +108 -0
  112. sheetwright-0.1.0/tests/test_end_to_end_recalc.py +56 -0
  113. sheetwright-0.1.0/tests/test_end_to_end_reimport.py +193 -0
  114. sheetwright-0.1.0/tests/test_end_to_end_tier2.py +83 -0
  115. sheetwright-0.1.0/tests/test_external_edit_detection.py +83 -0
  116. sheetwright-0.1.0/tests/test_format_model.py +45 -0
  117. sheetwright-0.1.0/tests/test_import.py +86 -0
  118. sheetwright-0.1.0/tests/test_import_flatten.py +55 -0
  119. sheetwright-0.1.0/tests/test_init.py +46 -0
  120. sheetwright-0.1.0/tests/test_mcp_cmd.py +215 -0
  121. sheetwright-0.1.0/tests/test_mcp_errors.py +89 -0
  122. sheetwright-0.1.0/tests/test_mcp_server_skeleton.py +21 -0
  123. sheetwright-0.1.0/tests/test_mcp_shaping.py +58 -0
  124. sheetwright-0.1.0/tests/test_mcp_tools_calc.py +88 -0
  125. sheetwright-0.1.0/tests/test_mcp_tools_mutating.py +93 -0
  126. sheetwright-0.1.0/tests/test_mcp_tools_reimport.py +130 -0
  127. sheetwright-0.1.0/tests/test_mcp_tools_simple.py +94 -0
  128. sheetwright-0.1.0/tests/test_model.py +68 -0
  129. sheetwright-0.1.0/tests/test_model_tier2_scaffolding.py +102 -0
  130. sheetwright-0.1.0/tests/test_recalc_cmd.py +71 -0
  131. sheetwright-0.1.0/tests/test_reimport_interactive.py +91 -0
  132. sheetwright-0.1.0/tests/test_reimport_noninteractive.py +99 -0
  133. sheetwright-0.1.0/tests/test_reimport_session.py +82 -0
  134. sheetwright-0.1.0/tests/test_reimport_stage.py +84 -0
  135. sheetwright-0.1.0/tests/test_reimport_uncommitted_guard.py +102 -0
  136. sheetwright-0.1.0/tests/test_snapshot.py +85 -0
  137. sheetwright-0.1.0/tests/test_snapshot_cmd.py +86 -0
  138. sheetwright-0.1.0/tests/test_source_markdown.py +82 -0
  139. sheetwright-0.1.0/tests/test_source_roundtrip.py +58 -0
  140. sheetwright-0.1.0/tests/test_source_tier2_roundtrip.py +48 -0
  141. sheetwright-0.1.0/tests/test_source_yaml.py +76 -0
  142. sheetwright-0.1.0/tests/test_test_cmd.py +115 -0
  143. sheetwright-0.1.0/tests/test_testing_model.py +97 -0
  144. sheetwright-0.1.0/tests/test_xlsx_comments_roundtrip.py +50 -0
  145. sheetwright-0.1.0/tests/test_xlsx_conditional_lossiness.py +90 -0
  146. sheetwright-0.1.0/tests/test_xlsx_conditional_roundtrip.py +117 -0
  147. sheetwright-0.1.0/tests/test_xlsx_determinism.py +36 -0
  148. sheetwright-0.1.0/tests/test_xlsx_flatten.py +103 -0
  149. sheetwright-0.1.0/tests/test_xlsx_format_roundtrip.py +70 -0
  150. sheetwright-0.1.0/tests/test_xlsx_frozen_panes_roundtrip.py +63 -0
  151. sheetwright-0.1.0/tests/test_xlsx_print_area_roundtrip.py +60 -0
  152. sheetwright-0.1.0/tests/test_xlsx_reader.py +55 -0
  153. sheetwright-0.1.0/tests/test_xlsx_roundtrip.py +49 -0
  154. sheetwright-0.1.0/tests/test_xlsx_table_roundtrip.py +128 -0
  155. sheetwright-0.1.0/tests/test_xlsx_validation_roundtrip.py +46 -0
  156. sheetwright-0.1.0/uv.lock +1019 -0
@@ -0,0 +1,37 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(git -C /srv/share/src/kaapstorm/claudesheets log --oneline -20)",
5
+ "WebFetch(domain:support.claude.com)",
6
+ "Bash(git -c user.email=nhooper@dimagi.com -c 'user.name=Norman Hooper' commit -m ' *)",
7
+ "WebFetch(domain:github.com)",
8
+ "Bash(git *)",
9
+ "Bash(uv run *)",
10
+ "Bash(uv add *)",
11
+ "Bash(awk 'length > 81')",
12
+ "Bash(python3 *)",
13
+ "Bash(libreoffice --version)",
14
+ "Bash(curl -fsSL https://raw.githubusercontent.com/kaapstorm/testsweet/refs/heads/main/README.md)",
15
+ "Bash(curl -fsSL https://raw.githubusercontent.com/kaapstorm/testsweet/refs/heads/main/docs/getting-started.md)",
16
+ "Bash(curl -fsSL https://raw.githubusercontent.com/kaapstorm/testsweet/refs/heads/main/docs/reference.md)",
17
+ "Read(//srv/share/src/kaapstorm/testsweet/src/testsweet/**)",
18
+ "Bash(git show *)",
19
+ "Read(//tmp/**)",
20
+ "Bash(uv pip *)",
21
+ "Bash(pip index *)",
22
+ "Bash(uv venv *)",
23
+ "Bash(/tmp/test-mcp/bin/python -c ' *)",
24
+ "Bash(grep -v ':0$')",
25
+ "Bash(uv remove *)",
26
+ "Bash(uv sync *)",
27
+ "Bash(xargs ls *)",
28
+ "Bash(grep -v \"^uv.lock$\")",
29
+ "Bash(xargs sed *)",
30
+ "Bash(gh pr *)",
31
+ "Bash(gh run *)",
32
+ "Bash(gh api *)",
33
+ "Bash(~/bin/pr-failures.sh)",
34
+ "Bash(awk '-F\\\\t' '$2==\"fail\" {print $NF}')"
35
+ ]
36
+ }
37
+ }
@@ -0,0 +1,63 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ name: Test on ${{ matrix.os }}
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ os: [ubuntu-latest, macos-latest, windows-latest]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v5
22
+ with:
23
+ enable-cache: true
24
+
25
+ - name: Set up Python
26
+ run: uv python install 3.11
27
+
28
+ - name: Install LibreOffice (Ubuntu)
29
+ if: runner.os == 'Linux'
30
+ run: |
31
+ sudo apt-get update
32
+ sudo apt-get install -y libreoffice
33
+
34
+ - name: Install LibreOffice (macOS)
35
+ if: runner.os == 'macOS'
36
+ run: brew install --cask libreoffice
37
+
38
+ - name: Install LibreOffice (Windows)
39
+ if: runner.os == 'Windows'
40
+ run: choco install libreoffice-still -y --no-progress
41
+
42
+ - name: Add LibreOffice to PATH (Windows)
43
+ if: runner.os == 'Windows'
44
+ shell: pwsh
45
+ run: echo "C:\Program Files\LibreOffice\program" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
46
+
47
+ - name: Confirm soffice is available
48
+ run: soffice --version
49
+
50
+ - name: Install dependencies
51
+ run: uv sync --all-extras
52
+
53
+ - name: Lint (ruff)
54
+ run: uv run ruff check src tests
55
+
56
+ - name: Format check (ruff)
57
+ run: uv run ruff format --check src tests
58
+
59
+ - name: Type check (mypy)
60
+ run: uv run mypy src/
61
+
62
+ - name: Run tests
63
+ run: uv run python -m testsweet tests/
@@ -0,0 +1,23 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .ruff_cache/
6
+
7
+ # uv / venvs
8
+ .venv/
9
+ .python-version.local
10
+
11
+ # sheetwright build artifacts (per-project, but ignored at repo root too)
12
+ build/
13
+ .sheetwright/
14
+
15
+ # IDE / OS
16
+ .vscode/
17
+ .idea/
18
+ .DS_Store
19
+
20
+ # Claude artifacts
21
+ claude/plans/
22
+ claude/reviews/
23
+ claude/transcripts/
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,51 @@
1
+ # Project conventions
2
+
3
+ ## Layout
4
+
5
+ - `src/sheetwright/` — library + CLI entry points
6
+ - `tests/` — testsweet tests, mirroring the package layout
7
+ - `claude/specs/` — design specifications
8
+ - `claude/plans/` — implementation plans (when written)
9
+
10
+ ## Design specs, plans and reviews
11
+
12
+ | File | Path |
13
+ |-----------------------|-------------------------------------------------|
14
+ | Design specifications | `claude/specs/YYYY-MM-DD_name-of-document.md` |
15
+ | Implementation plans | `claude/plans/YYYY-MM-DD_name-of-document.md` |
16
+ | Code reviews | `claude/reviews/YYYY-MM-DD_name-of-document.md` |
17
+
18
+ ## Python and tooling
19
+
20
+ - Python 3.11 (`.python-version`)
21
+
22
+ `python` must be run using `uv run python ...`
23
+
24
+ - [`uv`](https://docs.astral.sh/uv/) is the project manager — use
25
+ `uv sync` to install, `uv run <cmd>` to run, `uv add <pkg>` to add
26
+ runtime deps, `uv add --dev <pkg>` for dev deps. Don't edit
27
+ `pyproject.toml` dependency lists by hand unless you also know to
28
+ update `uv.lock`.
29
+
30
+ - [`ruff`](https://docs.astral.sh/ruff/) is the formatter/linter.
31
+ **Run `uv run ruff format <changed-files>` before every commit.**
32
+ Project style is `line-length = 79` and `quote-style = 'single'` —
33
+ use single quotes in new code; ruff format will fix mixed quoting.
34
+
35
+ - [`mypy`](https://mypy.readthedocs.io/) checks type annotations.
36
+ **Run `uv run mypy src/` before committing changes that add or
37
+ modify type annotations.** Public functions and CLI entry points
38
+ must have type hints; mypy must pass before commit.
39
+
40
+ - [testsweet](https://github.com/kaapstorm/testsweet) is the test library.
41
+ **Run `uv run python -m testsweet tests/` to verify changes.**
42
+ For links to documentation, see the testsweet
43
+ [README.md](https://raw.githubusercontent.com/kaapstorm/testsweet/refs/heads/main/README.md).
44
+
45
+ ## Code style
46
+
47
+ - Match the surrounding code. The project is young; when in doubt,
48
+ prefer the simplest readable option.
49
+ - Type hints on public functions and CLI entry points.
50
+ - No ad-hoc comments explaining what code does. Comment only when a
51
+ non-obvious *why* matters.