Repository navigation
fix(packaging): ship runtime assets, not just *.py - #101
Merged
Merged
Conversation
setuptools ships only Python files unless told otherwise, and nothing told it otherwise. `pip install` therefore produced a silently incomplete package: 18 frozen prompt templates src/models/prompts/*.txt 16 SQLMesh models src/pipeline/**/*.sql 5 connector manifests src/extensions/**/*.json 1 WhatsApp node bridge src/extensions/bridges/whatsapp/node/*.js 1 extension manifest *.yaml Verified against the live install: site-packages/src/models/prompts/ contained 0 .txt files against 18 in the app payload, and 0 .sql/.js anywhere. This stayed hidden because the desktop bundle puts the source tree on sys.path ahead of site-packages, so the app never reads the installed copy. It only surfaces for code that imports `src.*` from an installed package — which is how it was found: the Pro CLI's `extraction-models` died with "prompt template not found: .../site-packages/src/models/prompts/llm_classifier_v1.txt", because agent modules build a FrozenPromptTemplate at import time and bootstrap_agents() imports the whole graph. Scoped by extension rather than by path so a new asset in an existing package is covered by default. `src/interface` has no __init__.py, so packages.find never picks it up and the 137 frontend .ts/.tsx files are not candidates. Wheel built from this now carries 19 .txt, 16 .sql, 5 .json, 1 .yaml and 1 .js alongside the 227 .py. The new test is a static check on pyproject rather than a build, so it costs milliseconds and fails the moment an asset of an undeclared type lands in a packaged directory. Confirmed it fails without the fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
pyproject.tomldeclared[tool.setuptools.packages.find]but nopackage-data, sopip installshipped*.pyand dropped every runtime asset.Measured against the live install — app payload vs
site-packages:src/models/prompts/*.txt)src/pipeline/**/*.sql)*.json)*.js)Why nobody noticed
The desktop bundle puts the source tree on
sys.pathahead of site-packages, so the app never reads the installed copy. It only breaks for code importingsrc.*from an installed package.That's how it surfaced — the Pro CLI's
extraction-models:Agent modules construct a
FrozenPromptTemplateat import time, andbootstrap_agents()imports the whole graph, so the first missing template takes the process down.Fix
Scoped by extension, not path, so a new asset in an existing package is covered by default.
src/interfacehas no__init__.py, sopackages.findnever picks it up and the 137 frontend.ts/.tsxfiles aren't candidates.A wheel built from this branch carries 19 .txt, 16 .sql, 5 .json, 1 .yaml, 1 .js alongside the 227
.py.Guard
tests/unit/test_package_data.pywalks every directory with an__init__.py, collects the extensions of non-source files, and asserts each is declared. Static check onpyproject.toml— milliseconds, no build. Verified it fails without the fix (all 3 cases).Testing
2,974 passed; the 5 failures are the pre-existing WhatsApp bridge ones that fail identically on a clean tree.🤖 Generated with Claude Code