pymizan 3.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.
- pymizan-3.0.0/.agents/skills/mizan/SKILL.md +98 -0
- pymizan-3.0.0/.agents/skills/mizan/agents/openai.yaml +6 -0
- pymizan-3.0.0/.codex/AGENTS.md +26 -0
- pymizan-3.0.0/.codex/agents/docs-researcher.toml +9 -0
- pymizan-3.0.0/.codex/agents/explorer.toml +9 -0
- pymizan-3.0.0/.codex/agents/reviewer.toml +9 -0
- pymizan-3.0.0/.codex/config.toml +48 -0
- pymizan-3.0.0/.env.example +54 -0
- pymizan-3.0.0/.github/CODEOWNERS +15 -0
- pymizan-3.0.0/.github/ISSUE_TEMPLATE/bug_report.yml +58 -0
- pymizan-3.0.0/.github/ISSUE_TEMPLATE/feature_request.yml +48 -0
- pymizan-3.0.0/.github/workflows/auto-release.yml +268 -0
- pymizan-3.0.0/.github/workflows/ci.yml +68 -0
- pymizan-3.0.0/.github/workflows/docs.yml +49 -0
- pymizan-3.0.0/.github/workflows/pr-check.yml +42 -0
- pymizan-3.0.0/.github/workflows/release.yml +125 -0
- pymizan-3.0.0/.gitignore +57 -0
- pymizan-3.0.0/.pre-commit-config.yaml +18 -0
- pymizan-3.0.0/CHANGELOG.md +166 -0
- pymizan-3.0.0/CLAUDE.md +129 -0
- pymizan-3.0.0/CONTRIBUTING.md +269 -0
- pymizan-3.0.0/LICENSE +189 -0
- pymizan-3.0.0/Makefile +119 -0
- pymizan-3.0.0/PKG-INFO +576 -0
- pymizan-3.0.0/README.md +502 -0
- pymizan-3.0.0/VERSION +1 -0
- pymizan-3.0.0/backend/_version.py +3 -0
- pymizan-3.0.0/backend/agents/__init__.py +1 -0
- pymizan-3.0.0/backend/agents/base.py +2758 -0
- pymizan-3.0.0/backend/agents/federation.py +532 -0
- pymizan-3.0.0/backend/agents/khalifah.py +320 -0
- pymizan-3.0.0/backend/agents/perpetual_rotation.py +468 -0
- pymizan-3.0.0/backend/agents/shura_council.py +488 -0
- pymizan-3.0.0/backend/agents/specialized.py +1033 -0
- pymizan-3.0.0/backend/api/__init__.py +1 -0
- pymizan-3.0.0/backend/api/commands.py +114 -0
- pymizan-3.0.0/backend/api/main.py +3706 -0
- pymizan-3.0.0/backend/automation/__init__.py +29 -0
- pymizan-3.0.0/backend/automation/qadr.py +327 -0
- pymizan-3.0.0/backend/automation/triggers.py +95 -0
- pymizan-3.0.0/backend/automation/webhooks.py +118 -0
- pymizan-3.0.0/backend/cli.py +334 -0
- pymizan-3.0.0/backend/cognitive/__init__.py +0 -0
- pymizan-3.0.0/backend/cognitive/thinking_stream.py +204 -0
- pymizan-3.0.0/backend/core/__init__.py +35 -0
- pymizan-3.0.0/backend/core/architecture.py +469 -0
- pymizan-3.0.0/backend/core/basira.py +329 -0
- pymizan-3.0.0/backend/core/creativity.py +566 -0
- pymizan-3.0.0/backend/core/developmental_stages.py +316 -0
- pymizan-3.0.0/backend/core/dream_engine.py +640 -0
- pymizan-3.0.0/backend/core/events.py +295 -0
- pymizan-3.0.0/backend/core/fitrah.py +294 -0
- pymizan-3.0.0/backend/core/fuad.py +243 -0
- pymizan-3.0.0/backend/core/hawa.py +294 -0
- pymizan-3.0.0/backend/core/hidayah.py +244 -0
- pymizan-3.0.0/backend/core/hikmah.py +247 -0
- pymizan-3.0.0/backend/core/hooks.py +185 -0
- pymizan-3.0.0/backend/core/ihsan.py +192 -0
- pymizan-3.0.0/backend/core/imagination.py +442 -0
- pymizan-3.0.0/backend/core/lubb.py +385 -0
- pymizan-3.0.0/backend/core/middleware.py +136 -0
- pymizan-3.0.0/backend/core/nafs_triad.py +180 -0
- pymizan-3.0.0/backend/core/parallel_agents.py +412 -0
- pymizan-3.0.0/backend/core/plugins.py +366 -0
- pymizan-3.0.0/backend/core/qalb.py +243 -0
- pymizan-3.0.0/backend/core/qalb_processor.py +157 -0
- pymizan-3.0.0/backend/core/ruh_engine.py +198 -0
- pymizan-3.0.0/backend/core/sabr.py +280 -0
- pymizan-3.0.0/backend/core/self_healing.py +460 -0
- pymizan-3.0.0/backend/core/shukr.py +170 -0
- pymizan-3.0.0/backend/core/tawakkul.py +237 -0
- pymizan-3.0.0/backend/core/tawbah.py +228 -0
- pymizan-3.0.0/backend/doctor.py +668 -0
- pymizan-3.0.0/backend/gateway/__init__.py +14 -0
- pymizan-3.0.0/backend/gateway/bab.py +275 -0
- pymizan-3.0.0/backend/gateway/channels/__init__.py +1 -0
- pymizan-3.0.0/backend/gateway/channels/base.py +68 -0
- pymizan-3.0.0/backend/gateway/channels/discord.py +111 -0
- pymizan-3.0.0/backend/gateway/channels/slack.py +106 -0
- pymizan-3.0.0/backend/gateway/channels/telegram.py +103 -0
- pymizan-3.0.0/backend/gateway/channels/whatsapp.py +129 -0
- pymizan-3.0.0/backend/gateway/router.py +199 -0
- pymizan-3.0.0/backend/knowledge/__init__.py +0 -0
- pymizan-3.0.0/backend/knowledge/ingest.py +189 -0
- pymizan-3.0.0/backend/learner/__init__.py +0 -0
- pymizan-3.0.0/backend/learner/data_export.py +60 -0
- pymizan-3.0.0/backend/learner/ruh_learner.py +114 -0
- pymizan-3.0.0/backend/memory/__init__.py +1 -0
- pymizan-3.0.0/backend/memory/dhikr.py +1012 -0
- pymizan-3.0.0/backend/memory/knowledge_graph.py +240 -0
- pymizan-3.0.0/backend/memory/lawh_mahfuz.py +315 -0
- pymizan-3.0.0/backend/memory/living_memory.py +741 -0
- pymizan-3.0.0/backend/memory/masalik.py +821 -0
- pymizan-3.0.0/backend/memory/memory_pyramid.py +260 -0
- pymizan-3.0.0/backend/memory/quaternary.py +240 -0
- pymizan-3.0.0/backend/memory/vector_store.py +128 -0
- pymizan-3.0.0/backend/network/__init__.py +3 -0
- pymizan-3.0.0/backend/network/ummah.py +456 -0
- pymizan-3.0.0/backend/perception/__init__.py +13 -0
- pymizan-3.0.0/backend/perception/basirah.py +177 -0
- pymizan-3.0.0/backend/perception/nutq.py +303 -0
- pymizan-3.0.0/backend/perception/vision.py +100 -0
- pymizan-3.0.0/backend/perception/voice.py +87 -0
- pymizan-3.0.0/backend/providers.py +890 -0
- pymizan-3.0.0/backend/providers_ruh.py +97 -0
- pymizan-3.0.0/backend/qadar_research_paper.tex +206 -0
- pymizan-3.0.0/backend/qca/__init__.py +46 -0
- pymizan-3.0.0/backend/qca/answer_engine.py +251 -0
- pymizan-3.0.0/backend/qca/cognitive_methods.py +626 -0
- pymizan-3.0.0/backend/qca/engine.py +1113 -0
- pymizan-3.0.0/backend/qca/roots.py +814 -0
- pymizan-3.0.0/backend/qca/training.py +674 -0
- pymizan-3.0.0/backend/qca/yaqin_engine.py +251 -0
- pymizan-3.0.0/backend/reasoning/__init__.py +15 -0
- pymizan-3.0.0/backend/reasoning/aql_engine.py +372 -0
- pymizan-3.0.0/backend/reasoning/causal_engine.py +367 -0
- pymizan-3.0.0/backend/reasoning/context_manager.py +125 -0
- pymizan-3.0.0/backend/reasoning/planner.py +292 -0
- pymizan-3.0.0/backend/references.bib +42 -0
- pymizan-3.0.0/backend/requirements.txt +53 -0
- pymizan-3.0.0/backend/router/__init__.py +0 -0
- pymizan-3.0.0/backend/router/intelligent_router.py +144 -0
- pymizan-3.0.0/backend/security/__init__.py +19 -0
- pymizan-3.0.0/backend/security/auth.py +221 -0
- pymizan-3.0.0/backend/security/izn.py +376 -0
- pymizan-3.0.0/backend/security/validation.py +242 -0
- pymizan-3.0.0/backend/security/vault.py +152 -0
- pymizan-3.0.0/backend/security/wali.py +387 -0
- pymizan-3.0.0/backend/settings.py +114 -0
- pymizan-3.0.0/backend/skills/__init__.py +14 -0
- pymizan-3.0.0/backend/skills/base.py +60 -0
- pymizan-3.0.0/backend/skills/builtin/__init__.py +1 -0
- pymizan-3.0.0/backend/skills/builtin/data_analysis.py +133 -0
- pymizan-3.0.0/backend/skills/builtin/kitab_notebook.py +521 -0
- pymizan-3.0.0/backend/skills/builtin/linode_cloud.py +562 -0
- pymizan-3.0.0/backend/skills/builtin/majlis_social.py +1385 -0
- pymizan-3.0.0/backend/skills/builtin/raqib_scanner.py +959 -0
- pymizan-3.0.0/backend/skills/builtin/sahab_cloud.py +639 -0
- pymizan-3.0.0/backend/skills/builtin/ssh_remote.py +747 -0
- pymizan-3.0.0/backend/skills/builtin/suq_registry.py +920 -0
- pymizan-3.0.0/backend/skills/builtin/wahy_plugins.py +1554 -0
- pymizan-3.0.0/backend/skills/builtin/web_browse.py +140 -0
- pymizan-3.0.0/backend/skills/registry.py +241 -0
- pymizan-3.0.0/backend/task_queue/__init__.py +0 -0
- pymizan-3.0.0/backend/task_queue/priorities.py +18 -0
- pymizan-3.0.0/backend/task_queue/task_queue.py +205 -0
- pymizan-3.0.0/backend/task_queue/worker.py +69 -0
- pymizan-3.0.0/backend/tests/__init__.py +1 -0
- pymizan-3.0.0/backend/tests/test_security/__init__.py +1 -0
- pymizan-3.0.0/backend/training_manager.py +325 -0
- pymizan-3.0.0/deploy.sh +330 -0
- pymizan-3.0.0/docker/Dockerfile.backend +39 -0
- pymizan-3.0.0/docker/Dockerfile.backend.prod +70 -0
- pymizan-3.0.0/docker/Dockerfile.frontend +13 -0
- pymizan-3.0.0/docker/Dockerfile.frontend.prod +42 -0
- pymizan-3.0.0/docker/nginx-nossl.conf +59 -0
- pymizan-3.0.0/docker/nginx.conf +91 -0
- pymizan-3.0.0/docker-compose.prod.yml +142 -0
- pymizan-3.0.0/docker-compose.yml +107 -0
- pymizan-3.0.0/docs/index.html +1766 -0
- pymizan-3.0.0/docs/quranic_human_model.md +292 -0
- pymizan-3.0.0/frontend/index.html +17 -0
- pymizan-3.0.0/frontend/nginx-spa.conf +23 -0
- pymizan-3.0.0/frontend/package-lock.json +4971 -0
- pymizan-3.0.0/frontend/package.json +35 -0
- pymizan-3.0.0/frontend/postcss.config.js +6 -0
- pymizan-3.0.0/frontend/src/App.tsx +2536 -0
- pymizan-3.0.0/frontend/src/components/AgentCard.tsx +179 -0
- pymizan-3.0.0/frontend/src/components/AgentModal.tsx +165 -0
- pymizan-3.0.0/frontend/src/components/ChatMessage.tsx +637 -0
- pymizan-3.0.0/frontend/src/components/ConnectionBanner.tsx +44 -0
- pymizan-3.0.0/frontend/src/components/Icons.tsx +105 -0
- pymizan-3.0.0/frontend/src/components/Markdown.tsx +118 -0
- pymizan-3.0.0/frontend/src/components/MobileNav.tsx +46 -0
- pymizan-3.0.0/frontend/src/components/QueueDashboard.tsx +181 -0
- pymizan-3.0.0/frontend/src/components/RouterStatus.tsx +140 -0
- pymizan-3.0.0/frontend/src/components/Sidebar.tsx +138 -0
- pymizan-3.0.0/frontend/src/components/Skeleton.tsx +40 -0
- pymizan-3.0.0/frontend/src/components/ThemeToggle.tsx +37 -0
- pymizan-3.0.0/frontend/src/components/ThinkingStream.tsx +270 -0
- pymizan-3.0.0/frontend/src/components/Toast.tsx +85 -0
- pymizan-3.0.0/frontend/src/components/TrainingDashboard.tsx +205 -0
- pymizan-3.0.0/frontend/src/components/ruh/CheckpointBrowser.tsx +126 -0
- pymizan-3.0.0/frontend/src/components/ruh/DataComposition.tsx +177 -0
- pymizan-3.0.0/frontend/src/components/ruh/LossCurveChart.tsx +134 -0
- pymizan-3.0.0/frontend/src/components/ruh/ModelArchitectureView.tsx +215 -0
- pymizan-3.0.0/frontend/src/components/ruh/TasrifVisualizer.tsx +303 -0
- pymizan-3.0.0/frontend/src/components/ruh/TokenizerPipeline.tsx +372 -0
- pymizan-3.0.0/frontend/src/components/ruh/TrainingControls.tsx +143 -0
- pymizan-3.0.0/frontend/src/components/ruh/TrainingHistory.tsx +194 -0
- pymizan-3.0.0/frontend/src/config.ts +9 -0
- pymizan-3.0.0/frontend/src/hooks/useApi.ts +71 -0
- pymizan-3.0.0/frontend/src/hooks/useTheme.ts +68 -0
- pymizan-3.0.0/frontend/src/hooks/useTrainingWebSocket.ts +111 -0
- pymizan-3.0.0/frontend/src/hooks/useWebSocket.ts +97 -0
- pymizan-3.0.0/frontend/src/index.css +749 -0
- pymizan-3.0.0/frontend/src/main.tsx +13 -0
- pymizan-3.0.0/frontend/src/pages/AutomationPage.tsx +392 -0
- pymizan-3.0.0/frontend/src/pages/ChannelsPage.tsx +325 -0
- pymizan-3.0.0/frontend/src/pages/DeveloperPage.tsx +780 -0
- pymizan-3.0.0/frontend/src/pages/MajlisPage.tsx +786 -0
- pymizan-3.0.0/frontend/src/pages/NotebookPage.tsx +448 -0
- pymizan-3.0.0/frontend/src/pages/PerceptionPage.tsx +508 -0
- pymizan-3.0.0/frontend/src/pages/PluginsPage.tsx +550 -0
- pymizan-3.0.0/frontend/src/pages/ProvidersPage.tsx +629 -0
- pymizan-3.0.0/frontend/src/pages/RuhModelPage.tsx +530 -0
- pymizan-3.0.0/frontend/src/pages/ScannerPage.tsx +392 -0
- pymizan-3.0.0/frontend/src/pages/SecurityPage.tsx +616 -0
- pymizan-3.0.0/frontend/src/pages/SettingsPage.tsx +552 -0
- pymizan-3.0.0/frontend/src/pages/SkillsPage.tsx +417 -0
- pymizan-3.0.0/frontend/src/pages/WelcomePage.tsx +272 -0
- pymizan-3.0.0/frontend/src/types/ruh.ts +173 -0
- pymizan-3.0.0/frontend/src/types.ts +517 -0
- pymizan-3.0.0/frontend/src/vite-env.d.ts +1 -0
- pymizan-3.0.0/frontend/tailwind.config.js +73 -0
- pymizan-3.0.0/frontend/tsconfig.json +25 -0
- pymizan-3.0.0/frontend/vite.config.js +16 -0
- pymizan-3.0.0/install.ps1 +390 -0
- pymizan-3.0.0/install.sh +590 -0
- pymizan-3.0.0/masalik_network.json +1 -0
- pymizan-3.0.0/plugins/__init__.py +3 -0
- pymizan-3.0.0/plugins/hello_world/main.py +86 -0
- pymizan-3.0.0/plugins/hello_world/plugin.json +11 -0
- pymizan-3.0.0/plugins/request_logger/main.py +60 -0
- pymizan-3.0.0/plugins/request_logger/plugin.json +11 -0
- pymizan-3.0.0/pyproject.toml +145 -0
- pymizan-3.0.0/research/iaai27_agentops/CLAIMS.md +22 -0
- pymizan-3.0.0/research/iaai27_agentops/DEPLOYMENT.md +71 -0
- pymizan-3.0.0/research/iaai27_agentops/README.md +125 -0
- pymizan-3.0.0/research/iaai27_agentops/__init__.py +1 -0
- pymizan-3.0.0/research/iaai27_agentops/__main__.py +53 -0
- pymizan-3.0.0/research/iaai27_agentops/core.py +346 -0
- pymizan-3.0.0/research/iaai27_agentops/evaluate.py +211 -0
- pymizan-3.0.0/research/iaai27_agentops/results/cli-smoke.json +111 -0
- pymizan-3.0.0/research/iaai27_agentops/results/dependencies.json +198 -0
- pymizan-3.0.0/research/iaai27_agentops/results/episodes.jsonl +96 -0
- pymizan-3.0.0/research/iaai27_agentops/results/manifest.json +19 -0
- pymizan-3.0.0/research/iaai27_agentops/results/repeatability.json +10 -0
- pymizan-3.0.0/research/iaai27_agentops/results/scenarios.json +150 -0
- pymizan-3.0.0/research/iaai27_agentops/results/summary.json +50 -0
- pymizan-3.0.0/research/iaai27_agentops/results/tests.txt +17 -0
- pymizan-3.0.0/research/iaai27_agentops/results/validation.md +13 -0
- pymizan-3.0.0/research/iaai27_agentops/test_agentops.py +191 -0
- pymizan-3.0.0/ruh_model/README.md +1054 -0
- pymizan-3.0.0/ruh_model/__init__.py +8 -0
- pymizan-3.0.0/ruh_model/attention/__init__.py +6 -0
- pymizan-3.0.0/ruh_model/attention/qalb.py +212 -0
- pymizan-3.0.0/ruh_model/attention/sam_basar.py +177 -0
- pymizan-3.0.0/ruh_model/benchmarks/__init__.py +1 -0
- pymizan-3.0.0/ruh_model/config.py +98 -0
- pymizan-3.0.0/ruh_model/configs/alaqah.yaml +23 -0
- pymizan-3.0.0/ruh_model/configs/full_real.yaml +25 -0
- pymizan-3.0.0/ruh_model/configs/khalq_akhar.yaml +17 -0
- pymizan-3.0.0/ruh_model/configs/mudghah.yaml +17 -0
- pymizan-3.0.0/ruh_model/configs/nutfah.yaml +23 -0
- pymizan-3.0.0/ruh_model/embedding/__init__.py +11 -0
- pymizan-3.0.0/ruh_model/embedding/ism.py +132 -0
- pymizan-3.0.0/ruh_model/embedding/rope.py +124 -0
- pymizan-3.0.0/ruh_model/layers/__init__.py +6 -0
- pymizan-3.0.0/ruh_model/layers/adaptive_depth.py +88 -0
- pymizan-3.0.0/ruh_model/layers/ism_ffn.py +52 -0
- pymizan-3.0.0/ruh_model/layers/lubb.py +171 -0
- pymizan-3.0.0/ruh_model/layers/shura_moe.py +144 -0
- pymizan-3.0.0/ruh_model/layers/transformer_block.py +89 -0
- pymizan-3.0.0/ruh_model/loss/__init__.py +1 -0
- pymizan-3.0.0/ruh_model/loss/mizan_loss.py +238 -0
- pymizan-3.0.0/ruh_model/model.py +253 -0
- pymizan-3.0.0/ruh_model/tests/__init__.py +1 -0
- pymizan-3.0.0/ruh_model/tests/conftest.py +30 -0
- pymizan-3.0.0/ruh_model/tests/test_bayan.py +250 -0
- pymizan-3.0.0/ruh_model/tests/test_ism.py +265 -0
- pymizan-3.0.0/ruh_model/tokenizer/__init__.py +14 -0
- pymizan-3.0.0/ruh_model/tokenizer/bayan.py +277 -0
- pymizan-3.0.0/ruh_model/tokenizer/english_bridge.py +141 -0
- pymizan-3.0.0/ruh_model/tokenizer/morphology.py +204 -0
- pymizan-3.0.0/ruh_model/tokenizer/q28_articulatory.py +500 -0
- pymizan-3.0.0/ruh_model/tokenizer/root_vocab.py +180 -0
- pymizan-3.0.0/ruh_model/tokenizer/tasrif_ops.py +179 -0
- pymizan-3.0.0/ruh_model/train.py +308 -0
- pymizan-3.0.0/ruh_model/train_full.py +591 -0
- pymizan-3.0.0/ruh_model/training/__init__.py +12 -0
- pymizan-3.0.0/ruh_model/training/curriculum.py +168 -0
- pymizan-3.0.0/ruh_model/training/scheduler.py +115 -0
- pymizan-3.0.0/ruh_model/training/trainer.py +297 -0
- pymizan-3.0.0/scripts/bump-version.sh +144 -0
- pymizan-3.0.0/scripts/release.sh +202 -0
- pymizan-3.0.0/scripts/setup-branch-protection.sh +112 -0
- pymizan-3.0.0/start.sh +243 -0
- pymizan-3.0.0/tests/__init__.py +0 -0
- pymizan-3.0.0/tests/conftest.py +46 -0
- pymizan-3.0.0/tests/test_agent_comprehensive.py +501 -0
- pymizan-3.0.0/tests/test_agents.py +145 -0
- pymizan-3.0.0/tests/test_api.py +79 -0
- pymizan-3.0.0/tests/test_api_comprehensive.py +308 -0
- pymizan-3.0.0/tests/test_architecture.py +108 -0
- pymizan-3.0.0/tests/test_core_systems.py +681 -0
- pymizan-3.0.0/tests/test_doctor.py +181 -0
- pymizan-3.0.0/tests/test_e2e_scenarios.py +679 -0
- pymizan-3.0.0/tests/test_learner.py +205 -0
- pymizan-3.0.0/tests/test_masalik.py +420 -0
- pymizan-3.0.0/tests/test_memory.py +118 -0
- pymizan-3.0.0/tests/test_memory_comprehensive.py +588 -0
- pymizan-3.0.0/tests/test_providers_ruh.py +302 -0
- pymizan-3.0.0/tests/test_qca_comprehensive.py +600 -0
- pymizan-3.0.0/tests/test_qca_engine.py +204 -0
- pymizan-3.0.0/tests/test_quranic_faculties.py +183 -0
- pymizan-3.0.0/tests/test_router.py +208 -0
- pymizan-3.0.0/tests/test_security_comprehensive.py +404 -0
- pymizan-3.0.0/tests/test_task_queue.py +258 -0
- pymizan-3.0.0/update.sh +329 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# mizan Development Patterns
|
|
2
|
+
|
|
3
|
+
> Auto-generated skill from repository analysis; conventions corrected against the
|
|
4
|
+
> actual repository (snake_case sources, pytest suite, ruff linting).
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
This skill teaches the core development patterns and conventions used in the
|
|
8
|
+
`mizan` Python codebase. You'll learn about file naming, import styles, commit
|
|
9
|
+
message conventions, and how to write and run tests. This guide helps maintain
|
|
10
|
+
consistency and efficiency when contributing to `mizan`.
|
|
11
|
+
|
|
12
|
+
## Coding Conventions
|
|
13
|
+
|
|
14
|
+
### File Naming
|
|
15
|
+
- Use **snake_case** for Python files and directories.
|
|
16
|
+
- Example: `backend/memory/dhikr.py`, `backend/agents/base.py`
|
|
17
|
+
|
|
18
|
+
### Import Style
|
|
19
|
+
- Use **absolute imports** relative to the `backend/` directory, which lives on
|
|
20
|
+
`sys.path` (see `tests/conftest.py` for how tests set this up).
|
|
21
|
+
- Example (inside `backend/`):
|
|
22
|
+
```python
|
|
23
|
+
from memory.dhikr import DhikrMemorySystem
|
|
24
|
+
```
|
|
25
|
+
- Example (entry points that import the package):
|
|
26
|
+
```python
|
|
27
|
+
from backend._version import __version__
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Export Style
|
|
31
|
+
- Keep module internals private by leading underscore; re-export the public API
|
|
32
|
+
from the package `__init__.py` where a package boundary exists.
|
|
33
|
+
- Example: `backend/perception/__init__.py` re-exports `BasirahEngine` and
|
|
34
|
+
`NutqEngine`.
|
|
35
|
+
|
|
36
|
+
### Commit Messages
|
|
37
|
+
- Follow **conventional commit** patterns: `feat:`, `fix:`, `docs:`, `refactor:`,
|
|
38
|
+
`test:`, `chore:`.
|
|
39
|
+
- Example:
|
|
40
|
+
```
|
|
41
|
+
feat: add data normalization to processor
|
|
42
|
+
docs: update usage instructions in README
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Workflows
|
|
46
|
+
|
|
47
|
+
### Adding a New Feature
|
|
48
|
+
**Trigger:** When implementing new functionality.
|
|
49
|
+
**Command:** `/add-feature`
|
|
50
|
+
|
|
51
|
+
1. Create a new Python file using snake_case naming (e.g. `backend/core/new_feature.py`).
|
|
52
|
+
2. Implement the feature using absolute imports from `backend/`.
|
|
53
|
+
3. Re-export the public entry points from the package `__init__.py` if the
|
|
54
|
+
feature defines a new package boundary.
|
|
55
|
+
4. Write a test file named `tests/test_<feature>.py` covering the new behavior.
|
|
56
|
+
5. Run lint and tests: `make check` (or `ruff check backend/ tests/` plus
|
|
57
|
+
`pytest tests/`).
|
|
58
|
+
6. Commit your changes with a `feat:` prefix.
|
|
59
|
+
- Example: `feat: implement user authentication`
|
|
60
|
+
7. Push your branch and open a pull request.
|
|
61
|
+
|
|
62
|
+
### Updating Documentation
|
|
63
|
+
**Trigger:** When updating or adding documentation.
|
|
64
|
+
**Command:** `/update-docs`
|
|
65
|
+
|
|
66
|
+
1. Edit or create documentation files as needed (`README.md`, `docs/`,
|
|
67
|
+
`CONTRIBUTING.md`, `CHANGELOG.md` under `[Unreleased]`).
|
|
68
|
+
2. Commit changes with a `docs:` prefix.
|
|
69
|
+
- Example: `docs: add API usage examples`
|
|
70
|
+
3. Push your branch and open a pull request.
|
|
71
|
+
|
|
72
|
+
## Testing Patterns
|
|
73
|
+
|
|
74
|
+
- Test files follow the pattern `tests/test_*.py` (e.g. `tests/test_memory.py`).
|
|
75
|
+
- The testing framework is **pytest** with **pytest-asyncio** (`asyncio_mode = "auto"`,
|
|
76
|
+
configured in `pyproject.toml`).
|
|
77
|
+
- `tests/conftest.py` inserts `backend/` into `sys.path` and provides shared
|
|
78
|
+
fixtures (`temp_db`, `mock_wali`, `mock_izn`).
|
|
79
|
+
- Example test file:
|
|
80
|
+
```python
|
|
81
|
+
# tests/test_my_module.py
|
|
82
|
+
import pytest
|
|
83
|
+
|
|
84
|
+
from memory.my_module import main_function
|
|
85
|
+
|
|
86
|
+
def test_main_function():
|
|
87
|
+
assert main_function(2, 2) == 4
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Commands
|
|
91
|
+
| Command | Purpose |
|
|
92
|
+
|-------------------------------|----------------------------------------------------------|
|
|
93
|
+
| `pip install -e ".[dev]"` | Install dev dependencies (pytest, ruff, mypy, pre-commit)|
|
|
94
|
+
| `pytest tests/` | Run the full test suite |
|
|
95
|
+
| `ruff check backend/ tests/` | Lint sources and tests |
|
|
96
|
+
| `ruff format --check backend/ tests/` | Verify formatting (line-length 100) |
|
|
97
|
+
| `make check` | Run lint + typecheck + test |
|
|
98
|
+
| `make serve` | Start the backend API server |
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# ECC for Codex CLI
|
|
2
|
+
|
|
3
|
+
This supplements the repo's `CLAUDE.md` contributor guide with a repo-local ECC baseline.
|
|
4
|
+
|
|
5
|
+
## Repo Skill
|
|
6
|
+
|
|
7
|
+
- Repo-generated Codex skill: `.agents/skills/mizan/SKILL.md`
|
|
8
|
+
- Claude-facing companion skill: `.claude/skills/mizan/SKILL.md`
|
|
9
|
+
- Keep user-specific credentials and private MCPs in `~/.codex/config.toml`, not in this repo.
|
|
10
|
+
|
|
11
|
+
## MCP Baseline
|
|
12
|
+
|
|
13
|
+
Treat `.codex/config.toml` as the default ECC-safe baseline for work in this repository.
|
|
14
|
+
The generated baseline enables GitHub, Context7, Exa, Memory, Playwright, and Sequential Thinking.
|
|
15
|
+
|
|
16
|
+
## Multi-Agent Support
|
|
17
|
+
|
|
18
|
+
- Explorer: read-only evidence gathering
|
|
19
|
+
- Reviewer: correctness, security, and regression review
|
|
20
|
+
- Docs researcher: API and release-note verification
|
|
21
|
+
|
|
22
|
+
## Workflow Files
|
|
23
|
+
|
|
24
|
+
- No dedicated workflow command files were generated for this repo.
|
|
25
|
+
|
|
26
|
+
Use these workflow files as reusable task scaffolds when the detected repository workflows recur.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
model = "gpt-5.4"
|
|
2
|
+
model_reasoning_effort = "medium"
|
|
3
|
+
sandbox_mode = "read-only"
|
|
4
|
+
|
|
5
|
+
developer_instructions = """
|
|
6
|
+
Verify APIs, framework behavior, and release-note claims against primary documentation before changes land.
|
|
7
|
+
Cite the exact docs or file paths that support each claim.
|
|
8
|
+
Do not invent undocumented behavior.
|
|
9
|
+
"""
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
model = "gpt-5.4"
|
|
2
|
+
model_reasoning_effort = "medium"
|
|
3
|
+
sandbox_mode = "read-only"
|
|
4
|
+
|
|
5
|
+
developer_instructions = """
|
|
6
|
+
Stay in exploration mode.
|
|
7
|
+
Trace the real execution path, cite files and symbols, and avoid proposing fixes unless the parent agent asks for them.
|
|
8
|
+
Prefer targeted search and file reads over broad scans.
|
|
9
|
+
"""
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
model = "gpt-5.4"
|
|
2
|
+
model_reasoning_effort = "high"
|
|
3
|
+
sandbox_mode = "read-only"
|
|
4
|
+
|
|
5
|
+
developer_instructions = """
|
|
6
|
+
Review like an owner.
|
|
7
|
+
Prioritize correctness, security, behavioral regressions, and missing tests.
|
|
8
|
+
Lead with concrete findings and avoid style-only feedback unless it hides a real bug.
|
|
9
|
+
"""
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#:schema https://developers.openai.com/codex/config-schema.json
|
|
2
|
+
|
|
3
|
+
# ECC Tools generated Codex baseline
|
|
4
|
+
approval_policy = "on-request"
|
|
5
|
+
sandbox_mode = "workspace-write"
|
|
6
|
+
web_search = "live"
|
|
7
|
+
|
|
8
|
+
[mcp_servers.github]
|
|
9
|
+
command = "npx"
|
|
10
|
+
args = ["-y", "@modelcontextprotocol/server-github"]
|
|
11
|
+
|
|
12
|
+
[mcp_servers.context7]
|
|
13
|
+
command = "npx"
|
|
14
|
+
args = ["-y", "@upstash/context7-mcp@latest"]
|
|
15
|
+
|
|
16
|
+
[mcp_servers.exa]
|
|
17
|
+
url = "https://mcp.exa.ai/mcp"
|
|
18
|
+
|
|
19
|
+
[mcp_servers.memory]
|
|
20
|
+
command = "npx"
|
|
21
|
+
args = ["-y", "@modelcontextprotocol/server-memory"]
|
|
22
|
+
|
|
23
|
+
[mcp_servers.playwright]
|
|
24
|
+
command = "npx"
|
|
25
|
+
args = ["-y", "@playwright/mcp@latest", "--extension"]
|
|
26
|
+
|
|
27
|
+
[mcp_servers.sequential-thinking]
|
|
28
|
+
command = "npx"
|
|
29
|
+
args = ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
|
30
|
+
|
|
31
|
+
[features]
|
|
32
|
+
multi_agent = true
|
|
33
|
+
|
|
34
|
+
[agents]
|
|
35
|
+
max_threads = 6
|
|
36
|
+
max_depth = 1
|
|
37
|
+
|
|
38
|
+
[agents.explorer]
|
|
39
|
+
description = "Read-only codebase explorer for gathering evidence before changes are proposed."
|
|
40
|
+
config_file = "agents/explorer.toml"
|
|
41
|
+
|
|
42
|
+
[agents.reviewer]
|
|
43
|
+
description = "PR reviewer focused on correctness, security, and missing tests."
|
|
44
|
+
config_file = "agents/reviewer.toml"
|
|
45
|
+
|
|
46
|
+
[agents.docs_researcher]
|
|
47
|
+
description = "Documentation specialist that verifies APIs, framework behavior, and release notes."
|
|
48
|
+
config_file = "agents/docs-researcher.toml"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# ╔══════════════════════════════════════════════════════╗
|
|
2
|
+
# ║ ميزان · MIZAN Configuration ║
|
|
3
|
+
# ║ Copy to .env and fill in your values ║
|
|
4
|
+
# ╚══════════════════════════════════════════════════════╝
|
|
5
|
+
|
|
6
|
+
# ===== AI PROVIDERS (at least one required) =====
|
|
7
|
+
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
8
|
+
OPENAI_API_KEY= # Optional
|
|
9
|
+
OPENROUTER_API_KEY= # Optional — access 300+ models via openrouter.ai
|
|
10
|
+
|
|
11
|
+
# ===== MODEL =====
|
|
12
|
+
# LLM_PROVIDER= # auto-detect | anthropic | openrouter | openai | ollama
|
|
13
|
+
DEFAULT_MODEL=claude-sonnet-4-20250514
|
|
14
|
+
# OpenRouter models: anthropic/claude-sonnet-4, google/gemini-2.0-flash, meta-llama/llama-4-scout, etc.
|
|
15
|
+
|
|
16
|
+
# ===== SYSTEM =====
|
|
17
|
+
SECRET_KEY=change-this-to-a-secure-random-string
|
|
18
|
+
DEBUG=false
|
|
19
|
+
LOG_LEVEL=INFO
|
|
20
|
+
RUH_ENABLED=true
|
|
21
|
+
# al-Insān faculties: when true, Baṣīra/Hawā/Ḥikma actively gate & redirect the
|
|
22
|
+
# agent loop (high-severity lower-pull → forceful restraint). Default advisory.
|
|
23
|
+
DEEP_FACULTY_LOOP=false
|
|
24
|
+
# ===== SERVER =====
|
|
25
|
+
HOST=0.0.0.0
|
|
26
|
+
PORT=8000
|
|
27
|
+
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
|
|
28
|
+
|
|
29
|
+
# ===== PRODUCTION DEPLOYMENT =====
|
|
30
|
+
# DOMAIN=mizan.example.com # Your domain (for SSL)
|
|
31
|
+
# HTTP_PORT=80 # Public HTTP port
|
|
32
|
+
# HTTPS_PORT=443 # Public HTTPS port
|
|
33
|
+
# SSL_EMAIL=admin@example.com # Email for Let's Encrypt
|
|
34
|
+
# NGINX_CONF=nginx-nossl.conf # nginx-nossl.conf or nginx.conf (SSL)
|
|
35
|
+
|
|
36
|
+
# ===== DATABASE =====
|
|
37
|
+
DB_PATH=data/mizan.db
|
|
38
|
+
|
|
39
|
+
# ===== LOCAL AI (Optional) =====
|
|
40
|
+
OLLAMA_URL=http://localhost:11434
|
|
41
|
+
|
|
42
|
+
# ===== CLOUD PROVIDERS (Optional) =====
|
|
43
|
+
LINODE_API_TOKEN= # Linode Personal Access Token (linodes:read_write scope)
|
|
44
|
+
|
|
45
|
+
# ===== CHANNELS (Optional) =====
|
|
46
|
+
TELEGRAM_BOT_TOKEN=
|
|
47
|
+
DISCORD_BOT_TOKEN=
|
|
48
|
+
SLACK_APP_TOKEN=
|
|
49
|
+
WHATSAPP_TOKEN=
|
|
50
|
+
|
|
51
|
+
# ===== EMAIL (Optional) =====
|
|
52
|
+
EMAIL_HOST=imap.gmail.com
|
|
53
|
+
EMAIL_USER=
|
|
54
|
+
EMAIL_PASSWORD=
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# MIZAN Code Owners
|
|
2
|
+
# These users will be automatically requested for review on PRs.
|
|
3
|
+
|
|
4
|
+
# Default owner for everything
|
|
5
|
+
* @CodeWithJuber
|
|
6
|
+
|
|
7
|
+
# Backend core
|
|
8
|
+
/backend/core/ @CodeWithJuber
|
|
9
|
+
/backend/security/ @CodeWithJuber
|
|
10
|
+
/backend/api/main.py @CodeWithJuber
|
|
11
|
+
|
|
12
|
+
# Infrastructure
|
|
13
|
+
/docker-compose.yml @CodeWithJuber
|
|
14
|
+
/.github/workflows/ @CodeWithJuber
|
|
15
|
+
/scripts/ @CodeWithJuber
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a bug in MIZAN
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for reporting a bug! Please fill out the information below.
|
|
9
|
+
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: description
|
|
12
|
+
attributes:
|
|
13
|
+
label: Description
|
|
14
|
+
description: What happened? What did you expect to happen?
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: steps
|
|
20
|
+
attributes:
|
|
21
|
+
label: Steps to Reproduce
|
|
22
|
+
description: How can we reproduce this bug?
|
|
23
|
+
placeholder: |
|
|
24
|
+
1. Run `mizan serve`
|
|
25
|
+
2. Send a chat message
|
|
26
|
+
3. See error...
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
29
|
+
|
|
30
|
+
- type: textarea
|
|
31
|
+
id: logs
|
|
32
|
+
attributes:
|
|
33
|
+
label: Error Logs
|
|
34
|
+
description: Paste any relevant error logs or stack traces
|
|
35
|
+
render: shell
|
|
36
|
+
|
|
37
|
+
- type: dropdown
|
|
38
|
+
id: install-method
|
|
39
|
+
attributes:
|
|
40
|
+
label: Installation Method
|
|
41
|
+
options:
|
|
42
|
+
- pip install
|
|
43
|
+
- Docker
|
|
44
|
+
- From source
|
|
45
|
+
validations:
|
|
46
|
+
required: true
|
|
47
|
+
|
|
48
|
+
- type: input
|
|
49
|
+
id: python-version
|
|
50
|
+
attributes:
|
|
51
|
+
label: Python Version
|
|
52
|
+
placeholder: "3.12"
|
|
53
|
+
|
|
54
|
+
- type: input
|
|
55
|
+
id: os
|
|
56
|
+
attributes:
|
|
57
|
+
label: Operating System
|
|
58
|
+
placeholder: "Ubuntu 24.04 / macOS 15 / Windows 11"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest a new feature for MIZAN
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for suggesting a feature! Please describe what you'd like.
|
|
9
|
+
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: problem
|
|
12
|
+
attributes:
|
|
13
|
+
label: Problem
|
|
14
|
+
description: What problem does this feature solve?
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: solution
|
|
20
|
+
attributes:
|
|
21
|
+
label: Proposed Solution
|
|
22
|
+
description: How should this feature work?
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
|
|
26
|
+
- type: textarea
|
|
27
|
+
id: alternatives
|
|
28
|
+
attributes:
|
|
29
|
+
label: Alternatives Considered
|
|
30
|
+
description: What other solutions have you considered?
|
|
31
|
+
|
|
32
|
+
- type: dropdown
|
|
33
|
+
id: area
|
|
34
|
+
attributes:
|
|
35
|
+
label: Area
|
|
36
|
+
options:
|
|
37
|
+
- Agent System
|
|
38
|
+
- Memory / Knowledge
|
|
39
|
+
- Frontend / UI
|
|
40
|
+
- CLI
|
|
41
|
+
- API
|
|
42
|
+
- Skills / Plugins
|
|
43
|
+
- Security
|
|
44
|
+
- Deployment / Docker
|
|
45
|
+
- Documentation
|
|
46
|
+
- Other
|
|
47
|
+
validations:
|
|
48
|
+
required: true
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
name: Auto Release
|
|
2
|
+
|
|
3
|
+
# Automatically creates a release when a PR is merged to main/master.
|
|
4
|
+
# Determines version bump from PR labels or commit messages:
|
|
5
|
+
# - Label "release:major" or commit with "BREAKING CHANGE" → major bump
|
|
6
|
+
# - Label "release:minor" or commit with "feat:" → minor bump
|
|
7
|
+
# - Label "release:patch" or commit with "fix:" → patch bump
|
|
8
|
+
# - Label "release:beta" → beta pre-release
|
|
9
|
+
# - Label "release:skip" → skip release entirely
|
|
10
|
+
#
|
|
11
|
+
# Can also be triggered manually via workflow_dispatch.
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
branches: [main, master]
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
inputs:
|
|
18
|
+
bump_type:
|
|
19
|
+
description: "Version bump type"
|
|
20
|
+
required: true
|
|
21
|
+
type: choice
|
|
22
|
+
options:
|
|
23
|
+
- patch
|
|
24
|
+
- minor
|
|
25
|
+
- major
|
|
26
|
+
- beta
|
|
27
|
+
|
|
28
|
+
permissions:
|
|
29
|
+
contents: write
|
|
30
|
+
pull-requests: read
|
|
31
|
+
|
|
32
|
+
jobs:
|
|
33
|
+
determine-release:
|
|
34
|
+
name: Determine release type
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
# Skip release commits to avoid infinite loops
|
|
37
|
+
if: "!startsWith(github.event.head_commit.message, 'chore: release v')"
|
|
38
|
+
outputs:
|
|
39
|
+
should_release: ${{ steps.check.outputs.should_release }}
|
|
40
|
+
bump_type: ${{ steps.check.outputs.bump_type }}
|
|
41
|
+
is_prerelease: ${{ steps.check.outputs.is_prerelease }}
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
with:
|
|
45
|
+
fetch-depth: 0
|
|
46
|
+
|
|
47
|
+
- name: Check release type
|
|
48
|
+
id: check
|
|
49
|
+
env:
|
|
50
|
+
MANUAL_BUMP: ${{ github.event.inputs.bump_type }}
|
|
51
|
+
run: |
|
|
52
|
+
BUMP=""
|
|
53
|
+
IS_PRE="false"
|
|
54
|
+
|
|
55
|
+
# Manual trigger takes priority
|
|
56
|
+
if [ -n "$MANUAL_BUMP" ]; then
|
|
57
|
+
if [ "$MANUAL_BUMP" = "beta" ]; then
|
|
58
|
+
BUMP="beta"
|
|
59
|
+
IS_PRE="true"
|
|
60
|
+
else
|
|
61
|
+
BUMP="$MANUAL_BUMP"
|
|
62
|
+
fi
|
|
63
|
+
echo "should_release=true" >> "$GITHUB_OUTPUT"
|
|
64
|
+
echo "bump_type=$BUMP" >> "$GITHUB_OUTPUT"
|
|
65
|
+
echo "is_prerelease=$IS_PRE" >> "$GITHUB_OUTPUT"
|
|
66
|
+
exit 0
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Check merged PR labels
|
|
70
|
+
PR_NUMBER=$(gh pr list --state merged --base main --json number,mergedAt --jq 'sort_by(.mergedAt) | last | .number' 2>/dev/null || echo "")
|
|
71
|
+
if [ -n "$PR_NUMBER" ]; then
|
|
72
|
+
LABELS=$(gh pr view "$PR_NUMBER" --json labels --jq '.labels[].name' 2>/dev/null || echo "")
|
|
73
|
+
|
|
74
|
+
if echo "$LABELS" | grep -q "release:skip"; then
|
|
75
|
+
echo "should_release=false" >> "$GITHUB_OUTPUT"
|
|
76
|
+
echo "bump_type=" >> "$GITHUB_OUTPUT"
|
|
77
|
+
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
|
|
78
|
+
exit 0
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
if echo "$LABELS" | grep -q "release:major"; then BUMP="major"; fi
|
|
82
|
+
if echo "$LABELS" | grep -q "release:minor"; then BUMP="minor"; fi
|
|
83
|
+
if echo "$LABELS" | grep -q "release:patch"; then BUMP="patch"; fi
|
|
84
|
+
if echo "$LABELS" | grep -q "release:beta"; then BUMP="beta"; IS_PRE="true"; fi
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Fallback: detect from commit messages
|
|
88
|
+
if [ -z "$BUMP" ]; then
|
|
89
|
+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
|
90
|
+
if [ -n "$LAST_TAG" ]; then
|
|
91
|
+
COMMITS=$(git log "$LAST_TAG..HEAD" --pretty=format:"%s" --no-merges)
|
|
92
|
+
else
|
|
93
|
+
COMMITS=$(git log --pretty=format:"%s" --no-merges -20)
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
if echo "$COMMITS" | grep -qiE "BREAKING CHANGE|^feat!:"; then
|
|
97
|
+
BUMP="major"
|
|
98
|
+
elif echo "$COMMITS" | grep -qiE "^feat(\(.+\))?:"; then
|
|
99
|
+
BUMP="minor"
|
|
100
|
+
elif echo "$COMMITS" | grep -qiE "^fix(\(.+\))?:"; then
|
|
101
|
+
BUMP="patch"
|
|
102
|
+
fi
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Default: no auto-release unless there's a clear signal
|
|
106
|
+
if [ -z "$BUMP" ]; then
|
|
107
|
+
echo "should_release=false" >> "$GITHUB_OUTPUT"
|
|
108
|
+
echo "bump_type=" >> "$GITHUB_OUTPUT"
|
|
109
|
+
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
|
|
110
|
+
else
|
|
111
|
+
echo "should_release=true" >> "$GITHUB_OUTPUT"
|
|
112
|
+
echo "bump_type=$BUMP" >> "$GITHUB_OUTPUT"
|
|
113
|
+
echo "is_prerelease=$IS_PRE" >> "$GITHUB_OUTPUT"
|
|
114
|
+
fi
|
|
115
|
+
env:
|
|
116
|
+
GH_TOKEN: ${{ github.token }}
|
|
117
|
+
|
|
118
|
+
auto-release:
|
|
119
|
+
name: Create release
|
|
120
|
+
runs-on: ubuntu-latest
|
|
121
|
+
needs: determine-release
|
|
122
|
+
if: needs.determine-release.outputs.should_release == 'true'
|
|
123
|
+
steps:
|
|
124
|
+
- uses: actions/checkout@v4
|
|
125
|
+
with:
|
|
126
|
+
fetch-depth: 0
|
|
127
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
128
|
+
|
|
129
|
+
- uses: actions/setup-python@v5
|
|
130
|
+
with:
|
|
131
|
+
python-version: "3.12"
|
|
132
|
+
|
|
133
|
+
- name: Configure git
|
|
134
|
+
run: |
|
|
135
|
+
git config user.name "github-actions[bot]"
|
|
136
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
137
|
+
|
|
138
|
+
- name: Bump version
|
|
139
|
+
id: bump
|
|
140
|
+
run: |
|
|
141
|
+
BUMP_TYPE="${{ needs.determine-release.outputs.bump_type }}"
|
|
142
|
+
IS_PRE="${{ needs.determine-release.outputs.is_prerelease }}"
|
|
143
|
+
CURRENT=$(cat VERSION | tr -d '[:space:]')
|
|
144
|
+
|
|
145
|
+
if [ "$BUMP_TYPE" = "beta" ]; then
|
|
146
|
+
# Parse current version
|
|
147
|
+
BASE=$(echo "$CURRENT" | sed 's/-.*//')
|
|
148
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE"
|
|
149
|
+
NEXT_MINOR="$MAJOR.$((MINOR + 1)).0"
|
|
150
|
+
|
|
151
|
+
# Check if already in beta
|
|
152
|
+
if echo "$CURRENT" | grep -q "beta"; then
|
|
153
|
+
BETA_NUM=$(echo "$CURRENT" | grep -oP 'beta\.\K[0-9]+')
|
|
154
|
+
NEW_VERSION="${NEXT_MINOR}-beta.$((BETA_NUM + 1))"
|
|
155
|
+
else
|
|
156
|
+
NEW_VERSION="${NEXT_MINOR}-beta.1"
|
|
157
|
+
fi
|
|
158
|
+
else
|
|
159
|
+
# Standard semantic version bump
|
|
160
|
+
BASE=$(echo "$CURRENT" | sed 's/-.*//')
|
|
161
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE"
|
|
162
|
+
case "$BUMP_TYPE" in
|
|
163
|
+
patch) NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))" ;;
|
|
164
|
+
minor) NEW_VERSION="$MAJOR.$((MINOR + 1)).0" ;;
|
|
165
|
+
major) NEW_VERSION="$((MAJOR + 1)).0.0" ;;
|
|
166
|
+
esac
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
echo "current=$CURRENT" >> "$GITHUB_OUTPUT"
|
|
170
|
+
echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
|
|
171
|
+
echo "tag=v$NEW_VERSION" >> "$GITHUB_OUTPUT"
|
|
172
|
+
echo "Bumping $CURRENT → $NEW_VERSION"
|
|
173
|
+
|
|
174
|
+
# Update all version files
|
|
175
|
+
echo "$NEW_VERSION" > VERSION
|
|
176
|
+
|
|
177
|
+
cat > backend/_version.py << PYEOF
|
|
178
|
+
"""Single source of truth for MIZAN version — auto-generated"""
|
|
179
|
+
|
|
180
|
+
__version__ = "$NEW_VERSION"
|
|
181
|
+
PYEOF
|
|
182
|
+
|
|
183
|
+
# Clean indentation from heredoc
|
|
184
|
+
sed -i 's/^ //' backend/_version.py
|
|
185
|
+
|
|
186
|
+
sed -i "s/^version = \".*\"/version = \"$NEW_VERSION\"/" pyproject.toml
|
|
187
|
+
sed -i "s/\"version\": \".*\"/\"version\": \"$NEW_VERSION\"/" frontend/package.json
|
|
188
|
+
|
|
189
|
+
# CLI version
|
|
190
|
+
IFS='.' read -r NM NMI NP <<< "$(echo "$NEW_VERSION" | sed 's/-.*//')"
|
|
191
|
+
SHORT_VER="$NM.$NMI"
|
|
192
|
+
sed -i "s/MIZAN v[0-9][0-9]*\.[0-9][0-9]*/MIZAN v$SHORT_VER/" backend/cli.py
|
|
193
|
+
sed -i "s/MIZAN v[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*/MIZAN v$NEW_VERSION/" backend/cli.py
|
|
194
|
+
|
|
195
|
+
# API version
|
|
196
|
+
sed -i "s/\"version\": \"[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*[^\"]*\"/\"version\": \"$NEW_VERSION\"/g" backend/api/main.py
|
|
197
|
+
sed -i "s/version=\"[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*[^\"]*\"/version=\"$NEW_VERSION\"/" backend/api/main.py
|
|
198
|
+
|
|
199
|
+
- name: Generate changelog
|
|
200
|
+
id: changelog
|
|
201
|
+
run: |
|
|
202
|
+
NEW_VERSION="${{ steps.bump.outputs.new_version }}"
|
|
203
|
+
DATE=$(date +%Y-%m-%d)
|
|
204
|
+
|
|
205
|
+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
|
206
|
+
if [ -n "$LAST_TAG" ]; then
|
|
207
|
+
COMMITS=$(git log "$LAST_TAG..HEAD" --pretty=format:"- %s" --no-merges)
|
|
208
|
+
else
|
|
209
|
+
COMMITS=$(git log --pretty=format:"- %s" --no-merges -20)
|
|
210
|
+
fi
|
|
211
|
+
|
|
212
|
+
# Categorize
|
|
213
|
+
FEATURES=$(echo "$COMMITS" | grep -iE "^- (feat|add|new)" || true)
|
|
214
|
+
FIXES=$(echo "$COMMITS" | grep -iE "^- (fix|bug|patch|hotfix)" || true)
|
|
215
|
+
CHANGES=$(echo "$COMMITS" | grep -iE "^- (refactor|update|improve|enhance|chore|docs|style|perf)" || true)
|
|
216
|
+
|
|
217
|
+
# Build entry
|
|
218
|
+
ENTRY="## [v$NEW_VERSION] — $DATE"
|
|
219
|
+
if [ -n "$FEATURES" ]; then
|
|
220
|
+
ENTRY="$ENTRY
|
|
221
|
+
|
|
222
|
+
### Added
|
|
223
|
+
$FEATURES"
|
|
224
|
+
fi
|
|
225
|
+
if [ -n "$FIXES" ]; then
|
|
226
|
+
ENTRY="$ENTRY
|
|
227
|
+
|
|
228
|
+
### Fixed
|
|
229
|
+
$FIXES"
|
|
230
|
+
fi
|
|
231
|
+
if [ -n "$CHANGES" ]; then
|
|
232
|
+
ENTRY="$ENTRY
|
|
233
|
+
|
|
234
|
+
### Changed
|
|
235
|
+
$CHANGES"
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
# Save for release notes
|
|
239
|
+
echo "$ENTRY" > /tmp/release_notes.md
|
|
240
|
+
|
|
241
|
+
# Prepend to CHANGELOG.md
|
|
242
|
+
if [ -f CHANGELOG.md ]; then
|
|
243
|
+
HEADER=$(head -3 CHANGELOG.md)
|
|
244
|
+
BODY=$(tail -n +4 CHANGELOG.md)
|
|
245
|
+
printf "%s\n\n%s\n\n%s" "$HEADER" "$ENTRY" "$BODY" > CHANGELOG.md
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
- name: Commit and tag
|
|
249
|
+
run: |
|
|
250
|
+
git add -A
|
|
251
|
+
git commit -m "chore: release v${{ steps.bump.outputs.new_version }}
|
|
252
|
+
|
|
253
|
+
Bump version ${{ steps.bump.outputs.current }} → ${{ steps.bump.outputs.new_version }} and update CHANGELOG.
|
|
254
|
+
|
|
255
|
+
[skip ci]"
|
|
256
|
+
git tag -a "v${{ steps.bump.outputs.new_version }}" -m "Release v${{ steps.bump.outputs.new_version }}"
|
|
257
|
+
git push origin HEAD
|
|
258
|
+
git push origin "v${{ steps.bump.outputs.new_version }}"
|
|
259
|
+
|
|
260
|
+
- name: Create GitHub Release
|
|
261
|
+
uses: softprops/action-gh-release@v2
|
|
262
|
+
with:
|
|
263
|
+
tag_name: "v${{ steps.bump.outputs.new_version }}"
|
|
264
|
+
name: "MIZAN v${{ steps.bump.outputs.new_version }}"
|
|
265
|
+
body_path: /tmp/release_notes.md
|
|
266
|
+
draft: false
|
|
267
|
+
prerelease: ${{ needs.determine-release.outputs.is_prerelease == 'true' }}
|
|
268
|
+
generate_release_notes: true
|