vibetuner 2.14.1__py3-none-any.whl → 2.26.9__py3-none-any.whl

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.

Potentially problematic release.


This version of vibetuner might be problematic. Click here for more details.

Files changed (52) hide show
  1. vibetuner/cli/__init__.py +65 -3
  2. vibetuner/cli/run.py +2 -2
  3. vibetuner/config.py +19 -9
  4. vibetuner/context.py +3 -0
  5. vibetuner/frontend/__init__.py +27 -5
  6. vibetuner/frontend/lifespan.py +18 -7
  7. vibetuner/frontend/middleware.py +2 -6
  8. vibetuner/frontend/routes/debug.py +1 -1
  9. vibetuner/frontend/routes/user.py +1 -1
  10. vibetuner/frontend/templates.py +1 -3
  11. vibetuner/mongo.py +18 -3
  12. vibetuner/paths.py +31 -10
  13. vibetuner/tasks/__init__.py +0 -2
  14. vibetuner/tasks/lifespan.py +28 -0
  15. vibetuner/tasks/worker.py +2 -5
  16. vibetuner/templates/email/{default/magic_link.html.jinja → magic_link.html.jinja} +2 -1
  17. vibetuner/templates/frontend/base/favicons.html.jinja +1 -1
  18. vibetuner/templates/frontend/base/skeleton.html.jinja +5 -2
  19. vibetuner/templates/frontend/debug/collections.html.jinja +2 -0
  20. vibetuner/templates/frontend/debug/components/debug_nav.html.jinja +6 -6
  21. vibetuner/templates/frontend/debug/index.html.jinja +6 -4
  22. vibetuner/templates/frontend/debug/info.html.jinja +2 -0
  23. vibetuner/templates/frontend/debug/users.html.jinja +4 -2
  24. vibetuner/templates/frontend/debug/version.html.jinja +2 -0
  25. vibetuner/templates/frontend/email_sent.html.jinja +2 -1
  26. vibetuner/templates/frontend/index.html.jinja +1 -0
  27. vibetuner/templates/frontend/login.html.jinja +8 -3
  28. vibetuner/templates/frontend/user/edit.html.jinja +3 -2
  29. vibetuner/templates/frontend/user/profile.html.jinja +2 -1
  30. vibetuner/versioning.py +6 -2
  31. {vibetuner-2.14.1.dist-info → vibetuner-2.26.9.dist-info}/METADATA +23 -20
  32. vibetuner-2.26.9.dist-info/RECORD +71 -0
  33. {vibetuner-2.14.1.dist-info → vibetuner-2.26.9.dist-info}/WHEEL +1 -1
  34. vibetuner/frontend/AGENTS.md +0 -113
  35. vibetuner/frontend/CLAUDE.md +0 -113
  36. vibetuner/frontend/context.py +0 -10
  37. vibetuner/models/AGENTS.md +0 -165
  38. vibetuner/models/CLAUDE.md +0 -165
  39. vibetuner/services/AGENTS.md +0 -104
  40. vibetuner/services/CLAUDE.md +0 -104
  41. vibetuner/tasks/AGENTS.md +0 -98
  42. vibetuner/tasks/CLAUDE.md +0 -98
  43. vibetuner/tasks/context.py +0 -34
  44. vibetuner/templates/email/AGENTS.md +0 -48
  45. vibetuner/templates/email/CLAUDE.md +0 -48
  46. vibetuner/templates/frontend/AGENTS.md +0 -74
  47. vibetuner/templates/frontend/CLAUDE.md +0 -74
  48. vibetuner/templates/markdown/AGENTS.md +0 -29
  49. vibetuner/templates/markdown/CLAUDE.md +0 -29
  50. vibetuner-2.14.1.dist-info/RECORD +0 -86
  51. /vibetuner/templates/email/{default/magic_link.txt.jinja → magic_link.txt.jinja} +0 -0
  52. {vibetuner-2.14.1.dist-info → vibetuner-2.26.9.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  {% extends "base/skeleton.html.jinja" %}
2
+
2
3
  {% block title %}
3
4
  Debug Dashboard
4
5
  {% endblock title %}
@@ -23,7 +24,7 @@
23
24
  </h2>
24
25
  <p class="text-base-content/70 mb-4">View application configuration, cookies, and runtime information</p>
25
26
  <div class="card-actions justify-end">
26
- <a href="{{ url_for("debug_info") }}" class="btn btn-primary btn-sm">View Details</a>
27
+ <a href="{{ url_for('debug_info') }}" class="btn btn-primary btn-sm">View Details</a>
27
28
  </div>
28
29
  </div>
29
30
  </div>
@@ -39,7 +40,7 @@
39
40
  </h2>
40
41
  <p class="text-base-content/70 mb-4">Explore MongoDB collections and their field schemas</p>
41
42
  <div class="card-actions justify-end">
42
- <a href="{{ url_for("debug_collections") }}"
43
+ <a href="{{ url_for('debug_collections') }}"
43
44
  class="btn btn-primary btn-sm">View Schemas</a>
44
45
  </div>
45
46
  </div>
@@ -56,7 +57,7 @@
56
57
  </h2>
57
58
  <p class="text-base-content/70 mb-4">Check application version and build information</p>
58
59
  <div class="card-actions justify-end">
59
- <a href="{{ url_for("debug_version") }}" class="btn btn-primary btn-sm">View Version</a>
60
+ <a href="{{ url_for('debug_version') }}" class="btn btn-primary btn-sm">View Version</a>
60
61
  </div>
61
62
  </div>
62
63
  </div>
@@ -72,12 +73,13 @@
72
73
  </h2>
73
74
  <p class="text-base-content/70 mb-4">Verify application health and API endpoint status</p>
74
75
  <div class="card-actions justify-end">
75
- <a href="{{ url_for("health_ping") }}" class="btn btn-success btn-sm">Check Health</a>
76
+ <a href="{{ url_for('health_ping') }}" class="btn btn-success btn-sm">Check Health</a>
76
77
  </div>
77
78
  </div>
78
79
  </div>
79
80
  </div>
80
81
  <!-- Debug Navigation Footer -->
81
82
  {% include "debug/components/debug_nav.html.jinja" %}
83
+
82
84
  </div>
83
85
  {% endblock body %}
@@ -1,4 +1,5 @@
1
1
  {% extends "base/skeleton.html.jinja" %}
2
+
2
3
  {% block title %}
3
4
  System Information - Debug
4
5
  {% endblock title %}
@@ -252,5 +253,6 @@
252
253
  </div>
253
254
  <!-- Debug Navigation Footer -->
254
255
  {% include "debug/components/debug_nav.html.jinja" %}
256
+
255
257
  </div>
256
258
  {% endblock body %}
@@ -1,4 +1,5 @@
1
1
  {% extends "base/skeleton.html.jinja" %}
2
+
2
3
  {% block title %}
3
4
  Debug - User Impersonation
4
5
  {% endblock title %}
@@ -36,7 +37,7 @@
36
37
  User ID: <code>{{ current_user_id }}</code>
37
38
  </p>
38
39
  <div class="card-actions justify-end">
39
- <form method="post" action="/debug/stop-impersonation">
40
+ <form method="post" action="{{ url_for('debug.stop_impersonation') }}">
40
41
  <button type="submit" class="btn btn-secondary btn-sm">Stop Impersonation</button>
41
42
  </form>
42
43
  </div>
@@ -105,7 +106,7 @@
105
106
  <td class="text-center">
106
107
  {% if current_user_id != user.id|string %}
107
108
  <form method="post"
108
- action="/debug/impersonate/{{ user.id }}"
109
+ action="{{ url_for('debug.impersonate_user', user_id=user.id) }}"
109
110
  class="inline">
110
111
  <button type="submit" class="btn btn-outline btn-sm">Impersonate</button>
111
112
  </form>
@@ -133,5 +134,6 @@
133
134
  </div>
134
135
  <!-- Debug Navigation Footer -->
135
136
  {% include "debug/components/debug_nav.html.jinja" %}
137
+
136
138
  </div>
137
139
  {% endblock body %}
@@ -1,4 +1,5 @@
1
1
  {% extends "base/skeleton.html.jinja" %}
2
+
2
3
  {% block title %}
3
4
  Version Information - Debug
4
5
  {% endblock title %}
@@ -49,5 +50,6 @@
49
50
  </div>
50
51
  <!-- Debug Navigation Footer -->
51
52
  {% include "debug/components/debug_nav.html.jinja" %}
53
+
52
54
  </div>
53
55
  {% endblock body %}
@@ -1,4 +1,5 @@
1
1
  {% extends "base/skeleton.html.jinja" %}
2
+
2
3
  {% block title %}
3
4
  {{ _("Check Your Email") }}
4
5
  {% endblock title %}
@@ -64,7 +65,7 @@
64
65
  {{ _("Try Again") }}
65
66
  </a>
66
67
  <!-- Back to Home -->
67
- <a href="{{ url_for("homepage") }}"
68
+ <a href="{{ url_for('homepage') }}"
68
69
  class="btn btn-ghost btn-block gap-2 text-base-content/70 hover:text-base-content transition-all duration-300">
69
70
  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
70
71
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
@@ -1,5 +1,6 @@
1
1
  {% set BODY_CLASS = "min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-100 flex flex-col justify-between" %}
2
2
  {% extends "base/skeleton.html.jinja" %}
3
+
3
4
  {% block body %}
4
5
  <!-- Main Content -->
5
6
  <div class="flex-1 flex items-center justify-center px-6">
@@ -1,4 +1,5 @@
1
1
  {% extends "base/skeleton.html.jinja" %}
2
+
2
3
  {% block title %}
3
4
  {{ _("Sign In") }}
4
5
  {% endblock title %}
@@ -15,7 +16,11 @@
15
16
  {% if has_oauth and providers %}
16
17
  <div class="space-y-3 mb-6">
17
18
  {% for provider in providers %}
18
- <a href="{{ url_for('login_with_' + provider) }}{%- if next %}?next={{ next }}{%- endif %}"
19
+ {% set login_url = url_for('login_with_' + provider) %}
20
+ {% if next %}
21
+ {% set login_url = login_url ~ '?next=' ~ next %}
22
+ {% endif %}
23
+ <a href="{{ login_url }}"
19
24
  class="btn btn-outline btn-block justify-start gap-3 hover:btn-primary group transition-all duration-300 hover:scale-[1.02]">
20
25
  <span>{{ _("Continue with %(provider)s") | format(provider=provider.title()) }}</span>
21
26
  </a>
@@ -29,7 +34,7 @@
29
34
  <div class="bg-base-200/50 rounded-2xl p-6 border border-base-300/50">
30
35
  <form method="post"
31
36
  class="space-y-4"
32
- action="{{ url_for("send_magic_link") }}">
37
+ action="{{ url_for('send_magic_link') }}">
33
38
  {% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %}
34
39
  <div class="form-control">
35
40
  <label class="label" for="email">
@@ -40,7 +45,7 @@
40
45
  id="email"
41
46
  name="email"
42
47
  class="input input-bordered w-full pr-12 focus:input-primary transition-all duration-300"
43
- placeholder="{{ _("Enter your email address") }}"
48
+ placeholder="{{ _('Enter your email address') }}"
44
49
  required
45
50
  autocomplete="email" />
46
51
  <div class="absolute inset-y-0 right-0 flex items-center pr-3">
@@ -1,4 +1,5 @@
1
1
  {% extends "base/skeleton.html.jinja" %}
2
+
2
3
  {% block title %}
3
4
  {{ _("Edit Profile") }}
4
5
  {% endblock title %}
@@ -13,7 +14,7 @@
13
14
  </div>
14
15
  <!-- Edit Form -->
15
16
  <div class="bg-white shadow-lg rounded-lg p-6">
16
- <form method="post" action="{{ url_for("user_edit_submit") }}">
17
+ <form method="post" action="{{ url_for('user_edit_submit') }}">
17
18
  <div class="space-y-6">
18
19
  <!-- Name Field -->
19
20
  <div>
@@ -55,7 +56,7 @@
55
56
  </div>
56
57
  <!-- Form Actions -->
57
58
  <div class="flex justify-between items-center mt-8 pt-6 border-t border-gray-200">
58
- <a href="{{ url_for("user_profile") }}" class="btn btn-ghost">{{ _("Cancel") }}</a>
59
+ <a href="{{ url_for('user_profile') }}" class="btn btn-ghost">{{ _("Cancel") }}</a>
59
60
  <button type="submit" class="btn btn-primary">{{ _("Save Changes") }}</button>
60
61
  </div>
61
62
  </form>
@@ -1,4 +1,5 @@
1
1
  {% extends "base/skeleton.html.jinja" %}
2
+
2
3
  {% block title %}
3
4
  {{ _("User Profile") }}
4
5
  {% endblock title %}
@@ -108,7 +109,7 @@
108
109
  hx-get="/user/edit"
109
110
  hx-target="#main-content"
110
111
  hx-swap="innerHTML">{{ _("Edit Profile") }}</button>
111
- <a href="{{ url_for("auth_logout") }}" class="btn btn-outline btn-error">{{ _("Sign Out") }}</a>
112
+ <a href="{{ url_for('auth_logout') }}" class="btn btn-outline btn-error">{{ _("Sign Out") }}</a>
112
113
  </div>
113
114
  </div>
114
115
  </div>
vibetuner/versioning.py CHANGED
@@ -1,8 +1,12 @@
1
+ from vibetuner.logging import logger
2
+
3
+
1
4
  __version__ = "0.0.0-default"
2
5
 
3
6
  try:
4
7
  from app._version import version as __version__ # type: ignore
5
- except ImportError:
6
- pass
8
+ except (ImportError, ModuleNotFoundError) as e:
9
+ # Log warning for both ImportError and ModuleNotFoundError as requested
10
+ logger.warning(f"Failed to import app._version: {e}. Using default version.")
7
11
 
8
12
  version = __version__
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: vibetuner
3
- Version: 2.14.1
3
+ Version: 2.26.9
4
4
  Summary: Core Python framework and blessed dependencies for production-ready FastAPI + MongoDB + HTMX projects
5
5
  Keywords: fastapi,mongodb,htmx,web-framework,scaffolding,oauth,background-jobs
6
6
  Author: All Tuner Labs, S.L.
@@ -21,17 +21,17 @@ Requires-Dist: arel>=0.4.0
21
21
  Requires-Dist: asyncer>=0.0.10
22
22
  Requires-Dist: authlib>=1.6.5
23
23
  Requires-Dist: beanie[zstd]>=2.0.0
24
- Requires-Dist: click>=8.3.0
24
+ Requires-Dist: click>=8.3.1
25
25
  Requires-Dist: copier>=9.10.3,<9.10.4
26
26
  Requires-Dist: email-validator>=2.3.0
27
- Requires-Dist: fastapi[standard-no-fastapi-cloud-cli]>=0.121.0
28
- Requires-Dist: granian[pname]>=2.5.7
27
+ Requires-Dist: fastapi[standard-no-fastapi-cloud-cli]>=0.121.2
28
+ Requires-Dist: granian[pname]>=2.6.0
29
29
  Requires-Dist: httpx[http2]>=0.28.1
30
30
  Requires-Dist: itsdangerous>=2.2.0
31
31
  Requires-Dist: loguru>=0.7.3
32
32
  Requires-Dist: pydantic[email]>=2.12.4
33
33
  Requires-Dist: pydantic-extra-types[pycountry]>=2.10.6
34
- Requires-Dist: pydantic-settings>=2.11.0
34
+ Requires-Dist: pydantic-settings>=2.12.0
35
35
  Requires-Dist: pyyaml>=6.0.3
36
36
  Requires-Dist: redis[hiredis]>=7.0.1
37
37
  Requires-Dist: rich>=14.2.0
@@ -44,24 +44,24 @@ Requires-Dist: babel>=2.17.0 ; extra == 'dev'
44
44
  Requires-Dist: cloudflare>=4.3.1 ; extra == 'dev'
45
45
  Requires-Dist: djlint>=1.36.4 ; extra == 'dev'
46
46
  Requires-Dist: dunamai>=1.25.0 ; extra == 'dev'
47
- Requires-Dist: gh-bin>=2.81.0 ; extra == 'dev'
48
- Requires-Dist: granian[pname,reload]>=2.5.7 ; extra == 'dev'
47
+ Requires-Dist: gh-bin>=2.83.0 ; extra == 'dev'
48
+ Requires-Dist: granian[pname,reload]>=2.6.0 ; extra == 'dev'
49
49
  Requires-Dist: just-bin>=1.43.0 ; extra == 'dev'
50
- Requires-Dist: pre-commit>=4.3.0 ; extra == 'dev'
50
+ Requires-Dist: pre-commit>=4.4.0 ; extra == 'dev'
51
51
  Requires-Dist: pysemver>=0.5.0 ; extra == 'dev'
52
- Requires-Dist: ruff>=0.14.3 ; extra == 'dev'
53
- Requires-Dist: rumdl>=0.0.171 ; extra == 'dev'
52
+ Requires-Dist: ruff>=0.14.5 ; extra == 'dev'
53
+ Requires-Dist: rumdl>=0.0.177 ; extra == 'dev'
54
54
  Requires-Dist: semver>=3.0.4 ; extra == 'dev'
55
55
  Requires-Dist: taplo>=0.9.3 ; extra == 'dev'
56
- Requires-Dist: ty>=0.0.1a25 ; extra == 'dev'
56
+ Requires-Dist: ty>=0.0.1a26 ; extra == 'dev'
57
57
  Requires-Dist: types-aioboto3[s3,ses]>=15.5.0 ; extra == 'dev'
58
58
  Requires-Dist: types-authlib>=1.6.5.20251005 ; extra == 'dev'
59
59
  Requires-Dist: types-pyyaml>=6.0.12.20250915 ; extra == 'dev'
60
60
  Requires-Dist: uv-bump>=0.3.1 ; extra == 'dev'
61
61
  Requires-Python: >=3.11
62
62
  Project-URL: Changelog, https://github.com/alltuner/vibetuner/blob/main/CHANGELOG.md
63
- Project-URL: Documentation, https://github.com/alltuner/vibetuner#readme
64
- Project-URL: Homepage, https://github.com/alltuner/vibetuner
63
+ Project-URL: Documentation, https://vibetuner.alltuner.com/
64
+ Project-URL: Homepage, https://vibetuner.alltuner.com/
65
65
  Project-URL: Issues, https://github.com/alltuner/vibetuner/issues
66
66
  Project-URL: Repository, https://github.com/alltuner/vibetuner
67
67
  Provides-Extra: dev
@@ -69,13 +69,16 @@ Description-Content-Type: text/markdown
69
69
 
70
70
  # vibetuner
71
71
 
72
- **Core Python framework and blessed dependencies for Vibetuner projects**
72
+ Core Python framework and blessed dependencies for Vibetuner projects
73
73
 
74
- This package provides the complete Python framework and curated dependency set for building modern web applications with Vibetuner. It includes everything from FastAPI and MongoDB integration to authentication, background jobs, and CLI tools.
74
+ This package provides the complete Python framework and curated dependency set for building modern
75
+ web applications with Vibetuner. It includes everything from FastAPI and MongoDB integration to
76
+ authentication, background jobs, and CLI tools.
75
77
 
76
78
  ## What is Vibetuner?
77
79
 
78
- Vibetuner is a production-ready scaffolding tool for FastAPI + MongoDB + HTMX web applications. This package (`vibetuner`) is the Python component that provides:
80
+ Vibetuner is a production-ready scaffolding tool for FastAPI + MongoDB + HTMX web applications.
81
+ This package (`vibetuner`) is the Python component that provides:
79
82
 
80
83
  - Complete web application framework built on FastAPI
81
84
  - MongoDB integration with Beanie ODM
@@ -84,7 +87,8 @@ Vibetuner is a production-ready scaffolding tool for FastAPI + MongoDB + HTMX we
84
87
  - CLI framework with Typer
85
88
  - Email services, blob storage, and more
86
89
 
87
- **This package is designed to be used within projects generated by the Vibetuner scaffolding tool.** For standalone use, you'll need to set up the project structure manually.
90
+ **This package is designed to be used within projects generated by the Vibetuner scaffolding
91
+ tool.** For standalone use, you'll need to set up the project structure manually.
88
92
 
89
93
  ## Installation
90
94
 
@@ -172,7 +176,6 @@ vibetuner run prod worker
172
176
  The `[dev]` extra includes all tools needed for development:
173
177
 
174
178
  - **Ruff**: Fast linting and formatting
175
- - **djlint**: Template linting
176
179
  - **Babel**: i18n message extraction
177
180
  - **pre-commit**: Git hooks
178
181
  - **Type stubs**: For aioboto3, authlib, PyYAML
@@ -205,7 +208,7 @@ async def hello():
205
208
 
206
209
  For complete documentation, guides, and examples, see the main Vibetuner repository:
207
210
 
208
- **📖 [Vibetuner Documentation](https://github.com/alltuner/vibetuner#readme)**
211
+ **📖 [Vibetuner Documentation](https://vibetuner.alltuner.com/)**
209
212
 
210
213
  ## Package Ecosystem
211
214
 
@@ -232,7 +235,7 @@ See [LICENSE](https://github.com/alltuner/vibetuner/blob/main/LICENSE) for detai
232
235
  ## Links
233
236
 
234
237
  - **Main Repository**: <https://github.com/alltuner/vibetuner>
235
- - **Documentation**: <https://github.com/alltuner/vibetuner#readme>
238
+ - **Documentation**: <https://vibetuner.alltuner.com/>
236
239
  - **Issues**: <https://github.com/alltuner/vibetuner/issues>
237
240
  - **PyPI**: <https://pypi.org/project/vibetuner/>
238
241
  - **npm Package**: <https://www.npmjs.com/package/@alltuner/vibetuner>
@@ -0,0 +1,71 @@
1
+ vibetuner/__init__.py,sha256=rFIVCmxkKTT_g477V8biCw0lgpudyuUabXhYxg189lY,90
2
+ vibetuner/__main__.py,sha256=Ye9oBAgXhcYQ4I4yZli3TIXF5lWQ9yY4tTPs4XnDDUY,29
3
+ vibetuner/cli/__init__.py,sha256=9FFy0MTOhWVS-Z310auNTcpbG1xJtku0TS35Qxoyt-Q,3995
4
+ vibetuner/cli/run.py,sha256=TILyvy-bZTKWcAK-K2SNYqqD-G3ypCay-ghadGztqRQ,5021
5
+ vibetuner/cli/scaffold.py,sha256=qADWxx1gYECQ8N6dgvJmlucT6mZ29rxWu3VZhbWmhC0,5710
6
+ vibetuner/config.py,sha256=oG5naa6pu8wM4hzra0xaRQCPnQWbid9hGTJOHfsmHeI,4082
7
+ vibetuner/context.py,sha256=h4f4FfkmLlOD6WiSLhx7-IjFvIA4zcrsAp6478l6npg,743
8
+ vibetuner/frontend/__init__.py,sha256=DIAnvQHCFNBc5VtBXYE6IdAnIqCYTD_EyFAbmui7vW8,3927
9
+ vibetuner/frontend/deps.py,sha256=b3ocC_ryaK2Jp51SfcFqckrXiaL7V-chkFRqLjzgA_c,1296
10
+ vibetuner/frontend/email.py,sha256=k0d7FCZCge5VYOKp3fLsbx7EA5_SrtBkpMs57o4W7u0,1119
11
+ vibetuner/frontend/hotreload.py,sha256=Gl7FIKJaiCVVoyWQqdErBUOKDP1cGBFUpGzqHMiJd10,285
12
+ vibetuner/frontend/lifespan.py,sha256=ZduSyH6E2_IW9vFWH5jww2R22mRybSm_mNfbtDHnsS0,1074
13
+ vibetuner/frontend/middleware.py,sha256=iOqcp-7WwRqHLYa1dg3xDzAXGrpqmYpqBmtQcdd9obY,4890
14
+ vibetuner/frontend/oauth.py,sha256=EzEwoOZ_8xn_CiqAWpNoEdhV2NPxZKKwF2bA6W6Bkj0,5884
15
+ vibetuner/frontend/routes/__init__.py,sha256=nHhiylHIUPZ2R-Bd7vXEGHLJBQ7fNuzPTJodjJR3lyc,428
16
+ vibetuner/frontend/routes/auth.py,sha256=vKE-Dm2yPXReaOLvcxfT4a6df1dKUoteZ4p46v8Elm4,4331
17
+ vibetuner/frontend/routes/debug.py,sha256=Mzbyx3gv_mCxg0sdjY4p7LXgH1wI3BoEyn1sRZuGY90,12743
18
+ vibetuner/frontend/routes/health.py,sha256=_XkMpdMNUemu7qzkGkqn5TBnZmGrArA3Xps5CWCcGlg,959
19
+ vibetuner/frontend/routes/language.py,sha256=wHNfdewqWfK-2JLXwglu0Q0b_e00HFGd0A2-PYT44LE,1240
20
+ vibetuner/frontend/routes/meta.py,sha256=pSyIxQsiB0QZSYwCQbS07KhkT5oHC5r9jvjUDIqZRGw,1409
21
+ vibetuner/frontend/routes/user.py,sha256=b8ow6IGnfsHosSwSmEIYZtuQJnW_tacnNjp_aMnqWxU,2666
22
+ vibetuner/frontend/templates.py,sha256=xHpLMyAEjKWHgbloE40n6Fe3gjTuG5msWeqqYyJO3uU,5308
23
+ vibetuner/logging.py,sha256=9eNofqVtKZCBDS33NbBI7Sv2875gM8MNStTSCjX2AXQ,2409
24
+ vibetuner/models/__init__.py,sha256=JvmQvzDIxaI7zlk-ROCWEbuzxXSUOqCshINUjgu-AfQ,325
25
+ vibetuner/models/blob.py,sha256=F30HFS4Z_Bji_PGPflWIv4dOwqKLsEWQHcjW1Oz_79M,2523
26
+ vibetuner/models/email_verification.py,sha256=iwDnbPhceugY6vQZwyp0AKCEID61NbAxqA7tdQKHHAI,2488
27
+ vibetuner/models/mixins.py,sha256=934aAcdos_SlDMyiARBV8dhhClgtaVpf0O7OJf4d6YQ,3053
28
+ vibetuner/models/oauth.py,sha256=BdOZbW47Das9ntHTtRmVdl1lB5zLCcXW2fyVJ-tQ_F8,1509
29
+ vibetuner/models/registry.py,sha256=O5YG7vOrWluqpH5N7m44v72wbscMhU_Pu3TJw_u0MTk,311
30
+ vibetuner/models/types.py,sha256=Lj3ASEvx5eNgQMcVhNyKQHHolJqDxj2yH8S-M9oa4J8,402
31
+ vibetuner/models/user.py,sha256=ttcSH4mVREPhA6bCFUWXKfJ9_8_Iq3lEYXe3rDrslw4,2696
32
+ vibetuner/mongo.py,sha256=BejYrqHrupNfvNhEu6xUakCnRQy3YdiExk2r6hkafOs,1056
33
+ vibetuner/paths.py,sha256=IEH_GCJTThUPU0HWxr86j61IcwYgwXBamoWNmaJsxlo,8252
34
+ vibetuner/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
+ vibetuner/services/blob.py,sha256=-lEGIWe30yR2IuTfy5bB9Sg_PX0HoYC_WMTQ3VN28gU,5660
36
+ vibetuner/services/email.py,sha256=IavJZS5MI40LlF_cjBpPPRx_S2r1JD4GcFg3-dWkzPA,1626
37
+ vibetuner/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ vibetuner/tasks/lifespan.py,sha256=BKOI-wbMLOqEbR4NgCKI5c9OP8W1RpxOswBL3XzPTWc,861
39
+ vibetuner/tasks/worker.py,sha256=s91Pbmz--cV4ygzDuXa-kGLZFe28HSvaXfxhIWJyIhE,340
40
+ vibetuner/templates/email/magic_link.html.jinja,sha256=DzaCnBsYoau2JQh5enPAa2FMFFTyCwdyiM3vGhBQdtA,553
41
+ vibetuner/templates/email/magic_link.txt.jinja,sha256=dANak9ion1cpILt45V3GcI2qnL_gKFPj7PsZKYV0m5s,200
42
+ vibetuner/templates/frontend/base/favicons.html.jinja,sha256=A7s7YXuE82tRd7ZLJs1jGEGwBRiMPrqlWd507xL1iZg,70
43
+ vibetuner/templates/frontend/base/footer.html.jinja,sha256=P5EKssUk-HHz0yFE3auj1WtSqsJxAzi39XbRxjBtLLg,165
44
+ vibetuner/templates/frontend/base/header.html.jinja,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ vibetuner/templates/frontend/base/opengraph.html.jinja,sha256=wjmLAE3C4OZqxPhPCce1kD3XDN-BZgp3v0GwlToUoBc,419
46
+ vibetuner/templates/frontend/base/skeleton.html.jinja,sha256=uOEUt577Mfv83nLOKLPKvBJHh8PG6w7YwDYv1GVwnaQ,1698
47
+ vibetuner/templates/frontend/debug/collections.html.jinja,sha256=LogTicEMSzy-sYrHQ8Kjqf_6Il9Cv5cRElMgivcJC2U,7094
48
+ vibetuner/templates/frontend/debug/components/debug_nav.html.jinja,sha256=SntW7esMV6TDkIHcoevZX7j-fCv3h6pblOJ--_-5fUI,2963
49
+ vibetuner/templates/frontend/debug/index.html.jinja,sha256=qheuA53UYGBBeVvsNL8APJ2Y7FxjL3g8LWafY2U1MSA,4892
50
+ vibetuner/templates/frontend/debug/info.html.jinja,sha256=Z9yZxW-dyOZ1kWsY1_ZX7jvPQ4IaM9hJMVD6Sk8QxgA,14968
51
+ vibetuner/templates/frontend/debug/users.html.jinja,sha256=BjTiJbOMadZYZJYvtYW0KeFcYN7ooI7_YylhOnfbLD4,7809
52
+ vibetuner/templates/frontend/debug/version.html.jinja,sha256=pJ-QuDRuvB7X04nC43upZiXLaFCC6vmI5QhRS62rt6k,2901
53
+ vibetuner/templates/frontend/email/magic_link.txt.jinja,sha256=fTVl3Wjfvp3EJAB5DYt01EL_O7o9r8lHedDH05YP44c,192
54
+ vibetuner/templates/frontend/email_sent.html.jinja,sha256=Pq3J_WOwY_zFe9QJkvO29o6pw06JEnYxh068kyl_ZEg,5236
55
+ vibetuner/templates/frontend/index.html.jinja,sha256=m8_xNS1O7JlrfWOHy0y7prf64HyVokQEeKvFqRWjxrQ,925
56
+ vibetuner/templates/frontend/lang/select.html.jinja,sha256=4jHo8QWvMOIeK_KqHzSaDzgvuT3v8MlmjTrrYIl2sjk,224
57
+ vibetuner/templates/frontend/login.html.jinja,sha256=Y_dKk47-H6M8StepiFXntJcorBNXiOXKjORJN--SjOA,5548
58
+ vibetuner/templates/frontend/meta/browserconfig.xml.jinja,sha256=5DE-Dowxw3fRg4UJerW6tVrUYdHWUsUOfS_YucoRVXQ,300
59
+ vibetuner/templates/frontend/meta/robots.txt.jinja,sha256=SUBJqQCOW5FFdD4uIkReo04NcAYnjITLyB4Wk1wBcS4,46
60
+ vibetuner/templates/frontend/meta/site.webmanifest.jinja,sha256=QCg2Z2GXd2AwJ3C8CnW9Brvu3cbXcZiquLNEzA8FsOc,150
61
+ vibetuner/templates/frontend/meta/sitemap.xml.jinja,sha256=IhBjk7p5OdqszyK6DR3eUAdeAucKk2s_PpnOfYxgNCo,170
62
+ vibetuner/templates/frontend/user/edit.html.jinja,sha256=dhmLFsokTWbtnmIE10S8gC6rDHToC6vNIUB2BRximKQ,5443
63
+ vibetuner/templates/frontend/user/profile.html.jinja,sha256=qXFonyeCy99JE5o3rEtaOHtnxgg2-AlNykwIZyxpk_M,9964
64
+ vibetuner/templates/markdown/.placeholder,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
+ vibetuner/templates.py,sha256=xRoMb_oyAI5x4kxfpg56UcLKkT8e9HVn-o3KFAu9ISE,5094
66
+ vibetuner/time.py,sha256=3_DtveCCzI20ocTnAlTh2u7FByUXtINaUoQZO-_uZow,1188
67
+ vibetuner/versioning.py,sha256=c7Wg-SM-oJzQqG2RE0O8gZGHzHTgvwqa4yHn3Dk5-Sk,372
68
+ vibetuner-2.26.9.dist-info/WHEEL,sha256=w4ZtLaDgMAZW2MMZZwtH8zENekoQYBCeullI-zsXJQk,78
69
+ vibetuner-2.26.9.dist-info/entry_points.txt,sha256=aKIj9YCCXizjYupx9PeWkUJePg3ncHke_LTS5rmCsfs,49
70
+ vibetuner-2.26.9.dist-info/METADATA,sha256=WTPJkk2ZcYPzpzcWRdWDAnEgXcdjOBD3EgWo_ilp0sQ,8061
71
+ vibetuner-2.26.9.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.7
2
+ Generator: uv 0.9.9
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,113 +0,0 @@
1
- # Core Frontend Module
2
-
3
- **IMMUTABLE SCAFFOLDING CODE** - This is the framework's core frontend infrastructure.
4
-
5
- ## What's Here
6
-
7
- This module contains the scaffolding's core frontend components:
8
-
9
- - **routes/** - Essential default routes (auth, health, debug, language, user, meta)
10
- - **templates.py** - Template rendering with automatic context injection
11
- - **deps.py** - FastAPI dependencies (authentication, language, etc.)
12
- - **middleware.py** - Request/response middleware
13
- - **oauth.py** - OAuth provider integration
14
- - **email.py** - Magic link email authentication
15
- - **lifespan.py** - Application startup/shutdown lifecycle
16
- - **context.py** - Request context management
17
- - **hotreload.py** - Development hot-reload support
18
-
19
- ## Important Rules
20
-
21
- ⚠️ **DO NOT MODIFY** these core frontend components directly.
22
-
23
- **For changes to core frontend:**
24
-
25
- - File an issue at `https://github.com/alltuner/scaffolding`
26
- - Core changes benefit all projects using the scaffolding
27
-
28
- **For your application routes:**
29
-
30
- - Create them in `src/app/frontend/routes/` instead
31
- - Import core components when needed:
32
- - `from vibetuner.frontend.deps import get_current_user`
33
- - `from vibetuner.frontend.templates import render_template`
34
-
35
- ## User Route Pattern (for reference)
36
-
37
- Your application routes in `src/app/frontend/routes/` should follow this pattern:
38
-
39
- ```python
40
- # src/app/frontend/routes/dashboard.py
41
- from fastapi import APIRouter, Request, Depends
42
- from vibetuner.frontend.deps import get_current_user
43
- from vibetuner.frontend.templates import render_template
44
-
45
- router = APIRouter()
46
-
47
- @router.get("/dashboard")
48
- async def dashboard(request: Request, user=Depends(get_current_user)):
49
- return render_template("dashboard.html.jinja", request, {"user": user})
50
- ```
51
-
52
- ## Template Rendering
53
-
54
- ```python
55
- # Automatic context in every template:
56
- {
57
- "request": request,
58
- "DEBUG": settings.DEBUG,
59
- "hotreload": hotreload, # Dev mode
60
- # ... plus your custom context
61
- }
62
- ```
63
-
64
- ### Template Filters
65
-
66
- - `{{ datetime | timeago }}` - "2 hours ago"
67
- - `{{ datetime | format_date }}` - "January 15, 2024"
68
- - `{{ text | markdown }}` - Convert Markdown to HTML
69
-
70
- ## Core Dependencies Available
71
-
72
- Import these from `vibetuner.frontend.deps`:
73
-
74
- - `get_current_user` - Require authenticated user (raises 403 if not authenticated)
75
- - `get_current_user_optional` - Optional auth check (returns None if not authenticated)
76
- - `LangDep` - Current language from cookie/header
77
- - `MagicCookieDep` - Magic link cookie for authentication
78
-
79
- ## HTMX Patterns
80
-
81
- ```html
82
- <!-- Partial updates -->
83
- <button hx-post="/api/action" hx-target="#result">Click</button>
84
-
85
- <!-- Form submission -->
86
- <form hx-post="/submit" hx-swap="outerHTML">...</form>
87
-
88
- <!-- Polling -->
89
- <div hx-get="/status" hx-trigger="every 2s">...</div>
90
- ```
91
-
92
- ## Default Routes Provided
93
-
94
- The following routes are automatically available (DO NOT MODIFY):
95
-
96
- - **/auth/*** - OAuth and magic link authentication
97
- - **/health/ping** - Health check endpoint
98
- - **/debug/** - Debug info (only in DEBUG mode)
99
- - **/lang/** - Language selection
100
- - **/user/** - User profile routes
101
- - **/meta/** - Metadata endpoints
102
-
103
- ## Development
104
-
105
- **CRITICAL**: Both processes required:
106
-
107
- ```bash
108
- # Terminal 1: Frontend assets
109
- bun dev
110
-
111
- # Terminal 2: Backend server
112
- just local-dev
113
- ```
@@ -1,113 +0,0 @@
1
- # Core Frontend Module
2
-
3
- **IMMUTABLE SCAFFOLDING CODE** - This is the framework's core frontend infrastructure.
4
-
5
- ## What's Here
6
-
7
- This module contains the scaffolding's core frontend components:
8
-
9
- - **routes/** - Essential default routes (auth, health, debug, language, user, meta)
10
- - **templates.py** - Template rendering with automatic context injection
11
- - **deps.py** - FastAPI dependencies (authentication, language, etc.)
12
- - **middleware.py** - Request/response middleware
13
- - **oauth.py** - OAuth provider integration
14
- - **email.py** - Magic link email authentication
15
- - **lifespan.py** - Application startup/shutdown lifecycle
16
- - **context.py** - Request context management
17
- - **hotreload.py** - Development hot-reload support
18
-
19
- ## Important Rules
20
-
21
- ⚠️ **DO NOT MODIFY** these core frontend components directly.
22
-
23
- **For changes to core frontend:**
24
-
25
- - File an issue at `https://github.com/alltuner/scaffolding`
26
- - Core changes benefit all projects using the scaffolding
27
-
28
- **For your application routes:**
29
-
30
- - Create them in `src/app/frontend/routes/` instead
31
- - Import core components when needed:
32
- - `from vibetuner.frontend.deps import get_current_user`
33
- - `from vibetuner.frontend.templates import render_template`
34
-
35
- ## User Route Pattern (for reference)
36
-
37
- Your application routes in `src/app/frontend/routes/` should follow this pattern:
38
-
39
- ```python
40
- # src/app/frontend/routes/dashboard.py
41
- from fastapi import APIRouter, Request, Depends
42
- from vibetuner.frontend.deps import get_current_user
43
- from vibetuner.frontend.templates import render_template
44
-
45
- router = APIRouter()
46
-
47
- @router.get("/dashboard")
48
- async def dashboard(request: Request, user=Depends(get_current_user)):
49
- return render_template("dashboard.html.jinja", request, {"user": user})
50
- ```
51
-
52
- ## Template Rendering
53
-
54
- ```python
55
- # Automatic context in every template:
56
- {
57
- "request": request,
58
- "DEBUG": settings.DEBUG,
59
- "hotreload": hotreload, # Dev mode
60
- # ... plus your custom context
61
- }
62
- ```
63
-
64
- ### Template Filters
65
-
66
- - `{{ datetime | timeago }}` - "2 hours ago"
67
- - `{{ datetime | format_date }}` - "January 15, 2024"
68
- - `{{ text | markdown }}` - Convert Markdown to HTML
69
-
70
- ## Core Dependencies Available
71
-
72
- Import these from `vibetuner.frontend.deps`:
73
-
74
- - `get_current_user` - Require authenticated user (raises 403 if not authenticated)
75
- - `get_current_user_optional` - Optional auth check (returns None if not authenticated)
76
- - `LangDep` - Current language from cookie/header
77
- - `MagicCookieDep` - Magic link cookie for authentication
78
-
79
- ## HTMX Patterns
80
-
81
- ```html
82
- <!-- Partial updates -->
83
- <button hx-post="/api/action" hx-target="#result">Click</button>
84
-
85
- <!-- Form submission -->
86
- <form hx-post="/submit" hx-swap="outerHTML">...</form>
87
-
88
- <!-- Polling -->
89
- <div hx-get="/status" hx-trigger="every 2s">...</div>
90
- ```
91
-
92
- ## Default Routes Provided
93
-
94
- The following routes are automatically available (DO NOT MODIFY):
95
-
96
- - **/auth/*** - OAuth and magic link authentication
97
- - **/health/ping** - Health check endpoint
98
- - **/debug/** - Debug info (only in DEBUG mode)
99
- - **/lang/** - Language selection
100
- - **/user/** - User profile routes
101
- - **/meta/** - Metadata endpoints
102
-
103
- ## Development
104
-
105
- **CRITICAL**: Both processes required:
106
-
107
- ```bash
108
- # Terminal 1: Frontend assets
109
- bun dev
110
-
111
- # Terminal 2: Backend server
112
- just local-dev
113
- ```
@@ -1,10 +0,0 @@
1
- from vibetuner.context import Context
2
-
3
-
4
- class AppContext(Context):
5
- # Add typed state here
6
-
7
- model_config = {"arbitrary_types_allowed": True}
8
-
9
-
10
- ctx = AppContext()