@agentikos/omega-os 0.1.0 → 0.19.5
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.
- package/README.md +56 -14
- package/bootstrap/lib/__pycache__/claude-code-settings.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/manifest-helpers.cpython-313.pyc +0 -0
- package/bootstrap/lib/claude-code-settings.py +176 -0
- package/bootstrap/lib/common.sh +457 -1
- package/bootstrap/lib/llm-clis.py +341 -0
- package/bootstrap/lib/manifest-helpers.py +384 -0
- package/bootstrap/lib/steps.sh +1000 -26
- package/bootstrap/manifest.example.yaml +93 -2
- package/bootstrap/templates/aisb/CLAUDE.md +305 -0
- package/bootstrap/templates/aisb/architect.md +204 -0
- package/bootstrap/templates/aisb/checkers/CLAUDE.md +9 -0
- package/bootstrap/templates/aisb/checkers/checker-architect.md +151 -0
- package/bootstrap/templates/aisb/checkers/checker-common.md +171 -0
- package/bootstrap/templates/aisb/checkers/checker-construct.md +129 -0
- package/bootstrap/templates/aisb/checkers/checker-keymaker.md +204 -0
- package/bootstrap/templates/aisb/checkers/checker-link.md +205 -0
- package/bootstrap/templates/aisb/checkers/checker-merovingian.md +219 -0
- package/bootstrap/templates/aisb/checkers/checker-morpheus.md +211 -0
- package/bootstrap/templates/aisb/checkers/checker-neo.md +177 -0
- package/bootstrap/templates/aisb/checkers/checker-niobe.md +156 -0
- package/bootstrap/templates/aisb/checkers/checker-oracle.md +164 -0
- package/bootstrap/templates/aisb/checkers/checker-seraph.md +187 -0
- package/bootstrap/templates/aisb/checkers/checker-smith.md +195 -0
- package/bootstrap/templates/aisb/checkers/checker-zion.md +113 -0
- package/bootstrap/templates/aisb/construct.md +135 -0
- package/bootstrap/templates/aisb/keymaker.md +227 -0
- package/bootstrap/templates/aisb/link.md +170 -0
- package/bootstrap/templates/aisb/lmc-protocol.md +57 -0
- package/bootstrap/templates/aisb/merovingian.md +159 -0
- package/bootstrap/templates/aisb/morpheus.md +243 -0
- package/bootstrap/templates/aisb/neo.md +147 -0
- package/bootstrap/templates/aisb/niobe.md +197 -0
- package/bootstrap/templates/aisb/oracle.md +244 -0
- package/bootstrap/templates/aisb/protocols/handoff-templates.md +204 -0
- package/bootstrap/templates/aisb/protocols/shared-protocol.md +248 -0
- package/bootstrap/templates/aisb/pythia.md +153 -0
- package/bootstrap/templates/aisb/seraph.md +315 -0
- package/bootstrap/templates/aisb/smith.md +202 -0
- package/bootstrap/templates/aisb/zion.md +172 -0
- package/bootstrap/templates/autonomous/audit-patrol.yaml +41 -0
- package/bootstrap/templates/autonomous/smith-reflect.yaml +43 -0
- package/bootstrap/templates/autonomous/ssh-key-rotate.yaml +46 -0
- package/bootstrap/templates/autonomous/support-agent.yaml +38 -0
- package/docs/AUDITS.md +85 -0
- package/docs/COMPLETION-PLAN.md +48 -0
- package/docs/GAP-ANALYSIS.md +214 -0
- package/docs/INSTALL.md +47 -9
- package/docs/MCP-AND-PLUGINS.md +31 -4
- package/docs/SIMULATION.md +171 -0
- package/docs/simulate.sh +211 -0
- package/install.sh +164 -17
- package/omega/Agentik_Engine/README.md +27 -10
- package/omega/Agentik_Engine/omega_engine/__init__.py +212 -2
- package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/account.py +502 -0
- package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
- package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
- package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
- package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
- package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
- package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
- package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
- package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
- package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
- package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
- package/omega/Agentik_Engine/omega_engine/autonomous.py +538 -0
- package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
- package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
- package/omega/Agentik_Engine/omega_engine/cli.py +4564 -56
- package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
- package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__init__.py +14 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/autonomous.py +56 -0
- package/omega/Agentik_Engine/omega_engine/daemons/engine.py +236 -0
- package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +315 -0
- package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
- package/omega/Agentik_Engine/omega_engine/educators/__init__.py +51 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/artifact.py +65 -0
- package/omega/Agentik_Engine/omega_engine/educators/automation.py +76 -0
- package/omega/Agentik_Engine/omega_engine/educators/base.py +327 -0
- package/omega/Agentik_Engine/omega_engine/educators/claudecode.py +71 -0
- package/omega/Agentik_Engine/omega_engine/educators/connection.py +75 -0
- package/omega/Agentik_Engine/omega_engine/educators/coworker.py +68 -0
- package/omega/Agentik_Engine/omega_engine/educators/loop.py +82 -0
- package/omega/Agentik_Engine/omega_engine/educators/prompt.py +68 -0
- package/omega/Agentik_Engine/omega_engine/educators/skill.py +69 -0
- package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
- package/omega/Agentik_Engine/omega_engine/executor.py +195 -16
- package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
- package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
- package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
- package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
- package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
- package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
- package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
- package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
- package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
- package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
- package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
- package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
- package/omega/Agentik_Engine/omega_engine/mission.py +29 -14
- package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
- package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
- package/omega/Agentik_Engine/omega_engine/provider.py +408 -13
- package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
- package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/__init__.py +21 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/agentic.py +83 -0
- package/omega/Agentik_Engine/omega_engine/rag/base.py +42 -0
- package/omega/Agentik_Engine/omega_engine/rag/corrective.py +119 -0
- package/omega/Agentik_Engine/omega_engine/rag/graph.py +169 -0
- package/omega/Agentik_Engine/omega_engine/rag/hybrid.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/multimodal.py +136 -0
- package/omega/Agentik_Engine/omega_engine/rag/router.py +110 -0
- package/omega/Agentik_Engine/omega_engine/reducer.py +21 -3
- package/omega/Agentik_Engine/omega_engine/router.py +28 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
- package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
- package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
- package/omega/Agentik_Engine/omega_engine/store.py +132 -25
- package/omega/Agentik_Engine/omega_engine/sync.py +445 -0
- package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
- package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
- package/omega/Agentik_Engine/omega_engine/tools.py +272 -0
- package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
- package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
- package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
- package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
- package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
- package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/test_account.py +338 -0
- package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
- package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
- package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
- package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
- package/omega/Agentik_Engine/tests/test_autonomous.py +361 -0
- package/omega/Agentik_Engine/tests/test_educators.py +233 -0
- package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
- package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
- package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
- package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
- package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
- package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
- package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
- package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
- package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
- package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
- package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
- package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
- package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
- package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
- package/omega/Agentik_Engine/tests/test_rag.py +287 -0
- package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
- package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
- package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
- package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
- package/omega/Agentik_Engine/tests/test_snapshot_partial.py +172 -0
- package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
- package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
- package/omega/Agentik_Engine/tests/test_tools_and_sync.py +312 -0
- package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
- package/omega/Agentik_Engine/tests/test_vault.py +173 -0
- package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
- package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
- package/omega/Agentik_Runtime/audits.db +0 -0
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
- package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
- package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
- package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
- package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
- package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
- package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
- package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
- package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
- package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
- package/omega/Agentik_SSOT/skills/rag-route.md +82 -0
- package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
- package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
- package/package.json +2 -2
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Skill discovery + safety audit for Claude Code skills.
|
|
2
|
+
|
|
3
|
+
OmegaOS pulls skills from many sources: the curated SSOT, Anthropic's
|
|
4
|
+
official marketplace, Vercel Labs' skills CLI, davila7 templates, ad-hoc
|
|
5
|
+
GitHub repos. Each source is a different trust surface. This package is
|
|
6
|
+
the safety net:
|
|
7
|
+
|
|
8
|
+
* ``marketplaces.py`` — the catalog of known marketplaces with a
|
|
9
|
+
``trust`` rating.
|
|
10
|
+
* ``auditor.py`` — static + heuristic safety check on a SKILL.md
|
|
11
|
+
before it lands in ``~/.claude/skills/``.
|
|
12
|
+
* ``finder.py`` — search across marketplaces.
|
|
13
|
+
* ``installer.py`` — validated install with audit gate.
|
|
14
|
+
|
|
15
|
+
The user's hard rule: every new skill must pass the auditor first.
|
|
16
|
+
Malware patterns (shell-pipe-curl-bash, ``eval``, opaque base64 blobs)
|
|
17
|
+
hard-fail; suspicious-but-legitimate patterns (broad ``allowed-tools``,
|
|
18
|
+
external network calls) warn but don't block — the operator gets the
|
|
19
|
+
report and decides.
|
|
20
|
+
"""
|
|
21
|
+
from omega_engine.skill_discovery.auditor import (
|
|
22
|
+
SkillAuditIssue,
|
|
23
|
+
SkillAuditVerdict,
|
|
24
|
+
audit_skill_file,
|
|
25
|
+
audit_skill_text,
|
|
26
|
+
)
|
|
27
|
+
from omega_engine.skill_discovery.finder import (
|
|
28
|
+
DiscoveredSkill,
|
|
29
|
+
discover_skills,
|
|
30
|
+
list_curated,
|
|
31
|
+
)
|
|
32
|
+
from omega_engine.skill_discovery.installer import (
|
|
33
|
+
SkillInstallResult,
|
|
34
|
+
install_skill_from_github,
|
|
35
|
+
)
|
|
36
|
+
from omega_engine.skill_discovery.marketplaces import (
|
|
37
|
+
Marketplace,
|
|
38
|
+
load_marketplaces,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
__all__ = [
|
|
43
|
+
"Marketplace", "load_marketplaces",
|
|
44
|
+
"SkillAuditIssue", "SkillAuditVerdict",
|
|
45
|
+
"audit_skill_file", "audit_skill_text",
|
|
46
|
+
"DiscoveredSkill", "discover_skills", "list_curated",
|
|
47
|
+
"SkillInstallResult", "install_skill_from_github",
|
|
48
|
+
]
|
package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc
ADDED
|
Binary file
|
package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc
ADDED
|
Binary file
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""Skill safety auditor — block obvious malware before install.
|
|
2
|
+
|
|
3
|
+
A SKILL.md can ship arbitrary instructions and tool grants. We treat
|
|
4
|
+
each candidate skill as untrusted and run a battery of static checks
|
|
5
|
+
that catch the most common attack patterns:
|
|
6
|
+
|
|
7
|
+
* ``curl … | sh`` and equivalents — remote code execution on install
|
|
8
|
+
* Opaque base64/hex blobs > N bytes — likely encoded payloads
|
|
9
|
+
* ``eval`` / ``exec(`` / ``os.system`` in inline scripts
|
|
10
|
+
* Network calls to unfamiliar hosts
|
|
11
|
+
* ``allowed-tools`` that grants ``Bash`` unrestricted (no glob)
|
|
12
|
+
* Hidden HTML/script injection in markdown
|
|
13
|
+
* Missing ``description`` / ``name`` (signals careless author)
|
|
14
|
+
* Excessive size (likely scraped content, not a real skill)
|
|
15
|
+
|
|
16
|
+
Issues are tagged ``severity`` ∈ {block, warn, info}. The verdict
|
|
17
|
+
function aggregates into a score (0-100) and a verified-or-not boolean.
|
|
18
|
+
Block-severity issues hard-fail (verified=False, score capped).
|
|
19
|
+
"""
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import re
|
|
23
|
+
from dataclasses import dataclass, field
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
import yaml
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# ---- patterns ----------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
# `curl ... | sh` / `wget ... | bash` and similar pipe-and-execute patterns.
|
|
33
|
+
_PIPE_EXEC_RE = re.compile(
|
|
34
|
+
r"(?:curl|wget|fetch)\b[^|;]*?\|\s*(?:sh|bash|zsh|fish|pwsh|python\d?)",
|
|
35
|
+
re.IGNORECASE,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# `eval(...)`, `exec(...)`, `os.system(...)`, `subprocess.call(... shell=True ...)`
|
|
39
|
+
_EVAL_EXEC_RE = re.compile(
|
|
40
|
+
r"\b(eval|exec)\s*\(", re.IGNORECASE,
|
|
41
|
+
)
|
|
42
|
+
_OS_SYSTEM_RE = re.compile(
|
|
43
|
+
r"\b(os\.system|subprocess\.\w+\([^)]*shell\s*=\s*True)",
|
|
44
|
+
re.IGNORECASE,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Long base64-looking blocks (40+ continuous base64 chars on one line).
|
|
48
|
+
_BASE64_RE = re.compile(r"[A-Za-z0-9+/=]{120,}")
|
|
49
|
+
|
|
50
|
+
# Catchy script tags inside markdown.
|
|
51
|
+
_SCRIPT_TAG_RE = re.compile(r"<\s*script\b", re.IGNORECASE)
|
|
52
|
+
|
|
53
|
+
# Unrestricted Bash grant: just `Bash` (no glob) is a red flag.
|
|
54
|
+
_BASH_FREE_RE = re.compile(r"(?:^|\s)Bash(?!\(|[A-Za-z])")
|
|
55
|
+
|
|
56
|
+
# Network calls to suspicious hosts (raw IPs, .ru/.cn/.tk).
|
|
57
|
+
_SUSPICIOUS_HOST_RE = re.compile(
|
|
58
|
+
r"https?://(?:[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[^/\s]+\.(?:ru|cn|tk|onion))",
|
|
59
|
+
re.IGNORECASE,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Hidden HTML comments that might mask code.
|
|
63
|
+
_HTML_COMMENT_RE = re.compile(r"<!--.*?-->", re.DOTALL)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# ---- data model --------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass(frozen=True)
|
|
70
|
+
class SkillAuditIssue:
|
|
71
|
+
severity: str # "block" | "warn" | "info"
|
|
72
|
+
rule: str # short rule id (e.g. "pipe-exec")
|
|
73
|
+
message: str
|
|
74
|
+
excerpt: str = "" # the offending snippet, trimmed
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass
|
|
78
|
+
class SkillAuditVerdict:
|
|
79
|
+
skill_name: str
|
|
80
|
+
score: int # 0-100
|
|
81
|
+
verified: bool # iff no block issues
|
|
82
|
+
issues: list[SkillAuditIssue] = field(default_factory=list)
|
|
83
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def block_count(self) -> int:
|
|
87
|
+
return sum(1 for i in self.issues if i.severity == "block")
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def warn_count(self) -> int:
|
|
91
|
+
return sum(1 for i in self.issues if i.severity == "warn")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# ---- the audit ---------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _split_frontmatter(text: str) -> tuple[dict[str, Any], str]:
|
|
98
|
+
"""Split YAML frontmatter from the body. Returns (frontmatter, body)."""
|
|
99
|
+
m = re.match(r"^---\s*\n(.*?)\n---\s*\n", text, re.DOTALL)
|
|
100
|
+
if not m:
|
|
101
|
+
return {}, text
|
|
102
|
+
try:
|
|
103
|
+
front = yaml.safe_load(m.group(1)) or {}
|
|
104
|
+
except yaml.YAMLError:
|
|
105
|
+
front = {}
|
|
106
|
+
return (front if isinstance(front, dict) else {}), text[m.end():]
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def audit_skill_text(
|
|
110
|
+
text: str, *, skill_name: str = "<unnamed>",
|
|
111
|
+
) -> SkillAuditVerdict:
|
|
112
|
+
"""Audit a SKILL.md body in memory. Returns the structured verdict."""
|
|
113
|
+
issues: list[SkillAuditIssue] = []
|
|
114
|
+
front, body = _split_frontmatter(text)
|
|
115
|
+
|
|
116
|
+
# --- frontmatter sanity ---
|
|
117
|
+
if not front.get("name") and skill_name == "<unnamed>":
|
|
118
|
+
issues.append(SkillAuditIssue(
|
|
119
|
+
"warn", "missing-name",
|
|
120
|
+
"skill has no `name` in frontmatter or filename",
|
|
121
|
+
))
|
|
122
|
+
if not front.get("description"):
|
|
123
|
+
issues.append(SkillAuditIssue(
|
|
124
|
+
"warn", "missing-description",
|
|
125
|
+
"skill has no `description` — operators can't tell what it does",
|
|
126
|
+
))
|
|
127
|
+
allowed = front.get("allowed-tools") or ""
|
|
128
|
+
if isinstance(allowed, list):
|
|
129
|
+
allowed_str = " ".join(str(x) for x in allowed)
|
|
130
|
+
else:
|
|
131
|
+
allowed_str = str(allowed)
|
|
132
|
+
if _BASH_FREE_RE.search(" " + allowed_str + " "):
|
|
133
|
+
issues.append(SkillAuditIssue(
|
|
134
|
+
"warn", "unrestricted-bash",
|
|
135
|
+
"`allowed-tools` grants `Bash` without a glob — any shell "
|
|
136
|
+
"command runs without per-use approval",
|
|
137
|
+
))
|
|
138
|
+
if front.get("disable-model-invocation") is False and not front.get("description"):
|
|
139
|
+
issues.append(SkillAuditIssue(
|
|
140
|
+
"warn", "auto-invoke-no-desc",
|
|
141
|
+
"auto-invocable skill with no description — Claude can't "
|
|
142
|
+
"decide when to use it",
|
|
143
|
+
))
|
|
144
|
+
|
|
145
|
+
# --- body patterns ---
|
|
146
|
+
for match in _PIPE_EXEC_RE.finditer(body):
|
|
147
|
+
issues.append(SkillAuditIssue(
|
|
148
|
+
"block", "pipe-exec",
|
|
149
|
+
"downloads-and-executes pattern detected (curl|sh, wget|bash)",
|
|
150
|
+
excerpt=match.group(0)[:120],
|
|
151
|
+
))
|
|
152
|
+
for match in _OS_SYSTEM_RE.finditer(body):
|
|
153
|
+
issues.append(SkillAuditIssue(
|
|
154
|
+
"block", "shell-true-exec",
|
|
155
|
+
"subprocess with shell=True or os.system — arbitrary command exec",
|
|
156
|
+
excerpt=match.group(0)[:120],
|
|
157
|
+
))
|
|
158
|
+
# eval/exec is sometimes legitimate (e.g. in code samples) — flag as warn.
|
|
159
|
+
for match in _EVAL_EXEC_RE.finditer(body):
|
|
160
|
+
issues.append(SkillAuditIssue(
|
|
161
|
+
"warn", "eval-exec",
|
|
162
|
+
"eval/exec call present — may be safe but warrants review",
|
|
163
|
+
excerpt=match.group(0)[:120],
|
|
164
|
+
))
|
|
165
|
+
for match in _BASE64_RE.finditer(body):
|
|
166
|
+
issues.append(SkillAuditIssue(
|
|
167
|
+
"block", "opaque-blob",
|
|
168
|
+
"long base64-looking block (likely encoded payload)",
|
|
169
|
+
excerpt=match.group(0)[:60] + "…",
|
|
170
|
+
))
|
|
171
|
+
if _SCRIPT_TAG_RE.search(body):
|
|
172
|
+
issues.append(SkillAuditIssue(
|
|
173
|
+
"warn", "script-tag",
|
|
174
|
+
"<script> tag in markdown — unusual for a SKILL.md",
|
|
175
|
+
))
|
|
176
|
+
# Hidden HTML comments — count them; rarely needed in a SKILL.md.
|
|
177
|
+
comments = list(_HTML_COMMENT_RE.finditer(body))
|
|
178
|
+
if len(comments) > 5:
|
|
179
|
+
issues.append(SkillAuditIssue(
|
|
180
|
+
"info", "many-html-comments",
|
|
181
|
+
f"{len(comments)} HTML comments — could be hiding intent",
|
|
182
|
+
))
|
|
183
|
+
for match in _SUSPICIOUS_HOST_RE.finditer(body):
|
|
184
|
+
issues.append(SkillAuditIssue(
|
|
185
|
+
"warn", "suspicious-host",
|
|
186
|
+
f"URL points at a suspicious host: {match.group(0)[:80]}",
|
|
187
|
+
))
|
|
188
|
+
|
|
189
|
+
# Excessive size flag.
|
|
190
|
+
if len(text) > 200_000:
|
|
191
|
+
issues.append(SkillAuditIssue(
|
|
192
|
+
"warn", "excessive-size",
|
|
193
|
+
f"SKILL.md is {len(text):,} bytes — much larger than typical",
|
|
194
|
+
))
|
|
195
|
+
|
|
196
|
+
# --- score ---
|
|
197
|
+
block_n = sum(1 for i in issues if i.severity == "block")
|
|
198
|
+
warn_n = sum(1 for i in issues if i.severity == "warn")
|
|
199
|
+
info_n = sum(1 for i in issues if i.severity == "info")
|
|
200
|
+
# Hard cap: any block → score ≤ 30 + verified=False.
|
|
201
|
+
score = 100 - (block_n * 35) - (warn_n * 8) - (info_n * 2)
|
|
202
|
+
if block_n > 0:
|
|
203
|
+
score = min(score, 30)
|
|
204
|
+
score = max(0, min(100, score))
|
|
205
|
+
|
|
206
|
+
return SkillAuditVerdict(
|
|
207
|
+
skill_name=str(front.get("name") or skill_name),
|
|
208
|
+
score=score, verified=(block_n == 0),
|
|
209
|
+
issues=issues,
|
|
210
|
+
metadata={
|
|
211
|
+
"size_bytes": len(text),
|
|
212
|
+
"frontmatter_keys": sorted(front.keys()) if front else [],
|
|
213
|
+
"block": block_n, "warn": warn_n, "info": info_n,
|
|
214
|
+
},
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def audit_skill_file(path: str | Path) -> SkillAuditVerdict:
|
|
219
|
+
"""Audit a SKILL.md by path."""
|
|
220
|
+
p = Path(path)
|
|
221
|
+
try:
|
|
222
|
+
text = p.read_text()
|
|
223
|
+
except OSError as exc:
|
|
224
|
+
return SkillAuditVerdict(
|
|
225
|
+
skill_name=p.stem,
|
|
226
|
+
score=0, verified=False,
|
|
227
|
+
issues=[SkillAuditIssue(
|
|
228
|
+
"block", "unreadable",
|
|
229
|
+
f"cannot read {p}: {exc}",
|
|
230
|
+
)],
|
|
231
|
+
)
|
|
232
|
+
return audit_skill_text(text, skill_name=p.parent.name)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Skill discovery — search the curated marketplaces.
|
|
2
|
+
|
|
3
|
+
We don't try to be a general crawler. We rely on:
|
|
4
|
+
|
|
5
|
+
* The local SSOT catalog (``claude-plugins.yaml``) — every skill the
|
|
6
|
+
installer already knows about.
|
|
7
|
+
* The ``find-skills`` skill (Vercel Labs) — once installed, it's the
|
|
8
|
+
expert agent for live discovery via ``npx skills find``.
|
|
9
|
+
|
|
10
|
+
This module's job: return a normalised list of *known* skills, with
|
|
11
|
+
their marketplace + trust attribution, and let the CLI pass the list to
|
|
12
|
+
the auditor before any actual install.
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
import yaml
|
|
21
|
+
|
|
22
|
+
from omega_engine.skill_discovery.marketplaces import (
|
|
23
|
+
Marketplace,
|
|
24
|
+
load_marketplaces,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class DiscoveredSkill:
|
|
30
|
+
name: str
|
|
31
|
+
description: str
|
|
32
|
+
marketplace_id: str
|
|
33
|
+
marketplace_trust: str
|
|
34
|
+
scope: str # "user" | "project" | "local"
|
|
35
|
+
recommended: bool = False
|
|
36
|
+
secrets: list[str] = None # type: ignore[assignment]
|
|
37
|
+
category: str = ""
|
|
38
|
+
|
|
39
|
+
def __post_init__(self) -> None:
|
|
40
|
+
if self.secrets is None:
|
|
41
|
+
self.secrets = []
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def list_curated(omega_home: str | Path) -> list[DiscoveredSkill]:
|
|
45
|
+
"""Read the curated skill list from the SSOT catalog."""
|
|
46
|
+
path = (Path(omega_home) / "Agentik_SSOT" / "claude-plugins"
|
|
47
|
+
/ "claude-plugins.yaml")
|
|
48
|
+
if not path.exists():
|
|
49
|
+
return []
|
|
50
|
+
data = yaml.safe_load(path.read_text()) or {}
|
|
51
|
+
markets = {m.id: m for m in load_marketplaces(omega_home)}
|
|
52
|
+
out: list[DiscoveredSkill] = []
|
|
53
|
+
for entry in data.get("catalog") or []:
|
|
54
|
+
mid = entry.get("marketplace", "")
|
|
55
|
+
m = markets.get(mid)
|
|
56
|
+
out.append(DiscoveredSkill(
|
|
57
|
+
name=entry.get("name", entry.get("id", "?")),
|
|
58
|
+
description=entry.get("description", ""),
|
|
59
|
+
marketplace_id=mid,
|
|
60
|
+
marketplace_trust=(m.trust if m else "low"),
|
|
61
|
+
scope=entry.get("scope", "user"),
|
|
62
|
+
recommended=bool(entry.get("recommended", False)),
|
|
63
|
+
secrets=list(entry.get("secrets") or []),
|
|
64
|
+
category=entry.get("category", ""),
|
|
65
|
+
))
|
|
66
|
+
return out
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def discover_skills(
|
|
70
|
+
omega_home: str | Path,
|
|
71
|
+
*,
|
|
72
|
+
query: str | None = None,
|
|
73
|
+
min_trust: str = "low",
|
|
74
|
+
recommended_only: bool = False,
|
|
75
|
+
) -> list[DiscoveredSkill]:
|
|
76
|
+
"""Search the local catalog. ``query`` matches name + description
|
|
77
|
+
(case-insensitive substring). ``min_trust`` filters by marketplace
|
|
78
|
+
trust level. ``recommended_only`` returns only the curated picks.
|
|
79
|
+
"""
|
|
80
|
+
from omega_engine.skill_discovery.marketplaces import trust_floor
|
|
81
|
+
floor = trust_floor(min_trust)
|
|
82
|
+
out: list[DiscoveredSkill] = []
|
|
83
|
+
q = (query or "").strip().lower()
|
|
84
|
+
for s in list_curated(omega_home):
|
|
85
|
+
if recommended_only and not s.recommended:
|
|
86
|
+
continue
|
|
87
|
+
if trust_floor(s.marketplace_trust) < floor:
|
|
88
|
+
continue
|
|
89
|
+
if q:
|
|
90
|
+
hay = f"{s.name} {s.description}".lower()
|
|
91
|
+
if q not in hay:
|
|
92
|
+
continue
|
|
93
|
+
out.append(s)
|
|
94
|
+
return out
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""Validated skill installer — audit before write.
|
|
2
|
+
|
|
3
|
+
Two paths a skill can come from:
|
|
4
|
+
|
|
5
|
+
1. The Claude Code plugin marketplace (``claude plugin install
|
|
6
|
+
<name>@<marketplace>``). Step 45 of the OmegaOS installer handles
|
|
7
|
+
this for the curated list. We don't duplicate that path here.
|
|
8
|
+
|
|
9
|
+
2. Direct from a GitHub repo — `omega skill install <name>
|
|
10
|
+
--from github:<org>/<repo>[/<path>]`. We clone, locate the
|
|
11
|
+
``SKILL.md``, run the auditor, and only on a clean verdict copy
|
|
12
|
+
it into ``Agentik_SSOT/skills/<name>/``. ``omega sync`` then
|
|
13
|
+
projects it to ``~/.claude/skills/``.
|
|
14
|
+
|
|
15
|
+
We refuse to install if the auditor returns ``verified=False`` unless
|
|
16
|
+
the operator explicitly passes ``allow_blocked=True``.
|
|
17
|
+
"""
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import shutil
|
|
21
|
+
import subprocess
|
|
22
|
+
import tempfile
|
|
23
|
+
from dataclasses import dataclass
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
from omega_engine.skill_discovery.auditor import (
|
|
27
|
+
SkillAuditVerdict,
|
|
28
|
+
audit_skill_file,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class SkillInstallResult:
|
|
34
|
+
skill_name: str
|
|
35
|
+
installed: bool
|
|
36
|
+
skill_path: Path | None
|
|
37
|
+
audit: SkillAuditVerdict | None = None
|
|
38
|
+
reason: str = ""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _clone(repo: str, dest: Path) -> bool:
|
|
42
|
+
"""Shallow-clone a GitHub repo into ``dest``. Returns True on success."""
|
|
43
|
+
proc = subprocess.run(
|
|
44
|
+
["git", "clone", "--depth", "1",
|
|
45
|
+
f"https://github.com/{repo}.git", str(dest)],
|
|
46
|
+
check=False, capture_output=True, text=True, timeout=120,
|
|
47
|
+
)
|
|
48
|
+
return proc.returncode == 0
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def install_skill_from_github(
|
|
52
|
+
omega_home: str | Path,
|
|
53
|
+
skill_name: str,
|
|
54
|
+
*,
|
|
55
|
+
repo: str,
|
|
56
|
+
sub_path: str = "",
|
|
57
|
+
allow_blocked: bool = False,
|
|
58
|
+
) -> SkillInstallResult:
|
|
59
|
+
"""Install one skill from a GitHub repo.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
omega_home: ``$OMEGA_HOME`` — destination is
|
|
63
|
+
``$OMEGA_HOME/Agentik_SSOT/skills/<skill_name>/``.
|
|
64
|
+
skill_name: the directory name the skill will live under.
|
|
65
|
+
repo: ``org/repo`` (no ``github:`` prefix; no URL).
|
|
66
|
+
sub_path: optional path inside the repo where the SKILL.md
|
|
67
|
+
lives (e.g. ``skills/find-skills``). If empty, we try
|
|
68
|
+
``skills/<skill_name>/`` then the repo root.
|
|
69
|
+
allow_blocked: install even if the auditor returns
|
|
70
|
+
``verified=False``. Hard-fail by default.
|
|
71
|
+
|
|
72
|
+
Returns: ``SkillInstallResult``.
|
|
73
|
+
"""
|
|
74
|
+
home = Path(omega_home)
|
|
75
|
+
target = home / "Agentik_SSOT" / "skills" / skill_name
|
|
76
|
+
|
|
77
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
78
|
+
tmp_path = Path(tmp)
|
|
79
|
+
clone_dir = tmp_path / "src"
|
|
80
|
+
if not _clone(repo, clone_dir):
|
|
81
|
+
return SkillInstallResult(
|
|
82
|
+
skill_name=skill_name, installed=False, skill_path=None,
|
|
83
|
+
reason=f"git clone github:{repo} failed",
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Find the SKILL.md.
|
|
87
|
+
candidates = []
|
|
88
|
+
if sub_path:
|
|
89
|
+
candidates.append(clone_dir / sub_path / "SKILL.md")
|
|
90
|
+
candidates += [
|
|
91
|
+
clone_dir / "skills" / skill_name / "SKILL.md",
|
|
92
|
+
clone_dir / skill_name / "SKILL.md",
|
|
93
|
+
clone_dir / "SKILL.md",
|
|
94
|
+
]
|
|
95
|
+
skill_md = next((p for p in candidates if p.exists()), None)
|
|
96
|
+
if skill_md is None:
|
|
97
|
+
return SkillInstallResult(
|
|
98
|
+
skill_name=skill_name, installed=False, skill_path=None,
|
|
99
|
+
reason=f"no SKILL.md found in {repo} "
|
|
100
|
+
f"(looked at {[str(c.relative_to(clone_dir)) for c in candidates]})",
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# Audit.
|
|
104
|
+
verdict = audit_skill_file(skill_md)
|
|
105
|
+
if not verdict.verified and not allow_blocked:
|
|
106
|
+
return SkillInstallResult(
|
|
107
|
+
skill_name=skill_name, installed=False, skill_path=None,
|
|
108
|
+
audit=verdict,
|
|
109
|
+
reason=(
|
|
110
|
+
f"audit blocked install: {verdict.block_count} block + "
|
|
111
|
+
f"{verdict.warn_count} warn issue(s)"
|
|
112
|
+
),
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# Copy the skill directory (SKILL.md + any siblings — scripts/, examples/).
|
|
116
|
+
skill_dir = skill_md.parent
|
|
117
|
+
target.mkdir(parents=True, exist_ok=True)
|
|
118
|
+
for item in skill_dir.iterdir():
|
|
119
|
+
dest = target / item.name
|
|
120
|
+
if item.is_dir():
|
|
121
|
+
if dest.exists():
|
|
122
|
+
shutil.rmtree(dest)
|
|
123
|
+
shutil.copytree(item, dest)
|
|
124
|
+
else:
|
|
125
|
+
shutil.copy(item, dest)
|
|
126
|
+
return SkillInstallResult(
|
|
127
|
+
skill_name=skill_name, installed=True, skill_path=target,
|
|
128
|
+
audit=verdict,
|
|
129
|
+
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Marketplace catalog — every trusted source of Claude Code skills.
|
|
2
|
+
|
|
3
|
+
The catalog itself lives in YAML at
|
|
4
|
+
``Agentik_SSOT/claude-plugins/claude-plugins.yaml`` (extended in this
|
|
5
|
+
PR with ``trust`` and a few non-builtin marketplaces). This module
|
|
6
|
+
loads + filters it.
|
|
7
|
+
|
|
8
|
+
Trust levels:
|
|
9
|
+
|
|
10
|
+
* ``high`` — Anthropic, Vercel Labs, other vetted vendors. Auditor
|
|
11
|
+
still runs but warnings rarely block.
|
|
12
|
+
* ``medium`` — community marketplaces (davila7, thedotmack, etc.).
|
|
13
|
+
Auditor warnings get surfaced to the operator.
|
|
14
|
+
* ``low`` — random GitHub repos. Auditor hard-fails on anything
|
|
15
|
+
suspicious.
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from dataclasses import dataclass
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
import yaml
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class Marketplace:
|
|
28
|
+
id: str
|
|
29
|
+
source: str
|
|
30
|
+
description: str
|
|
31
|
+
trust: str = "medium" # "high" | "medium" | "low"
|
|
32
|
+
builtin: bool = False
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def is_github(self) -> bool:
|
|
36
|
+
return self.source.startswith("github:")
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def github_repo(self) -> str | None:
|
|
40
|
+
if not self.is_github:
|
|
41
|
+
return None
|
|
42
|
+
return self.source.split(":", 1)[1]
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def github_url(self) -> str | None:
|
|
46
|
+
repo = self.github_repo
|
|
47
|
+
return f"https://github.com/{repo}" if repo else None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def load_marketplaces(omega_home: str | Path) -> list[Marketplace]:
|
|
51
|
+
"""Read the marketplace list from the SSOT catalog."""
|
|
52
|
+
path = (Path(omega_home) / "Agentik_SSOT" / "claude-plugins"
|
|
53
|
+
/ "claude-plugins.yaml")
|
|
54
|
+
if not path.exists():
|
|
55
|
+
return []
|
|
56
|
+
data = yaml.safe_load(path.read_text()) or {}
|
|
57
|
+
out: list[Marketplace] = []
|
|
58
|
+
for m in data.get("marketplaces") or []:
|
|
59
|
+
out.append(Marketplace(
|
|
60
|
+
id=m["id"],
|
|
61
|
+
source=m.get("source", ""),
|
|
62
|
+
description=m.get("description", ""),
|
|
63
|
+
trust=m.get("trust", "medium"),
|
|
64
|
+
builtin=bool(m.get("builtin", False)),
|
|
65
|
+
))
|
|
66
|
+
return out
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_marketplace(
|
|
70
|
+
omega_home: str | Path, marketplace_id: str,
|
|
71
|
+
) -> Marketplace | None:
|
|
72
|
+
for m in load_marketplaces(omega_home):
|
|
73
|
+
if m.id == marketplace_id:
|
|
74
|
+
return m
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def trust_floor(trust: str) -> int:
|
|
79
|
+
"""Numeric trust floor — higher = more trust."""
|
|
80
|
+
return {"high": 3, "medium": 2, "low": 1}.get(trust.lower(), 0)
|