Skip to content

fix(packaging): ship runtime assets, not just *.py - #101

Merged
vdittgen merged 1 commit into
mainfrom
fix/package-data
Aug 5, 2026
Merged

vdittgen merged 1 commit into
mainfrom
fix/package-data

Conversation

@vdittgen

@vdittgen vdittgen commented Aug 5, 2026

Copy link
Copy Markdown
Owner

The bug

pyproject.toml declared [tool.setuptools.packages.find] but no package-data, so pip install shipped *.py and dropped every runtime asset.

Measured against the live install — app payload vs site-packages:

asset in payload installed
prompt templates (src/models/prompts/*.txt) 18 0
SQLMesh models (src/pipeline/**/*.sql) 16 0
connector manifests (*.json) 5 0
WhatsApp node bridge (*.js) 1 0

Why nobody noticed

The desktop bundle puts the source tree on sys.path ahead of site-packages, so the app never reads the installed copy. It only breaks for code importing src.* from an installed package.

That's how it surfaced — the Pro CLI's extraction-models:

{"ok": false, "error": "arandu core unavailable: prompt template not found:
 .../site-packages/src/models/prompts/llm_classifier_v1.txt"}

Agent modules construct a FrozenPromptTemplate at import time, and bootstrap_agents() imports the whole graph, so the first missing template takes the process down.

Fix

[tool.setuptools.package-data]
"*" = ["*.txt", "*.sql", "*.yaml", "*.yml", "*.json", "*.js"]

Scoped by extension, not 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 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.py walks every directory with an __init__.py, collects the extensions of non-source files, and asserts each is declared. Static check on pyproject.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

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>
@vdittgen
vdittgen merged commit b76857d into main Aug 5, 2026
5 of 6 checks passed
@vdittgen
vdittgen deleted the fix/package-data branch August 5, 2026 23:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant