z4j-brain 1.0.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.
- z4j_brain-1.0.0/.github/CODEOWNERS +2 -0
- z4j_brain-1.0.0/.github/ISSUE_TEMPLATE/bug_report.yml +74 -0
- z4j_brain-1.0.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- z4j_brain-1.0.0/.github/ISSUE_TEMPLATE/feature_request.yml +33 -0
- z4j_brain-1.0.0/.github/dependabot.yml +35 -0
- z4j_brain-1.0.0/.github/workflows/ci.yml +109 -0
- z4j_brain-1.0.0/.github/workflows/release.yml +65 -0
- z4j_brain-1.0.0/.gitignore +100 -0
- z4j_brain-1.0.0/CHANGELOG.md +52 -0
- z4j_brain-1.0.0/LICENSE +662 -0
- z4j_brain-1.0.0/PKG-INFO +216 -0
- z4j_brain-1.0.0/README.md +151 -0
- z4j_brain-1.0.0/SECURITY.md +37 -0
- z4j_brain-1.0.0/backend/Dockerfile +431 -0
- z4j_brain-1.0.0/backend/alembic.ini +58 -0
- z4j_brain-1.0.0/backend/pytest.ini +6 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/__init__.py +13 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/alembic.ini +58 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/__init__.py +47 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/_export.py +203 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/_pagination.py +92 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/agent_longpoll.py +538 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/agents.py +286 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/api_keys.py +394 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/audit.py +273 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/auth.py +993 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/commands.py +883 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/deps.py +639 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/events.py +119 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/health.py +134 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/home.py +741 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/invitations.py +607 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/memberships.py +388 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/metrics.py +257 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/notifications.py +691 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/projects.py +347 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/queues.py +80 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/schedules.py +400 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/setup.py +570 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/stats.py +333 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/tasks.py +719 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/trends.py +231 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/user_notifications.py +735 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/users.py +464 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/api/workers.py +171 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/auth/__init__.py +20 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/auth/common_passwords.py +178 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/auth/csrf.py +97 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/auth/ip.py +115 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/auth/passwords.py +193 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/auth/scopes.py +223 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/auth/sessions.py +241 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/cli.py +448 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/Combination-Mbn7Inc3.js +41 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated-yHuswt-u.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.home-C6L1f7oW.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug-Ty5E18hS.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.agents-D53LTI3M.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.audit-2lQmR7ZZ.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.commands-PxDs5ITy.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.index-C31o3VnO.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.queues-hO0iEz_F.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.schedules-DQlFv65Z.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.settings-CuF-h8Wg.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.settings.defaults-B9N75VlR.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.settings.deliveries-DOlRHRDF.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.settings.members-Cfpkhf2u.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.settings.providers-CHHPZAvX.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.tasks-Bkh9pQcc.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.tasks_._engine._taskId-BivceoBq.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.trends-DbwuYHX3.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.workers-C9shlGeT.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.projects._slug.workers_._workerId-CuET-FyJ.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings-DbzH1raW.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.account-hXGcb4G8.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.api-keys-m27esXGg.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.appearance-DjeVPc6x.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.channels-C2g7F2no.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.general-Cu9H13pp.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.memberships-D_4vtjrR.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.notifications-o9GjAUv3.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.projects-BHIndW4l.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.system-DX0Fh-0R.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/_authenticated.settings.users-D1eZ8ibl.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/activity-BWh012OF.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/arrow-left-BQQHqTKK.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/badge-1j2s04og.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/ban-DIC2HEN9.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/bell-CRhLWKvr.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/bell-off-B5p802U-.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/bell-ring-CPe5h8Ku.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/button-BTErSQWc.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/card-Bv2SixwD.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/chart-line-DUksAY_V.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/check-KyJs9yL_.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/checkbox-y5MQTcA1.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/chevron-right-CfZeHkjR.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/circle-alert-MLD0sCYw.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/circle-check-BBd2PIQM.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/clipboard-list-k-q09MYK.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/clock-DE6XxV0F.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/confirm-dialog-C07Qqqbn.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/copy-BOUMVSG8.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/cpu-BYUVSiY2.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/createLucideIcon-DMx1LJYK.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/data-table-DlojG8e5.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/date-cell-DHba2_Oe.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dialog-Cx-4p_Yo.js +5 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-BGEifFXA.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-BrvYKv70.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-C-pkwDHM.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-CEpZKEqE.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-CZ2DFBPl.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-Cj-DySzz.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-D5rSZoAz.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-DCDLaPGw.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-DgZbGCjW.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-DqDGPSW2.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dist-XehZhxsQ.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/download-Cd7lHtRp.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/dropdown-menu-D61NiM2D.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/empty-state-iSniN1fx.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/folder-kanban-BvyPZ6TV.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/format-sTEWtB1U.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/globe-2kMh7aNV.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/history-BzDOTslU.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/house-DSjqTu7G.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/index-Dkgj55uS.js +2 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/index-DsLIXgQk.css +2 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/input-DTTuBPwW.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/invite-8R2TwZtt.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/key-round-BvQlr9t6.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/label-i9g5JZcB.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/layers-Db7WFPz6.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/layout-dashboard-Brz1rkc5.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/loader-circle-CY0EO3r2.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/lock-DdOVKkrO.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/login-riDNMVEd.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/minus-DLTC1Z6P.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/network-Bn-xtMtm.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/page-header-BK0fJmaX.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/pencil-CoBVgdI1.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/plus-CuumkKre.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/preload-helper-rov5CBGT.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/query-D2jtzWuf.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/query-error-Dx_SoLpY.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/react-D60AwLVq.js +9 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/refresh-cw-42j0uDGE.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/role-badge-CFUIUWM1.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/rolldown-runtime-jpDsebLB.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/router-BmO-cTww.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/search-BKIEIPhL.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/select-BMBPT_z2.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/send-D-i0jr8o.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/separator-BRRZn_PK.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/settings-2-BW2184fT.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/settings-BHI-ZKHx.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/shield-B2W0vByS.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/skeleton-B0mfFEvh.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/state-badges-DF0X2ROb.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/sun-DPP3Wzf0.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/switch-DynNVPid.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/table-DPppdgl5.js +4 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/table-Q4i-YGKF.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/tabs-4pdsDhyo.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/terminal-4MUsW_Os.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/trash-2-4-xl3681.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/triangle-alert-C_8O7qKh.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/use-agents-DsCCNl4n.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/use-auth-f7A065vm.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/use-commands-C8RYsnlq.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/use-invitations-B4lhwJb8.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/use-memberships-DykHguXI.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/use-notifications-Dz3B4u2h.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/use-projects-BhvPIet_.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/use-tasks-CdsG9K2r.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/use-workers-B9jUfcm-.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/users-BA_Xd4QW.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/webhook-CBO05TrQ.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/assets/x-CIwKBEbE.js +1 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/favicon.svg +14 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/index.html +44 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/logos/logo-dark.svg +16 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/dashboard/dist/logos/logo-light.svg +16 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/__init__.py +37 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/audit_service.py +343 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/auth_service.py +400 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/command_dispatcher.py +416 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/event_ingestor.py +701 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/ip_rate_limit.py +163 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/notifications/__init__.py +11 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/notifications/channels.py +957 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/notifications/service.py +673 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/policy_engine.py +132 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/setup_service.py +449 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/workers/__init__.py +29 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/workers/agent_health.py +54 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/workers/agent_hygiene.py +72 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/workers/command_timeout.py +41 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/workers/partition_creator.py +127 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/workers/reconciliation.py +190 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/domain/workers/supervisor.py +123 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/errors.py +84 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/logging_config.py +105 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/main.py +565 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/middleware/__init__.py +24 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/middleware/body_size.py +126 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/middleware/errors.py +143 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/middleware/host_validation.py +92 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/middleware/real_client_ip.py +49 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/middleware/request_id.py +80 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/middleware/security_headers.py +164 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/migrations/__init__.py +5 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/migrations/env.py +99 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/migrations/script.py.mako +26 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/migrations/versions/.gitkeep +0 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/migrations/versions/2026_04_15_0001-initial_schema.py +632 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/migrations/versions/2026_04_15_0002-invitation_acceptance.py +110 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/migrations/versions/2026_04_15_0003-password_reset_tokens.py +87 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/__init__.py +27 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/base.py +38 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/database.py +120 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/enums.py +46 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/__init__.py +82 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/_mixins.py +68 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/agent.py +114 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/alert_event.py +58 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/api_key.py +95 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/audit_log.py +138 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/command.py +129 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/event.py +127 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/export_job.py +53 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/feature_flag.py +30 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/first_boot_token.py +45 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/invitation.py +113 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/kv_store.py +123 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/membership.py +69 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/meta.py +33 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/notification.py +489 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/password_reset_token.py +64 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/project.py +81 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/queue.py +73 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/saved_view.py +46 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/schedule.py +127 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/session.py +122 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/task.py +155 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/task_annotation.py +46 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/user.py +119 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/models/worker.py +111 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/__init__.py +73 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/_base.py +101 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/agents.py +193 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/api_keys.py +129 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/audit_log.py +145 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/commands.py +192 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/events.py +139 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/first_boot_tokens.py +88 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/invitations.py +101 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/memberships.py +134 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/notifications.py +698 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/projects.py +84 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/queues.py +123 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/schedules.py +138 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/sessions.py +122 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/tasks.py +455 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/users.py +309 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/repositories/workers.py +190 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/statement_timeout.py +72 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/persistence/types.py +106 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/py.typed +0 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/settings.py +518 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/startup.py +265 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/startup_version.py +123 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/__init__.py +19 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/auth.py +65 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/dashboard_gateway.py +288 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/dashboard_hub/__init__.py +41 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/dashboard_hub/_protocol.py +142 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/dashboard_hub/local.py +247 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/dashboard_hub/postgres_notify.py +361 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/frame_router.py +493 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/gateway.py +533 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/registry/__init__.py +34 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/registry/_protocol.py +102 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/registry/local.py +124 -0
- z4j_brain-1.0.0/backend/src/z4j_brain/websocket/registry/postgres_notify.py +574 -0
- z4j_brain-1.0.0/backend/tests/__init__.py +0 -0
- z4j_brain-1.0.0/backend/tests/integration/__init__.py +0 -0
- z4j_brain-1.0.0/backend/tests/integration/conftest.py +262 -0
- z4j_brain-1.0.0/backend/tests/integration/test_audit_log_trigger.py +77 -0
- z4j_brain-1.0.0/backend/tests/integration/test_citext_email.py +67 -0
- z4j_brain-1.0.0/backend/tests/integration/test_end_to_end_loop.py +272 -0
- z4j_brain-1.0.0/backend/tests/integration/test_events_partitioning.py +140 -0
- z4j_brain-1.0.0/backend/tests/integration/test_migration_pg.py +167 -0
- z4j_brain-1.0.0/backend/tests/integration/test_postgres_notify_dashboard_hub.py +229 -0
- z4j_brain-1.0.0/backend/tests/integration/test_postgres_notify_registry.py +213 -0
- z4j_brain-1.0.0/backend/tests/integration/test_registry_reconcile.py +127 -0
- z4j_brain-1.0.0/backend/tests/unit/__init__.py +0 -0
- z4j_brain-1.0.0/backend/tests/unit/conftest.py +53 -0
- z4j_brain-1.0.0/backend/tests/unit/test_api_key_expires_tz.py +102 -0
- z4j_brain-1.0.0/backend/tests/unit/test_audit_service.py +183 -0
- z4j_brain-1.0.0/backend/tests/unit/test_auth_endpoint.py +265 -0
- z4j_brain-1.0.0/backend/tests/unit/test_b4_endpoints.py +381 -0
- z4j_brain-1.0.0/backend/tests/unit/test_b5_endpoints.py +512 -0
- z4j_brain-1.0.0/backend/tests/unit/test_background_workers.py +141 -0
- z4j_brain-1.0.0/backend/tests/unit/test_body_size.py +74 -0
- z4j_brain-1.0.0/backend/tests/unit/test_channel_validation.py +149 -0
- z4j_brain-1.0.0/backend/tests/unit/test_command_dispatcher.py +328 -0
- z4j_brain-1.0.0/backend/tests/unit/test_csrf.py +69 -0
- z4j_brain-1.0.0/backend/tests/unit/test_dashboard_sub_cap.py +129 -0
- z4j_brain-1.0.0/backend/tests/unit/test_errors.py +103 -0
- z4j_brain-1.0.0/backend/tests/unit/test_event_ingestor.py +296 -0
- z4j_brain-1.0.0/backend/tests/unit/test_event_ingestor_batch6.py +394 -0
- z4j_brain-1.0.0/backend/tests/unit/test_event_ingestor_security.py +462 -0
- z4j_brain-1.0.0/backend/tests/unit/test_export_formula_injection.py +92 -0
- z4j_brain-1.0.0/backend/tests/unit/test_health.py +25 -0
- z4j_brain-1.0.0/backend/tests/unit/test_home_aggregates.py +123 -0
- z4j_brain-1.0.0/backend/tests/unit/test_host_validation.py +90 -0
- z4j_brain-1.0.0/backend/tests/unit/test_invitations.py +285 -0
- z4j_brain-1.0.0/backend/tests/unit/test_local_dashboard_hub.py +206 -0
- z4j_brain-1.0.0/backend/tests/unit/test_local_registry.py +146 -0
- z4j_brain-1.0.0/backend/tests/unit/test_migration.py +93 -0
- z4j_brain-1.0.0/backend/tests/unit/test_models_smoke.py +338 -0
- z4j_brain-1.0.0/backend/tests/unit/test_pagination.py +67 -0
- z4j_brain-1.0.0/backend/tests/unit/test_password_change_lock.py +104 -0
- z4j_brain-1.0.0/backend/tests/unit/test_passwords.py +161 -0
- z4j_brain-1.0.0/backend/tests/unit/test_policy_engine.py +197 -0
- z4j_brain-1.0.0/backend/tests/unit/test_real_client_ip.py +81 -0
- z4j_brain-1.0.0/backend/tests/unit/test_reconciliation_apply.py +145 -0
- z4j_brain-1.0.0/backend/tests/unit/test_reconciliation_worker.py +200 -0
- z4j_brain-1.0.0/backend/tests/unit/test_request_id.py +50 -0
- z4j_brain-1.0.0/backend/tests/unit/test_security_headers.py +120 -0
- z4j_brain-1.0.0/backend/tests/unit/test_session_cookies.py +178 -0
- z4j_brain-1.0.0/backend/tests/unit/test_settings.py +73 -0
- z4j_brain-1.0.0/backend/tests/unit/test_settings_invariants.py +105 -0
- z4j_brain-1.0.0/backend/tests/unit/test_setup_endpoint.py +194 -0
- z4j_brain-1.0.0/backend/tests/unit/test_trends_query.py +88 -0
- z4j_brain-1.0.0/dashboard/.gitignore +9 -0
- z4j_brain-1.0.0/dashboard/.npmrc +62 -0
- z4j_brain-1.0.0/dashboard/Dockerfile.dev +43 -0
- z4j_brain-1.0.0/dashboard/README.md +171 -0
- z4j_brain-1.0.0/dashboard/components.json +21 -0
- z4j_brain-1.0.0/dashboard/index.html +33 -0
- z4j_brain-1.0.0/dashboard/package.json +96 -0
- z4j_brain-1.0.0/dashboard/playwright.config.ts +58 -0
- z4j_brain-1.0.0/dashboard/pnpm-lock.yaml +4575 -0
- z4j_brain-1.0.0/dashboard/public/favicon.svg +14 -0
- z4j_brain-1.0.0/dashboard/public/logos/logo-dark.svg +16 -0
- z4j_brain-1.0.0/dashboard/public/logos/logo-light.svg +16 -0
- z4j_brain-1.0.0/dashboard/scripts/fetch-openapi-snapshot.mjs +37 -0
- z4j_brain-1.0.0/dashboard/src/components/command-palette.tsx +229 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/confirm-dialog.tsx +99 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/date-cell.tsx +28 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/empty-state.tsx +38 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/invite-dialog.tsx +188 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/page-header.tsx +42 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/pending-invitations.tsx +111 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/query-error.tsx +39 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/role-badge.tsx +51 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/stat-card.tsx +66 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/state-badges.tsx +112 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/task-tree.tsx +270 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/trend-chart.tsx +248 -0
- z4j_brain-1.0.0/dashboard/src/components/domain/version-mismatch-banner.tsx +45 -0
- z4j_brain-1.0.0/dashboard/src/components/error-boundary.tsx +73 -0
- z4j_brain-1.0.0/dashboard/src/components/layout/app-sidebar.tsx +348 -0
- z4j_brain-1.0.0/dashboard/src/components/layout/notification-bell.tsx +238 -0
- z4j_brain-1.0.0/dashboard/src/components/layout/password-dialog.tsx +132 -0
- z4j_brain-1.0.0/dashboard/src/components/layout/project-switcher.tsx +131 -0
- z4j_brain-1.0.0/dashboard/src/components/layout/sidebar-context.tsx +77 -0
- z4j_brain-1.0.0/dashboard/src/components/layout/theme-provider.tsx +134 -0
- z4j_brain-1.0.0/dashboard/src/components/layout/theme-toggle.tsx +61 -0
- z4j_brain-1.0.0/dashboard/src/components/layout/topbar.tsx +205 -0
- z4j_brain-1.0.0/dashboard/src/components/layout/user-menu.tsx +86 -0
- z4j_brain-1.0.0/dashboard/src/components/shortcuts-dialog.tsx +59 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/alert.tsx +69 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/avatar.tsx +50 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/badge.tsx +50 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/button.tsx +59 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/card.tsx +109 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/checkbox.tsx +34 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/data-table.tsx +347 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/dialog.tsx +136 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/dropdown-menu.tsx +199 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/input.tsx +28 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/label.tsx +23 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/scroll-area.tsx +47 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/select.tsx +133 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/separator.tsx +26 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/skeleton.tsx +16 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/sonner.tsx +33 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/switch.tsx +31 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/table.tsx +131 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/tabs.tsx +55 -0
- z4j_brain-1.0.0/dashboard/src/components/ui/tooltip.tsx +39 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-agents.ts +41 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-audit.ts +47 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-auth.ts +35 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-commands.ts +191 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-dashboard-socket.ts +90 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-events.ts +22 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-home.ts +131 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-invitations.ts +119 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-keyboard-shortcuts.ts +137 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-memberships.ts +86 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-notifications.ts +472 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-projects.ts +64 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-queues.ts +12 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-schedules.ts +40 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-stats.ts +24 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-tasks.ts +121 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-trends.ts +35 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-users.ts +88 -0
- z4j_brain-1.0.0/dashboard/src/hooks/use-workers.ts +33 -0
- z4j_brain-1.0.0/dashboard/src/lib/api-types-check.ts +128 -0
- z4j_brain-1.0.0/dashboard/src/lib/api-types.ts +396 -0
- z4j_brain-1.0.0/dashboard/src/lib/api.ts +221 -0
- z4j_brain-1.0.0/dashboard/src/lib/dashboard-socket.ts +227 -0
- z4j_brain-1.0.0/dashboard/src/lib/format.ts +86 -0
- z4j_brain-1.0.0/dashboard/src/lib/openapi-snapshot.json +9042 -0
- z4j_brain-1.0.0/dashboard/src/lib/openapi-types.gen.ts +6003 -0
- z4j_brain-1.0.0/dashboard/src/lib/query-client.ts +88 -0
- z4j_brain-1.0.0/dashboard/src/lib/utils.ts +14 -0
- z4j_brain-1.0.0/dashboard/src/main.tsx +60 -0
- z4j_brain-1.0.0/dashboard/src/routes/__root.tsx +14 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.account.tsx +13 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.admin.users.tsx +13 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.home.tsx +725 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.agents.tsx +321 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.audit.tsx +222 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.commands.tsx +263 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.index.tsx +279 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.queues.tsx +97 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.schedules.tsx +405 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.settings.defaults.tsx +357 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.settings.deliveries.tsx +122 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.settings.index.tsx +15 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.settings.members.tsx +322 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.settings.providers.tsx +481 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.settings.tsx +150 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.tasks.tsx +722 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.tasks_.$engine.$taskId.tsx +465 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.trends.tsx +148 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.tsx +23 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.workers.tsx +302 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.projects.$slug.workers_.$workerId.tsx +674 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.account.tsx +580 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.api-keys.tsx +527 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.appearance.tsx +152 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.channels.tsx +388 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.general.tsx +244 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.index.tsx +10 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.memberships.tsx +96 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.notifications.tsx +519 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.projects.tsx +566 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.system.tsx +125 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.tsx +140 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.settings.users.tsx +684 -0
- z4j_brain-1.0.0/dashboard/src/routes/_authenticated.tsx +66 -0
- z4j_brain-1.0.0/dashboard/src/routes/index.tsx +77 -0
- z4j_brain-1.0.0/dashboard/src/routes/invite.tsx +234 -0
- z4j_brain-1.0.0/dashboard/src/routes/login.tsx +125 -0
- z4j_brain-1.0.0/dashboard/src/styles/globals.css +218 -0
- z4j_brain-1.0.0/dashboard/test-results/.last-run.json +6 -0
- z4j_brain-1.0.0/dashboard/test-results/spine-spine-/342/200/224-auth-home-1-login-lands-on-authenticated-page-chromium/error-context.md +1704 -0
- z4j_brain-1.0.0/dashboard/test-results/spine-spine-/342/200/224-auth-home-1-login-lands-on-authenticated-page-chromium/test-failed-1.png +0 -0
- z4j_brain-1.0.0/dashboard/test-results/spine-spine-/342/200/224-auth-home-1-login-lands-on-authenticated-page-chromium/video.webm +0 -0
- z4j_brain-1.0.0/dashboard/tests/e2e/README.md +48 -0
- z4j_brain-1.0.0/dashboard/tests/e2e/fixtures.ts +101 -0
- z4j_brain-1.0.0/dashboard/tests/e2e/spine.spec.ts +200 -0
- z4j_brain-1.0.0/dashboard/tests/e2e/visual-regression.spec.ts +98 -0
- z4j_brain-1.0.0/dashboard/tests/setup.ts +32 -0
- z4j_brain-1.0.0/dashboard/tests/unit/badge.test.tsx +75 -0
- z4j_brain-1.0.0/dashboard/tests/unit/button.test.tsx +73 -0
- z4j_brain-1.0.0/dashboard/tests/unit/lib-format.test.ts +137 -0
- z4j_brain-1.0.0/dashboard/tests/unit/password-dialog.test.tsx +109 -0
- z4j_brain-1.0.0/dashboard/tests/unit/state-badges.test.tsx +65 -0
- z4j_brain-1.0.0/dashboard/tests/unit/theme-provider.test.tsx +146 -0
- z4j_brain-1.0.0/dashboard/tests/unit/theme-toggle.test.tsx +51 -0
- z4j_brain-1.0.0/dashboard/tests/unit/version-mismatch-banner.test.tsx +128 -0
- z4j_brain-1.0.0/dashboard/tsconfig.json +27 -0
- z4j_brain-1.0.0/dashboard/tsconfig.tsbuildinfo +1 -0
- z4j_brain-1.0.0/dashboard/vite.config.ts +114 -0
- z4j_brain-1.0.0/pyproject.toml +112 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a problem with z4j-brain
|
|
3
|
+
title: "[bug] "
|
|
4
|
+
labels: ["bug", "triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for reporting a bug in `z4j-brain`.
|
|
10
|
+
|
|
11
|
+
**Security bugs do NOT belong here.** If you believe you've
|
|
12
|
+
found a security issue, please email `security@z4j.com` -
|
|
13
|
+
see [SECURITY.md](../blob/main/SECURITY.md).
|
|
14
|
+
|
|
15
|
+
- type: input
|
|
16
|
+
id: package-version
|
|
17
|
+
attributes:
|
|
18
|
+
label: z4j-brain version
|
|
19
|
+
description: Output of `pip show z4j-brain | grep -E 'Name|Version'`
|
|
20
|
+
placeholder: z4j-brain 1.0.0
|
|
21
|
+
validations:
|
|
22
|
+
required: true
|
|
23
|
+
|
|
24
|
+
- type: input
|
|
25
|
+
id: python-version
|
|
26
|
+
attributes:
|
|
27
|
+
label: Python version
|
|
28
|
+
placeholder: 3.14.4
|
|
29
|
+
validations:
|
|
30
|
+
required: true
|
|
31
|
+
|
|
32
|
+
- type: dropdown
|
|
33
|
+
id: module
|
|
34
|
+
attributes:
|
|
35
|
+
label: Affected module
|
|
36
|
+
description: (Customize this dropdown's options per package.)
|
|
37
|
+
options:
|
|
38
|
+
- Unsure / multiple
|
|
39
|
+
validations:
|
|
40
|
+
required: false
|
|
41
|
+
|
|
42
|
+
- type: textarea
|
|
43
|
+
id: repro
|
|
44
|
+
attributes:
|
|
45
|
+
label: Minimal reproduction
|
|
46
|
+
description: A standalone script is ideal.
|
|
47
|
+
validations:
|
|
48
|
+
required: true
|
|
49
|
+
|
|
50
|
+
- type: textarea
|
|
51
|
+
id: expected
|
|
52
|
+
attributes:
|
|
53
|
+
label: Expected behavior
|
|
54
|
+
validations:
|
|
55
|
+
required: true
|
|
56
|
+
|
|
57
|
+
- type: textarea
|
|
58
|
+
id: actual
|
|
59
|
+
attributes:
|
|
60
|
+
label: Actual behavior
|
|
61
|
+
description: Include the full traceback if applicable. Please redact secrets.
|
|
62
|
+
render: shell
|
|
63
|
+
validations:
|
|
64
|
+
required: true
|
|
65
|
+
|
|
66
|
+
- type: checkboxes
|
|
67
|
+
id: terms
|
|
68
|
+
attributes:
|
|
69
|
+
label: Confirmation
|
|
70
|
+
options:
|
|
71
|
+
- label: I searched existing issues and this is not a duplicate
|
|
72
|
+
required: true
|
|
73
|
+
- label: This is NOT a security issue (those go to security@z4j.com)
|
|
74
|
+
required: true
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security vulnerability
|
|
4
|
+
url: mailto:security@z4j.com
|
|
5
|
+
about: Report a security issue privately
|
|
6
|
+
- name: Question or discussion
|
|
7
|
+
url: https://github.com/z4jdev/z4j/discussions
|
|
8
|
+
about: General questions about z4j go to the project-wide Discussions
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a capability for z4j-brain
|
|
3
|
+
title: "[feature] "
|
|
4
|
+
labels: ["enhancement", "triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for suggesting a feature for `z4j-brain`. Please describe
|
|
10
|
+
the problem you're trying to solve, not just the solution you
|
|
11
|
+
have in mind.
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: problem
|
|
15
|
+
attributes:
|
|
16
|
+
label: Problem
|
|
17
|
+
description: What are you trying to do that z4j-brain does not currently support?
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: proposed
|
|
23
|
+
attributes:
|
|
24
|
+
label: Proposed solution
|
|
25
|
+
validations:
|
|
26
|
+
required: false
|
|
27
|
+
|
|
28
|
+
- type: textarea
|
|
29
|
+
id: alternatives
|
|
30
|
+
attributes:
|
|
31
|
+
label: Alternatives considered
|
|
32
|
+
validations:
|
|
33
|
+
required: false
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: uv
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: weekly
|
|
7
|
+
day: monday
|
|
8
|
+
time: "04:00"
|
|
9
|
+
timezone: UTC
|
|
10
|
+
open-pull-requests-limit: 5
|
|
11
|
+
labels:
|
|
12
|
+
- dependencies
|
|
13
|
+
- python
|
|
14
|
+
commit-message:
|
|
15
|
+
prefix: chore
|
|
16
|
+
include: scope
|
|
17
|
+
groups:
|
|
18
|
+
minor-and-patch:
|
|
19
|
+
update-types:
|
|
20
|
+
- minor
|
|
21
|
+
- patch
|
|
22
|
+
|
|
23
|
+
- package-ecosystem: github-actions
|
|
24
|
+
directory: /
|
|
25
|
+
schedule:
|
|
26
|
+
interval: weekly
|
|
27
|
+
day: monday
|
|
28
|
+
time: "04:00"
|
|
29
|
+
timezone: UTC
|
|
30
|
+
open-pull-requests-limit: 3
|
|
31
|
+
labels:
|
|
32
|
+
- dependencies
|
|
33
|
+
- ci
|
|
34
|
+
commit-message:
|
|
35
|
+
prefix: ci
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
env:
|
|
17
|
+
UV_VERSION: "0.5.11"
|
|
18
|
+
FORCE_COLOR: "1"
|
|
19
|
+
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
lint:
|
|
23
|
+
name: Lint and format
|
|
24
|
+
runs-on: ubuntu-24.04
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
|
|
28
|
+
- name: Set up Python
|
|
29
|
+
uses: actions/setup-python@v5
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.14"
|
|
32
|
+
|
|
33
|
+
- name: Install uv
|
|
34
|
+
uses: astral-sh/setup-uv@v4
|
|
35
|
+
with:
|
|
36
|
+
version: ${{ env.UV_VERSION }}
|
|
37
|
+
enable-cache: true
|
|
38
|
+
|
|
39
|
+
- name: Sync dependencies
|
|
40
|
+
run: uv sync --all-extras --dev
|
|
41
|
+
|
|
42
|
+
- name: Ruff check
|
|
43
|
+
run: uv run ruff check .
|
|
44
|
+
|
|
45
|
+
- name: Ruff format check
|
|
46
|
+
run: uv run ruff format --check .
|
|
47
|
+
|
|
48
|
+
- name: Mypy
|
|
49
|
+
run: uv run mypy src
|
|
50
|
+
|
|
51
|
+
test:
|
|
52
|
+
name: Tests (Python ${{ matrix.python-version }})
|
|
53
|
+
runs-on: ubuntu-24.04
|
|
54
|
+
needs: [lint]
|
|
55
|
+
strategy:
|
|
56
|
+
fail-fast: false
|
|
57
|
+
matrix:
|
|
58
|
+
python-version: ["3.13", "3.14"]
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/checkout@v4
|
|
61
|
+
|
|
62
|
+
- name: Set up Python
|
|
63
|
+
uses: actions/setup-python@v5
|
|
64
|
+
with:
|
|
65
|
+
python-version: ${{ matrix.python-version }}
|
|
66
|
+
|
|
67
|
+
- name: Install uv
|
|
68
|
+
uses: astral-sh/setup-uv@v4
|
|
69
|
+
with:
|
|
70
|
+
version: ${{ env.UV_VERSION }}
|
|
71
|
+
enable-cache: true
|
|
72
|
+
|
|
73
|
+
- name: Sync dependencies
|
|
74
|
+
run: uv sync --all-extras --dev
|
|
75
|
+
|
|
76
|
+
- name: Run tests
|
|
77
|
+
run: uv run pytest -xvs tests/
|
|
78
|
+
|
|
79
|
+
build:
|
|
80
|
+
name: Build wheel + sdist
|
|
81
|
+
runs-on: ubuntu-24.04
|
|
82
|
+
needs: [test]
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/checkout@v4
|
|
85
|
+
|
|
86
|
+
- name: Set up Python
|
|
87
|
+
uses: actions/setup-python@v5
|
|
88
|
+
with:
|
|
89
|
+
python-version: "3.14"
|
|
90
|
+
|
|
91
|
+
- name: Install uv
|
|
92
|
+
uses: astral-sh/setup-uv@v4
|
|
93
|
+
with:
|
|
94
|
+
version: ${{ env.UV_VERSION }}
|
|
95
|
+
|
|
96
|
+
- name: Build
|
|
97
|
+
run: uv build
|
|
98
|
+
|
|
99
|
+
- name: Validate metadata
|
|
100
|
+
run: |
|
|
101
|
+
uv tool install twine
|
|
102
|
+
uv tool run twine check dist/*
|
|
103
|
+
|
|
104
|
+
- name: Upload artefacts
|
|
105
|
+
uses: actions/upload-artifact@v4
|
|
106
|
+
with:
|
|
107
|
+
name: dist
|
|
108
|
+
path: dist/
|
|
109
|
+
retention-days: 7
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Manual-publish phase: this workflow builds the package and attaches
|
|
4
|
+
# the wheel + sdist to a GitHub Release. It does NOT upload to PyPI.
|
|
5
|
+
# PyPI uploads are hand-picked from a local staging folder via twine,
|
|
6
|
+
# under the maintainer's direct control. See docs/RELEASE.md.
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
tags:
|
|
11
|
+
- "v*.*.*"
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write
|
|
15
|
+
id-token: read
|
|
16
|
+
|
|
17
|
+
env:
|
|
18
|
+
UV_VERSION: "0.5.11"
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
build-and-release:
|
|
22
|
+
name: Build and attach to GitHub Release
|
|
23
|
+
runs-on: ubuntu-24.04
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Verify tag matches pyproject version
|
|
28
|
+
run: |
|
|
29
|
+
TAG_VERSION="${GITHUB_REF_NAME#v}"
|
|
30
|
+
PKG_VERSION=$(grep -E '^version = ' pyproject.toml | head -1 | sed -E 's/version = "(.*)"/\1/')
|
|
31
|
+
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
|
|
32
|
+
echo "::error::Tag $GITHUB_REF_NAME does not match pyproject version $PKG_VERSION"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
- name: Set up Python
|
|
37
|
+
uses: actions/setup-python@v5
|
|
38
|
+
with:
|
|
39
|
+
python-version: "3.14"
|
|
40
|
+
|
|
41
|
+
- name: Install uv
|
|
42
|
+
uses: astral-sh/setup-uv@v4
|
|
43
|
+
with:
|
|
44
|
+
version: ${{ env.UV_VERSION }}
|
|
45
|
+
|
|
46
|
+
- name: Sync dependencies
|
|
47
|
+
run: uv sync --all-extras --dev
|
|
48
|
+
|
|
49
|
+
- name: Run tests
|
|
50
|
+
run: uv run pytest -xvs tests/
|
|
51
|
+
|
|
52
|
+
- name: Build wheel + sdist
|
|
53
|
+
run: uv build
|
|
54
|
+
|
|
55
|
+
- name: Validate metadata
|
|
56
|
+
run: |
|
|
57
|
+
uv tool install twine
|
|
58
|
+
uv tool run twine check dist/*
|
|
59
|
+
|
|
60
|
+
- name: Create GitHub Release with artefacts
|
|
61
|
+
uses: softprops/action-gh-release@v2
|
|
62
|
+
with:
|
|
63
|
+
files: dist/*
|
|
64
|
+
generate_release_notes: true
|
|
65
|
+
fail_on_unmatched_files: true
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
*.egg
|
|
8
|
+
*.egg-info/
|
|
9
|
+
.eggs/
|
|
10
|
+
dist/
|
|
11
|
+
build/
|
|
12
|
+
wheels/
|
|
13
|
+
*.egg-info/
|
|
14
|
+
.installed.cfg
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
.mypy_cache/
|
|
17
|
+
.ruff_cache/
|
|
18
|
+
.coverage
|
|
19
|
+
.coverage.*
|
|
20
|
+
coverage.xml
|
|
21
|
+
*.cover
|
|
22
|
+
htmlcov/
|
|
23
|
+
.tox/
|
|
24
|
+
.nox/
|
|
25
|
+
.hypothesis/
|
|
26
|
+
.pytest_cache/
|
|
27
|
+
|
|
28
|
+
# Virtual envs
|
|
29
|
+
.venv/
|
|
30
|
+
venv/
|
|
31
|
+
env/
|
|
32
|
+
ENV/
|
|
33
|
+
.python-version-local
|
|
34
|
+
|
|
35
|
+
# uv
|
|
36
|
+
.uv/
|
|
37
|
+
|
|
38
|
+
# Node / pnpm
|
|
39
|
+
node_modules/
|
|
40
|
+
.pnpm-store/
|
|
41
|
+
pnpm-debug.log*
|
|
42
|
+
npm-debug.log*
|
|
43
|
+
yarn-debug.log*
|
|
44
|
+
yarn-error.log*
|
|
45
|
+
|
|
46
|
+
# TanStack Router auto-generated routes
|
|
47
|
+
routeTree.gen.ts
|
|
48
|
+
routeTree.gen.ts.timestamp-*
|
|
49
|
+
|
|
50
|
+
# Next.js / Vite build outputs (defensive — future proofing)
|
|
51
|
+
.next/
|
|
52
|
+
.vite/
|
|
53
|
+
dist/
|
|
54
|
+
out/
|
|
55
|
+
|
|
56
|
+
# IDE / editor
|
|
57
|
+
.idea/
|
|
58
|
+
.vscode/
|
|
59
|
+
*.swp
|
|
60
|
+
*.swo
|
|
61
|
+
*~
|
|
62
|
+
.DS_Store
|
|
63
|
+
Thumbs.db
|
|
64
|
+
desktop.ini
|
|
65
|
+
|
|
66
|
+
# Claude Code workspace state — local-machine permissions cache,
|
|
67
|
+
# scheduled-task locks, and an allowlist that often embeds dev
|
|
68
|
+
# tokens. Each developer regenerates their own.
|
|
69
|
+
.claude/
|
|
70
|
+
|
|
71
|
+
# OS
|
|
72
|
+
.AppleDouble
|
|
73
|
+
.LSOverride
|
|
74
|
+
|
|
75
|
+
# Env files — never commit secrets. Match every .env* by default,
|
|
76
|
+
# then explicitly allow-list the templates / examples that are
|
|
77
|
+
# safe to share publicly.
|
|
78
|
+
.env
|
|
79
|
+
.env.*
|
|
80
|
+
!.env.example
|
|
81
|
+
!.env.template
|
|
82
|
+
!.env.sample
|
|
83
|
+
|
|
84
|
+
# z4j local data
|
|
85
|
+
/var/
|
|
86
|
+
*.sqlite
|
|
87
|
+
*.sqlite-journal
|
|
88
|
+
z4j-*.dump
|
|
89
|
+
|
|
90
|
+
# Docker
|
|
91
|
+
docker-compose.override.yml
|
|
92
|
+
|
|
93
|
+
# Logs
|
|
94
|
+
*.log
|
|
95
|
+
logs/
|
|
96
|
+
|
|
97
|
+
# Misc build artifacts
|
|
98
|
+
*.bak
|
|
99
|
+
*.orig
|
|
100
|
+
*.rej
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `z4j-brain` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.0.0] - 2026-04-21
|
|
11
|
+
|
|
12
|
+
First public release.
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- **Self-contained wheel.** `pip install z4j-brain` lands a fully working control plane: FastAPI backend + React dashboard + embedded SQLite + Alembic migrations + packaged `alembic.ini`, all in one Python package. No npm, no Docker, no separate database server required.
|
|
17
|
+
- **Dashboard.** React 19 + TanStack Start SPA served at `/` from the same process. Covers projects, agents, tasks, commands, schedules, events (SSE live tail), audit log, users, roles, API keys, notification channels (email / Slack / webhook), export jobs, and feature flags.
|
|
18
|
+
- **Agent protocol.** WebSocket primary transport with HTTPS long-poll fallback. Signed command dispatch with command-level HMAC signatures.
|
|
19
|
+
- **Multi-tenant.** Projects with per-project memberships, role-based permissions (admin / maintainer / viewer), per-project rate limits, per-project event retention, per-project default notification subscriptions.
|
|
20
|
+
- **Two database backends.** SQLite (default, via `aiosqlite`) for homelab / small-team; PostgreSQL 18 (via optional `[postgres]` extra) for multi-worker horizontal scale-out. PostgreSQL unlocks `LISTEN/NOTIFY`-based registry fan-out across workers.
|
|
21
|
+
- **Observability.** Prometheus `/metrics` endpoint, structured JSON logs via structlog, optional OpenTelemetry OTLP exporter (via `[otel]` extra).
|
|
22
|
+
- **First-boot UX.** Zero-config admin provisioning via signed, single-use, 15-minute setup token printed to stdout, or via `Z4J_BOOTSTRAP_ADMIN_*` env vars for zero-log-exposure deployments.
|
|
23
|
+
- **820 unit tests + 376 integration tests** covering the full REST/WebSocket/CLI surface.
|
|
24
|
+
|
|
25
|
+
### Security
|
|
26
|
+
|
|
27
|
+
- **Argon2id** password hashing with production-grade cost (t=3, m=64 MiB, p=4). Side-channel-free via `argon2-cffi`.
|
|
28
|
+
- **HMAC-chained audit log** with `prev_row_hmac` chaining every row to the previous row's HMAC; tamper-evident append-only timeline.
|
|
29
|
+
- **Separate secrets** for session signing (`Z4J_SESSION_SECRET`) and HMAC signing (`Z4J_SECRET`); session compromise does not extend to command signing.
|
|
30
|
+
- **Startup-time invariant checks** refuse to boot in `production` unless `allowed_hosts` is set and `public_url` uses `https://`.
|
|
31
|
+
- **CSP + HSTS** headers (CSP on HTML responses, HSTS in prod over HTTPS), frame-ancestors deny, X-Content-Type-Options nosniff.
|
|
32
|
+
- **Command signatures** mint via HMAC-SHA256 over canonical JSON so a stolen in-transit command cannot be replayed or rewritten.
|
|
33
|
+
- **Single-use first-boot token** signed with `Z4J_SECRET`, 15-minute TTL, bound to admin setup flow only.
|
|
34
|
+
- **Rate limiting** per-project on command issuance and event ingestion.
|
|
35
|
+
- **`secrets.token_urlsafe(32)`** for every token the brain mints (invitations, API keys, password-reset, first-boot).
|
|
36
|
+
- **Dependency hygiene.** All direct + transitive deps pinned at currently-shipping security-patched floors, zero CVEs across the Python package graph AND the bundled dashboard (React, TanStack, Vite 8, TypeScript 6).
|
|
37
|
+
- **Supply-chain hardening.** pnpm `ignore-scripts=true` with explicit `onlyBuiltDependencies=[]` allowlist prevents arbitrary install-time code execution from any of the ~400 dashboard transitive deps.
|
|
38
|
+
|
|
39
|
+
### Compatibility
|
|
40
|
+
|
|
41
|
+
- Python 3.11, 3.12, 3.13, 3.14.
|
|
42
|
+
- SQLite bundled by default; PostgreSQL 18+ via `pip install "z4j-brain[postgres]"`.
|
|
43
|
+
- Operating-system independent (Linux, macOS, Windows).
|
|
44
|
+
|
|
45
|
+
## Links
|
|
46
|
+
|
|
47
|
+
- Repository: <https://github.com/z4jdev/z4j-brain>
|
|
48
|
+
- Issues: <https://github.com/z4jdev/z4j-brain/issues>
|
|
49
|
+
- PyPI: <https://pypi.org/project/z4j-brain/>
|
|
50
|
+
|
|
51
|
+
[Unreleased]: https://github.com/z4jdev/z4j-brain/compare/v1.0.0...HEAD
|
|
52
|
+
[1.0.0]: https://github.com/z4jdev/z4j-brain/releases/tag/v1.0.0
|