stkit 17.3.0__tar.gz → 17.3.1__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.
- {stkit-17.3.0 → stkit-17.3.1}/CHANGELOG.md +7 -0
- {stkit-17.3.0 → stkit-17.3.1}/PKG-INFO +1 -1
- {stkit-17.3.0 → stkit-17.3.1}/pyproject.toml +1 -1
- {stkit-17.3.0 → stkit-17.3.1}/stk/__init__.py +1 -1
- {stkit-17.3.0 → stkit-17.3.1}/stk/app.py +10 -5
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/copy_rules.py +2 -1
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_copy_rules.py +6 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_static_versioning.py +15 -0
- {stkit-17.3.0 → stkit-17.3.1}/.gitignore +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/LICENSE +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/README.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/SECURITY.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/.env-sample +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/.gitignore +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/README.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/minimal/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/minimal/app.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/minimal/migrations/364232ae77d5_add_note.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/minimal/note/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/minimal/note/models.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/minimal/note/templates/note/index.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/minimal/note/views.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/minimal/settings.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/minimal/templates/layout.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/pyproject.toml +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/tests/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/tests/test_app.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/examples/minimal/uv.lock +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/__main__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/agent_login.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/checks.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/agent.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/base.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/database.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/develop.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/doctor.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/main.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/reports.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/smoke.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/users.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/cli/watch.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/extensions.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/files/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/files/models.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/files/store.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/files/views.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/mcp/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/mcp/models.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/mcp/server.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/mcp/views.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/env.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/script.py.mako +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/versions/stk_0001_initial_schema.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/versions/stk_0002_jobs.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/versions/stk_0003_files.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/versions/stk_0004_notifications.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/versions/stk_0005_mcp_tokens.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/versions/stk_0006_stk_mcp_token.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/migrations/versions/stk_0007_confirm_existing_users.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/notification/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/notification/models.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/notification/views.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/portal/views.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/public/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/public/models.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/public/views.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/CLAUDE.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/Dockerfile +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/README.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/__app__/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/__app__/app.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/__app__/settings.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/claude/skills/stk-api/SKILL.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/claude/skills/stk-blueprint/SKILL.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/claude/skills/stk-deploy/SKILL.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/claude/skills/stk-lessons/SKILL.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/claude/skills/stk-migrate/SKILL.md +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/docker-compose.yml +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/dockerignore +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/env-sample +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/github/workflows/checks.yml +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/gitignore +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/nginx/nginx.conf +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/nginx/stk.conf +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/postgres/init-db.sh +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/pyproject.toml +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/tests/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/app/tests/test_app.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/generator.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/scaffold/templates.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/security.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/settings.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/shell.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/VERSIONS.txt +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/css/app.css +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/css/layout.css +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/css/vuetify.min.css +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.animals.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.arrows-1.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.arrows-2.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.badges.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.brand-1.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.brand-2.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.buildings.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.charts.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.communication.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.computers.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.core.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.currencies.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.database.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.design-1.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.design-2.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.development.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.devices-1.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.devices-2.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.document.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.e-commerce.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.electrical.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.extensions.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.food.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.games.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.gender.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.gestures.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.health.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.laundry.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.letters.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.logic.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.map.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.math.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.media.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.mood.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.nature.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.numbers.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.photography.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.shapes.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.sport.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.symbols.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.system-1.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.system-2.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.system-3.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.text.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.vehicles.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.version-control.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.weather.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/fonts/tabler-icons.zodiac.woff2 +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/icons/tabler-icons.min.css +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/img/auth-bg.webp +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/img/favicon.ico +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/img/stk.svg +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/axios.min.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/components/NotificationDropdown.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/components/ThemeSwitcher.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/components/TransitionExpand.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/components/VerticalNavGroup.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/components/VerticalNavLink.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/components/VerticalNavSectionTitle.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/components/index.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/config.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/vue.min.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/js/vuetify.min.js +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/static/robots.txt +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/tasks/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/tasks/models.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/401.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/404.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/500.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/_brand.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/auth_layout.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/cms/activities.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/cms/jobs.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/cms/roles.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/cms/users.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/dashboard.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/index.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/layout.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/login-layout.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/mcp/tokens.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/_macros.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/_messages.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/change_password.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/confirm_email.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/change_notice.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/change_notice.txt +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/confirmation_instructions.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/confirmation_instructions.txt +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/login_instructions.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/login_instructions.txt +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/reset_instructions.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/reset_instructions.txt +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/reset_notice.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/reset_notice.txt +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/welcome.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/email/welcome.txt +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/forgot_password.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/login_user.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/mf_recovery.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/mf_recovery_codes.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/register_user.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/reset_password.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/send_confirmation.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/send_login.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/two_factor_select.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/two_factor_setup.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/two_factor_verify_code.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/wan_register.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/wan_signin.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/templates/security/wan_verify.html +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/user/__init__.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/user/forms.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/user/models.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/user/views.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/utils/email.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/utils/netguard.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/utils/ratelimit.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/stk/websocket.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_agent_operability.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_app_index.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_branding.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_builder_ux.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_cli.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_composition.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_confirm_migration.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_csrf_exempt.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_error_handler.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_files.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_jobs.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_mcp.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_mcp_migration.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_migration_drift.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_netguard.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_notifications.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_production_security.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_revision_imports.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_route_collisions.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_scaffolder.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_security_compatibility.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_shell.py +0 -0
- {stkit-17.3.0 → stkit-17.3.1}/tests/test_smoke_pages.py +0 -0
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v17.3.1 (2026-10-31)
|
|
4
|
+
|
|
5
|
+
No migration required.
|
|
6
|
+
|
|
7
|
+
- Versioned static responses were marked public and immutable for a year even when they were a 404 or carried a session cookie change, such as clearing a stale login. A shared cache could then replay them to other visitors. Only a 200 with no cookie change is cached publicly now; a response that changes the session is `private, no-store`.
|
|
8
|
+
- `stk smoke`'s raw-score rule could take tens of seconds on a page with a long run of blanks after the word "score", from two adjacent optional-blank patterns backtracking. It is linear now (Build Loop).
|
|
9
|
+
|
|
3
10
|
## v17.3.0 (2026-10-31)
|
|
4
11
|
|
|
5
12
|
Run `uv run stk db upgrade`: `stk_0007` marks every existing account confirmed. Requires quart-security 2.1.0.
|
|
@@ -18,6 +18,7 @@ from quart import (
|
|
|
18
18
|
send_from_directory,
|
|
19
19
|
url_for,
|
|
20
20
|
)
|
|
21
|
+
from quart import session as quart_session
|
|
21
22
|
from quart_security import Security, SQLAlchemyUserDatastore
|
|
22
23
|
from quart_security.views import _ensure_csrf_token
|
|
23
24
|
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
|
|
@@ -253,11 +254,15 @@ def register_static_versioning(app):
|
|
|
253
254
|
@app.after_request
|
|
254
255
|
async def _cache_static(response):
|
|
255
256
|
if request.path.startswith(f"{app.static_url_path}/"):
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
)
|
|
257
|
+
if quart_session.modified:
|
|
258
|
+
# This response sets or clears a session cookie; a shared cache
|
|
259
|
+
# must never replay it to someone else.
|
|
260
|
+
policy = "private, no-store"
|
|
261
|
+
elif request.args.get("v") and response.status_code == 200:
|
|
262
|
+
policy = "public, max-age=31536000, immutable"
|
|
263
|
+
else:
|
|
264
|
+
policy = "no-cache"
|
|
265
|
+
response.headers["Cache-Control"] = policy
|
|
261
266
|
return response
|
|
262
267
|
|
|
263
268
|
def import_map():
|
|
@@ -41,7 +41,8 @@ HEX = re.compile(r"[0-9a-f]{6,}", re.I)
|
|
|
41
41
|
HASH_LABEL = re.compile(r"(?:sha-?256|sha|md5|hash|digest|fingerprint)\W{0,3}$", re.I)
|
|
42
42
|
SNAKE = re.compile(r"(?<![\w./@-])[a-z][a-z0-9]*(?:_[a-z0-9]+)+(?![\w@-]|\.\w)")
|
|
43
43
|
SCORE = re.compile(
|
|
44
|
-
r"\b(?:score|similarity|confidence|distance|cosine)\b\s*[:=]
|
|
44
|
+
r"\b(?:score|similarity|confidence|distance|cosine)\b\s*(?:[:=]\s*)?-?\d*\.\d+",
|
|
45
|
+
re.I,
|
|
45
46
|
)
|
|
46
47
|
ONE = re.compile(r"(?<![\d.,:/-])\b1[ \t]+([A-Za-z]+s)\b")
|
|
47
48
|
# Words ending in s after a 1 that are not plurals: "1 is", "1 status".
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import time
|
|
1
2
|
import unittest
|
|
2
3
|
|
|
3
4
|
from stk.cli.copy_rules import (
|
|
@@ -49,6 +50,11 @@ class CopyRuleTests(unittest.TestCase):
|
|
|
49
50
|
["jane_doe@example.com", "/static/app_icon.png", "STK_ENV", "Pending"],
|
|
50
51
|
)
|
|
51
52
|
|
|
53
|
+
def test_raw_score_is_linear_on_long_blank_runs(self):
|
|
54
|
+
start = time.perf_counter()
|
|
55
|
+
self.assertEqual(raw_score("score" + " " * 50_000 + "!"), [])
|
|
56
|
+
self.assertLess(time.perf_counter() - start, 1)
|
|
57
|
+
|
|
52
58
|
def test_raw_score(self):
|
|
53
59
|
self.assertRule(
|
|
54
60
|
raw_score,
|
|
@@ -22,6 +22,21 @@ class StaticVersioningTests(unittest.IsolatedAsyncioTestCase):
|
|
|
22
22
|
bare = await client.get("/static/js/config.js")
|
|
23
23
|
self.assertEqual(bare.headers["Cache-Control"], "no-cache")
|
|
24
24
|
|
|
25
|
+
async def test_errors_and_session_cookies_are_never_cached_publicly(self):
|
|
26
|
+
app = Stk(__name__, config=TestingConfig)
|
|
27
|
+
client = app.test_client()
|
|
28
|
+
missing = await client.get("/static/missing.css?v=1")
|
|
29
|
+
self.assertEqual(missing.status_code, 404)
|
|
30
|
+
self.assertNotIn("public", missing.headers["Cache-Control"])
|
|
31
|
+
# A stale login is cleared on any request, static ones included; that
|
|
32
|
+
# response carries a cookie change and must stay private.
|
|
33
|
+
async with client.session_transaction() as cookie:
|
|
34
|
+
cookie["_user_id"] = "gone"
|
|
35
|
+
async with app.test_request_context("/"):
|
|
36
|
+
url = url_for("static", filename="js/config.js")
|
|
37
|
+
cleared = await client.get(url)
|
|
38
|
+
self.assertEqual(cleared.headers["Cache-Control"], "private, no-store")
|
|
39
|
+
|
|
25
40
|
|
|
26
41
|
if __name__ == "__main__":
|
|
27
42
|
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|