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.
- sheetwright-0.1.0/.claude/settings.local.json +37 -0
- sheetwright-0.1.0/.github/workflows/test.yml +63 -0
- sheetwright-0.1.0/.gitignore +23 -0
- sheetwright-0.1.0/.python-version +1 -0
- sheetwright-0.1.0/CLAUDE.md +51 -0
- sheetwright-0.1.0/LICENSE +674 -0
- sheetwright-0.1.0/PKG-INFO +92 -0
- sheetwright-0.1.0/README.md +76 -0
- sheetwright-0.1.0/claude/specs/2026-04-25_sheetwright-design.md +294 -0
- sheetwright-0.1.0/docs/README.md +60 -0
- sheetwright-0.1.0/docs/getting-started.md +215 -0
- sheetwright-0.1.0/docs/reference/calc-engine.md +210 -0
- sheetwright-0.1.0/docs/reference/cli.md +264 -0
- sheetwright-0.1.0/docs/reference/mcp.md +290 -0
- sheetwright-0.1.0/docs/reference/source-format.md +331 -0
- sheetwright-0.1.0/docs/reference/testing.md +293 -0
- sheetwright-0.1.0/docs/tutorials/escape-hatch.md +167 -0
- sheetwright-0.1.0/docs/tutorials/greenfield-project.md +245 -0
- sheetwright-0.1.0/docs/tutorials/importing-existing.md +167 -0
- sheetwright-0.1.0/docs/tutorials/snapshots.md +156 -0
- sheetwright-0.1.0/docs/tutorials/tdd-workflow.md +156 -0
- sheetwright-0.1.0/docs/tutorials/windows-setup.md +222 -0
- sheetwright-0.1.0/pyproject.toml +65 -0
- sheetwright-0.1.0/src/sheetwright/__init__.py +3 -0
- sheetwright-0.1.0/src/sheetwright/build_hash.py +41 -0
- sheetwright-0.1.0/src/sheetwright/bulk.py +82 -0
- sheetwright-0.1.0/src/sheetwright/calc/__init__.py +20 -0
- sheetwright-0.1.0/src/sheetwright/calc/base.py +22 -0
- sheetwright-0.1.0/src/sheetwright/calc/cache.py +59 -0
- sheetwright-0.1.0/src/sheetwright/calc/libreoffice.py +112 -0
- sheetwright-0.1.0/src/sheetwright/cli.py +230 -0
- sheetwright-0.1.0/src/sheetwright/commands/__init__.py +0 -0
- sheetwright-0.1.0/src/sheetwright/commands/build_cmd.py +44 -0
- sheetwright-0.1.0/src/sheetwright/commands/check_cmd.py +29 -0
- sheetwright-0.1.0/src/sheetwright/commands/diff_cmd.py +29 -0
- sheetwright-0.1.0/src/sheetwright/commands/import_cmd.py +96 -0
- sheetwright-0.1.0/src/sheetwright/commands/init_cmd.py +52 -0
- sheetwright-0.1.0/src/sheetwright/commands/mcp_cmd.py +10 -0
- sheetwright-0.1.0/src/sheetwright/commands/recalc_cmd.py +52 -0
- sheetwright-0.1.0/src/sheetwright/commands/snapshot_cmd.py +74 -0
- sheetwright-0.1.0/src/sheetwright/commands/test_cmd.py +133 -0
- sheetwright-0.1.0/src/sheetwright/config.py +111 -0
- sheetwright-0.1.0/src/sheetwright/diff/__init__.py +23 -0
- sheetwright-0.1.0/src/sheetwright/diff/check.py +177 -0
- sheetwright-0.1.0/src/sheetwright/diff/compute.py +165 -0
- sheetwright-0.1.0/src/sheetwright/diff/format.py +79 -0
- sheetwright-0.1.0/src/sheetwright/diff/loaders.py +77 -0
- sheetwright-0.1.0/src/sheetwright/diff/model.py +105 -0
- sheetwright-0.1.0/src/sheetwright/exceptions.py +45 -0
- sheetwright-0.1.0/src/sheetwright/external_edit.py +44 -0
- sheetwright-0.1.0/src/sheetwright/gitutil.py +28 -0
- sheetwright-0.1.0/src/sheetwright/mcp/__init__.py +8 -0
- sheetwright-0.1.0/src/sheetwright/mcp/errors.py +42 -0
- sheetwright-0.1.0/src/sheetwright/mcp/server.py +359 -0
- sheetwright-0.1.0/src/sheetwright/mcp/shaping.py +86 -0
- sheetwright-0.1.0/src/sheetwright/model/__init__.py +0 -0
- sheetwright-0.1.0/src/sheetwright/model/cell.py +36 -0
- sheetwright-0.1.0/src/sheetwright/model/comment.py +11 -0
- sheetwright-0.1.0/src/sheetwright/model/conditional.py +116 -0
- sheetwright-0.1.0/src/sheetwright/model/format.py +45 -0
- sheetwright-0.1.0/src/sheetwright/model/table.py +27 -0
- sheetwright-0.1.0/src/sheetwright/model/validation.py +25 -0
- sheetwright-0.1.0/src/sheetwright/model/workbook.py +66 -0
- sheetwright-0.1.0/src/sheetwright/project.py +83 -0
- sheetwright-0.1.0/src/sheetwright/reimport/__init__.py +31 -0
- sheetwright-0.1.0/src/sheetwright/reimport/flow.py +239 -0
- sheetwright-0.1.0/src/sheetwright/reimport/session.py +60 -0
- sheetwright-0.1.0/src/sheetwright/security.py +196 -0
- sheetwright-0.1.0/src/sheetwright/snapshot.py +88 -0
- sheetwright-0.1.0/src/sheetwright/source/__init__.py +0 -0
- sheetwright-0.1.0/src/sheetwright/source/markdown.py +169 -0
- sheetwright-0.1.0/src/sheetwright/source/reader.py +32 -0
- sheetwright-0.1.0/src/sheetwright/source/writer.py +43 -0
- sheetwright-0.1.0/src/sheetwright/source/yaml_sidecar.py +408 -0
- sheetwright-0.1.0/src/sheetwright/testing/__init__.py +6 -0
- sheetwright-0.1.0/src/sheetwright/testing/addresses.py +44 -0
- sheetwright-0.1.0/src/sheetwright/testing/model.py +79 -0
- sheetwright-0.1.0/src/sheetwright/xlsx/__init__.py +0 -0
- sheetwright-0.1.0/src/sheetwright/xlsx/cf_translate.py +219 -0
- sheetwright-0.1.0/src/sheetwright/xlsx/flatten.py +96 -0
- sheetwright-0.1.0/src/sheetwright/xlsx/reader.py +246 -0
- sheetwright-0.1.0/src/sheetwright/xlsx/safe_load.py +88 -0
- sheetwright-0.1.0/src/sheetwright/xlsx/writer.py +238 -0
- sheetwright-0.1.0/tests/__init__.py +0 -0
- sheetwright-0.1.0/tests/fixtures/__init__.py +0 -0
- sheetwright-0.1.0/tests/fixtures/external_xlsx.py +49 -0
- sheetwright-0.1.0/tests/fixtures/libreoffice.py +13 -0
- sheetwright-0.1.0/tests/fixtures/workbooks.py +145 -0
- sheetwright-0.1.0/tests/security/__init__.py +0 -0
- sheetwright-0.1.0/tests/security/test_bulk_identifier_injection.py +121 -0
- sheetwright-0.1.0/tests/security/test_mcp_path_traversal.py +183 -0
- sheetwright-0.1.0/tests/security/test_path_containment.py +103 -0
- sheetwright-0.1.0/tests/security/test_phase1_acceptance.py +182 -0
- sheetwright-0.1.0/tests/security/test_safe_load_workbook.py +266 -0
- sheetwright-0.1.0/tests/security/test_security_limits.py +278 -0
- sheetwright-0.1.0/tests/test_addresses.py +71 -0
- sheetwright-0.1.0/tests/test_build.py +60 -0
- sheetwright-0.1.0/tests/test_build_hash.py +62 -0
- sheetwright-0.1.0/tests/test_bulk.py +76 -0
- sheetwright-0.1.0/tests/test_calc_base.py +46 -0
- sheetwright-0.1.0/tests/test_calc_cache.py +61 -0
- sheetwright-0.1.0/tests/test_calc_libreoffice.py +101 -0
- sheetwright-0.1.0/tests/test_check.py +144 -0
- sheetwright-0.1.0/tests/test_check_cmd.py +46 -0
- sheetwright-0.1.0/tests/test_cli.py +20 -0
- sheetwright-0.1.0/tests/test_config.py +95 -0
- sheetwright-0.1.0/tests/test_diff_cmd.py +72 -0
- sheetwright-0.1.0/tests/test_diff_compute.py +136 -0
- sheetwright-0.1.0/tests/test_diff_format.py +67 -0
- sheetwright-0.1.0/tests/test_diff_model.py +77 -0
- sheetwright-0.1.0/tests/test_end_to_end.py +108 -0
- sheetwright-0.1.0/tests/test_end_to_end_recalc.py +56 -0
- sheetwright-0.1.0/tests/test_end_to_end_reimport.py +193 -0
- sheetwright-0.1.0/tests/test_end_to_end_tier2.py +83 -0
- sheetwright-0.1.0/tests/test_external_edit_detection.py +83 -0
- sheetwright-0.1.0/tests/test_format_model.py +45 -0
- sheetwright-0.1.0/tests/test_import.py +86 -0
- sheetwright-0.1.0/tests/test_import_flatten.py +55 -0
- sheetwright-0.1.0/tests/test_init.py +46 -0
- sheetwright-0.1.0/tests/test_mcp_cmd.py +215 -0
- sheetwright-0.1.0/tests/test_mcp_errors.py +89 -0
- sheetwright-0.1.0/tests/test_mcp_server_skeleton.py +21 -0
- sheetwright-0.1.0/tests/test_mcp_shaping.py +58 -0
- sheetwright-0.1.0/tests/test_mcp_tools_calc.py +88 -0
- sheetwright-0.1.0/tests/test_mcp_tools_mutating.py +93 -0
- sheetwright-0.1.0/tests/test_mcp_tools_reimport.py +130 -0
- sheetwright-0.1.0/tests/test_mcp_tools_simple.py +94 -0
- sheetwright-0.1.0/tests/test_model.py +68 -0
- sheetwright-0.1.0/tests/test_model_tier2_scaffolding.py +102 -0
- sheetwright-0.1.0/tests/test_recalc_cmd.py +71 -0
- sheetwright-0.1.0/tests/test_reimport_interactive.py +91 -0
- sheetwright-0.1.0/tests/test_reimport_noninteractive.py +99 -0
- sheetwright-0.1.0/tests/test_reimport_session.py +82 -0
- sheetwright-0.1.0/tests/test_reimport_stage.py +84 -0
- sheetwright-0.1.0/tests/test_reimport_uncommitted_guard.py +102 -0
- sheetwright-0.1.0/tests/test_snapshot.py +85 -0
- sheetwright-0.1.0/tests/test_snapshot_cmd.py +86 -0
- sheetwright-0.1.0/tests/test_source_markdown.py +82 -0
- sheetwright-0.1.0/tests/test_source_roundtrip.py +58 -0
- sheetwright-0.1.0/tests/test_source_tier2_roundtrip.py +48 -0
- sheetwright-0.1.0/tests/test_source_yaml.py +76 -0
- sheetwright-0.1.0/tests/test_test_cmd.py +115 -0
- sheetwright-0.1.0/tests/test_testing_model.py +97 -0
- sheetwright-0.1.0/tests/test_xlsx_comments_roundtrip.py +50 -0
- sheetwright-0.1.0/tests/test_xlsx_conditional_lossiness.py +90 -0
- sheetwright-0.1.0/tests/test_xlsx_conditional_roundtrip.py +117 -0
- sheetwright-0.1.0/tests/test_xlsx_determinism.py +36 -0
- sheetwright-0.1.0/tests/test_xlsx_flatten.py +103 -0
- sheetwright-0.1.0/tests/test_xlsx_format_roundtrip.py +70 -0
- sheetwright-0.1.0/tests/test_xlsx_frozen_panes_roundtrip.py +63 -0
- sheetwright-0.1.0/tests/test_xlsx_print_area_roundtrip.py +60 -0
- sheetwright-0.1.0/tests/test_xlsx_reader.py +55 -0
- sheetwright-0.1.0/tests/test_xlsx_roundtrip.py +49 -0
- sheetwright-0.1.0/tests/test_xlsx_table_roundtrip.py +128 -0
- sheetwright-0.1.0/tests/test_xlsx_validation_roundtrip.py +46 -0
- 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.
|