@trac3r/oh-my-god 2.2.11
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/CHANGELOG.md +188 -0
- package/INSTALL-VERIFICATION-INDEX.md +51 -0
- package/LICENSE +21 -0
- package/OMG-setup.sh +2549 -0
- package/QUICK-REFERENCE.md +58 -0
- package/README.md +207 -0
- package/agents/__init__.py +1 -0
- package/agents/__pycache__/model_roles.cpython-313.pyc +0 -0
- package/agents/_model_roles.yaml +26 -0
- package/agents/designer.md +67 -0
- package/agents/explore.md +60 -0
- package/agents/model_roles.py +196 -0
- package/agents/omg-api-builder.md +23 -0
- package/agents/omg-architect-mode.md +41 -0
- package/agents/omg-architect.md +13 -0
- package/agents/omg-backend-engineer.md +41 -0
- package/agents/omg-critic.md +16 -0
- package/agents/omg-database-engineer.md +41 -0
- package/agents/omg-escalation-router.md +17 -0
- package/agents/omg-executor.md +12 -0
- package/agents/omg-frontend-designer.md +41 -0
- package/agents/omg-implement-mode.md +49 -0
- package/agents/omg-infra-engineer.md +41 -0
- package/agents/omg-qa-tester.md +16 -0
- package/agents/omg-research-mode.md +41 -0
- package/agents/omg-security-auditor.md +41 -0
- package/agents/omg-testing-engineer.md +41 -0
- package/agents/plan.md +80 -0
- package/agents/quick_task.md +64 -0
- package/agents/reviewer.md +83 -0
- package/agents/task.md +71 -0
- package/bin/omg +41 -0
- package/commands/OMG:ai-commit.md +113 -0
- package/commands/OMG:api-twin.md +22 -0
- package/commands/OMG:arch.md +313 -0
- package/commands/OMG:browser.md +29 -0
- package/commands/OMG:ccg.md +22 -0
- package/commands/OMG:compat.md +57 -0
- package/commands/OMG:cost.md +181 -0
- package/commands/OMG:crazy.md +125 -0
- package/commands/OMG:create-agent.md +183 -0
- package/commands/OMG:deep-plan.md +18 -0
- package/commands/OMG:deps.md +248 -0
- package/commands/OMG:diagnose-plugins.md +33 -0
- package/commands/OMG:doctor.md +37 -0
- package/commands/OMG:domain-init.md +11 -0
- package/commands/OMG:escalate.md +52 -0
- package/commands/OMG:forge.md +103 -0
- package/commands/OMG:health-check.md +48 -0
- package/commands/OMG:init.md +134 -0
- package/commands/OMG:issue.md +56 -0
- package/commands/OMG:mode.md +44 -0
- package/commands/OMG:playwright.md +17 -0
- package/commands/OMG:preflight.md +26 -0
- package/commands/OMG:preset.md +49 -0
- package/commands/OMG:profile-review.md +58 -0
- package/commands/OMG:project-init.md +11 -0
- package/commands/OMG:ralph-start.md +43 -0
- package/commands/OMG:ralph-stop.md +23 -0
- package/commands/OMG:security-check.md +28 -0
- package/commands/OMG:session-branch.md +101 -0
- package/commands/OMG:session-fork.md +57 -0
- package/commands/OMG:session-merge.md +138 -0
- package/commands/OMG:setup.md +82 -0
- package/commands/OMG:ship.md +18 -0
- package/commands/OMG:stats.md +225 -0
- package/commands/OMG:teams.md +54 -0
- package/commands/OMG:theme.md +44 -0
- package/commands/OMG:validate.md +59 -0
- package/commands/__init__.py +1 -0
- package/docs/command-surface.md +55 -0
- package/docs/install/claude-code.md +53 -0
- package/docs/install/codex.md +45 -0
- package/docs/install/gemini.md +43 -0
- package/docs/install/github-action.md +81 -0
- package/docs/install/github-app-required-checks.md +107 -0
- package/docs/install/github-app.md +161 -0
- package/docs/install/kimi.md +43 -0
- package/docs/install/opencode.md +38 -0
- package/docs/proof.md +182 -0
- package/hooks/__init__.py +0 -0
- package/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_agent_registry.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_analytics.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_budget.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_common.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_compression_optimizer.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_cost_ledger.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_learnings.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_memory.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_post_write.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_protected_context.cpython-313.pyc +0 -0
- package/hooks/__pycache__/_token_counter.cpython-313.pyc +0 -0
- package/hooks/__pycache__/branch_manager.cpython-313.pyc +0 -0
- package/hooks/__pycache__/budget_governor.cpython-313.pyc +0 -0
- package/hooks/__pycache__/circuit-breaker.cpython-313.pyc +0 -0
- package/hooks/__pycache__/compression_feedback.cpython-313.pyc +0 -0
- package/hooks/__pycache__/config-guard.cpython-313.pyc +0 -0
- package/hooks/__pycache__/context_pressure.cpython-313.pyc +0 -0
- package/hooks/__pycache__/credential_store.cpython-313.pyc +0 -0
- package/hooks/__pycache__/fetch-rate-limits.cpython-313.pyc +0 -0
- package/hooks/__pycache__/firewall.cpython-313.pyc +0 -0
- package/hooks/__pycache__/hashline-formatter-bridge.cpython-313.pyc +0 -0
- package/hooks/__pycache__/hashline-injector.cpython-313.pyc +0 -0
- package/hooks/__pycache__/hashline-validator.cpython-313.pyc +0 -0
- package/hooks/__pycache__/idle-detector.cpython-313.pyc +0 -0
- package/hooks/__pycache__/instructions-loaded.cpython-313.pyc +0 -0
- package/hooks/__pycache__/intentgate-keyword-detector.cpython-313.pyc +0 -0
- package/hooks/__pycache__/magic-keyword-router.cpython-313.pyc +0 -0
- package/hooks/__pycache__/policy_engine.cpython-313.pyc +0 -0
- package/hooks/__pycache__/post-tool-failure.cpython-313.pyc +0 -0
- package/hooks/__pycache__/post-write.cpython-313.pyc +0 -0
- package/hooks/__pycache__/post_write.cpython-313.pyc +0 -0
- package/hooks/__pycache__/pre-compact.cpython-313.pyc +0 -0
- package/hooks/__pycache__/pre-tool-inject.cpython-313.pyc +0 -0
- package/hooks/__pycache__/prompt-enhancer.cpython-313.pyc +0 -0
- package/hooks/__pycache__/quality-runner.cpython-313.pyc +0 -0
- package/hooks/__pycache__/query.cpython-313.pyc +0 -0
- package/hooks/__pycache__/secret-guard.cpython-313.pyc +0 -0
- package/hooks/__pycache__/secret_audit.cpython-313.pyc +0 -0
- package/hooks/__pycache__/security_validators.cpython-313.pyc +0 -0
- package/hooks/__pycache__/session-end-capture.cpython-313.pyc +0 -0
- package/hooks/__pycache__/session-start.cpython-313.pyc +0 -0
- package/hooks/__pycache__/setup_wizard.cpython-313.pyc +0 -0
- package/hooks/__pycache__/shadow_manager.cpython-313.pyc +0 -0
- package/hooks/__pycache__/state_migration.cpython-313.pyc +0 -0
- package/hooks/__pycache__/stop-gate.cpython-313.pyc +0 -0
- package/hooks/__pycache__/stop_dispatcher.cpython-313.pyc +0 -0
- package/hooks/__pycache__/tdd-gate.cpython-313.pyc +0 -0
- package/hooks/__pycache__/terms-guard.cpython-313.pyc +0 -0
- package/hooks/__pycache__/test-validator.cpython-313.pyc +0 -0
- package/hooks/__pycache__/test_generator_hook.cpython-313.pyc +0 -0
- package/hooks/__pycache__/todo-state-tracker.cpython-313.pyc +0 -0
- package/hooks/__pycache__/tool-ledger.cpython-313.pyc +0 -0
- package/hooks/__pycache__/trust_review.cpython-313.pyc +0 -0
- package/hooks/__pycache__/user-prompt-submit.cpython-313.pyc +0 -0
- package/hooks/_agent_registry.py +481 -0
- package/hooks/_analytics.py +291 -0
- package/hooks/_budget.py +31 -0
- package/hooks/_common.py +761 -0
- package/hooks/_compression_optimizer.py +119 -0
- package/hooks/_cost_ledger.py +176 -0
- package/hooks/_learnings.py +126 -0
- package/hooks/_memory.py +103 -0
- package/hooks/_post_write.py +46 -0
- package/hooks/_protected_context.py +150 -0
- package/hooks/_token_counter.py +221 -0
- package/hooks/branch_manager.py +255 -0
- package/hooks/budget_governor.py +326 -0
- package/hooks/circuit-breaker.py +270 -0
- package/hooks/compression_feedback.py +254 -0
- package/hooks/config-guard.py +193 -0
- package/hooks/context_pressure.py +119 -0
- package/hooks/credential_store.py +970 -0
- package/hooks/fetch-rate-limits.py +212 -0
- package/hooks/firewall.py +323 -0
- package/hooks/hashline-formatter-bridge.py +224 -0
- package/hooks/hashline-injector.py +273 -0
- package/hooks/hashline-validator.py +216 -0
- package/hooks/idle-detector.py +97 -0
- package/hooks/instructions-loaded.py +26 -0
- package/hooks/intentgate-keyword-detector.py +200 -0
- package/hooks/magic-keyword-router.py +195 -0
- package/hooks/policy_engine.py +767 -0
- package/hooks/post-tool-failure.py +19 -0
- package/hooks/post-write.py +233 -0
- package/hooks/pre-compact.py +470 -0
- package/hooks/pre-tool-inject.py +98 -0
- package/hooks/prompt-enhancer.py +879 -0
- package/hooks/quality-runner.py +191 -0
- package/hooks/query.py +512 -0
- package/hooks/secret-guard.py +120 -0
- package/hooks/secret_audit.py +144 -0
- package/hooks/security_validators.py +93 -0
- package/hooks/session-end-capture.py +505 -0
- package/hooks/session-start.py +261 -0
- package/hooks/setup_wizard.py +1101 -0
- package/hooks/shadow_manager.py +476 -0
- package/hooks/state_migration.py +228 -0
- package/hooks/stop-gate.py +7 -0
- package/hooks/stop_dispatcher.py +1259 -0
- package/hooks/tdd-gate.py +10 -0
- package/hooks/terms-guard.py +98 -0
- package/hooks/test-validator.py +462 -0
- package/hooks/test_generator_hook.py +123 -0
- package/hooks/todo-state-tracker.py +114 -0
- package/hooks/tool-ledger.py +165 -0
- package/hooks/trust_review.py +662 -0
- package/hooks/user-prompt-submit.py +12 -0
- package/hud/omg-hud.mjs +1571 -0
- package/lab/__init__.py +1 -0
- package/lab/__pycache__/__init__.cpython-313.pyc +0 -0
- package/lab/__pycache__/axolotl_adapter.cpython-313.pyc +0 -0
- package/lab/__pycache__/forge_runner.cpython-313.pyc +0 -0
- package/lab/__pycache__/gazebo_adapter.cpython-313.pyc +0 -0
- package/lab/__pycache__/isaac_gym_adapter.cpython-313.pyc +0 -0
- package/lab/__pycache__/mock_isaac_env.cpython-313.pyc +0 -0
- package/lab/__pycache__/pipeline.cpython-313.pyc +0 -0
- package/lab/__pycache__/policies.cpython-313.pyc +0 -0
- package/lab/__pycache__/pybullet_adapter.cpython-313.pyc +0 -0
- package/lab/axolotl_adapter.py +531 -0
- package/lab/forge_runner.py +103 -0
- package/lab/gazebo_adapter.py +168 -0
- package/lab/isaac_gym_adapter.py +190 -0
- package/lab/mock_isaac_env.py +47 -0
- package/lab/pipeline.py +712 -0
- package/lab/policies.py +52 -0
- package/lab/pybullet_adapter.py +192 -0
- package/package.json +61 -0
- package/plugins/README.md +78 -0
- package/plugins/__init__.py +1 -0
- package/plugins/__pycache__/__init__.cpython-313.pyc +0 -0
- package/plugins/advanced/commands/OMG-code-review.md +114 -0
- package/plugins/advanced/commands/OMG-deep-plan.md +266 -0
- package/plugins/advanced/commands/OMG-handoff.md +115 -0
- package/plugins/advanced/commands/OMG-learn.md +110 -0
- package/plugins/advanced/commands/OMG-maintainer.md +31 -0
- package/plugins/advanced/commands/OMG-ralph-start.md +43 -0
- package/plugins/advanced/commands/OMG-ralph-stop.md +23 -0
- package/plugins/advanced/commands/OMG-security-review.md +16 -0
- package/plugins/advanced/commands/OMG-sequential-thinking.md +20 -0
- package/plugins/advanced/commands/OMG-ship.md +46 -0
- package/plugins/advanced/commands/OMG:code-review.md +114 -0
- package/plugins/advanced/commands/OMG:deep-plan.md +266 -0
- package/plugins/advanced/commands/OMG:handoff.md +115 -0
- package/plugins/advanced/commands/OMG:learn.md +110 -0
- package/plugins/advanced/commands/OMG:maintainer.md +31 -0
- package/plugins/advanced/commands/OMG:ralph-start.md +43 -0
- package/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
- package/plugins/advanced/commands/OMG:security-review.md +16 -0
- package/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
- package/plugins/advanced/commands/OMG:ship.md +46 -0
- package/plugins/advanced/plugin.json +104 -0
- package/plugins/core/plugin.json +204 -0
- package/plugins/dephealth/__init__.py +0 -0
- package/plugins/dephealth/__pycache__/__init__.cpython-313.pyc +0 -0
- package/plugins/dephealth/__pycache__/cve_scanner.cpython-313.pyc +0 -0
- package/plugins/dephealth/__pycache__/license_checker.cpython-313.pyc +0 -0
- package/plugins/dephealth/__pycache__/manifest_detector.cpython-313.pyc +0 -0
- package/plugins/dephealth/__pycache__/vuln_analyzer.cpython-313.pyc +0 -0
- package/plugins/dephealth/cve_scanner.py +279 -0
- package/plugins/dephealth/license_checker.py +135 -0
- package/plugins/dephealth/manifest_detector.py +423 -0
- package/plugins/dephealth/vuln_analyzer.py +176 -0
- package/plugins/testgen/__init__.py +0 -0
- package/plugins/testgen/__pycache__/__init__.cpython-313.pyc +0 -0
- package/plugins/testgen/__pycache__/codamosa_engine.cpython-313.pyc +0 -0
- package/plugins/testgen/__pycache__/edge_case_synthesizer.cpython-313.pyc +0 -0
- package/plugins/testgen/__pycache__/framework_detector.cpython-313.pyc +0 -0
- package/plugins/testgen/__pycache__/skeleton_generator.cpython-313.pyc +0 -0
- package/plugins/testgen/codamosa_engine.py +402 -0
- package/plugins/testgen/edge_case_synthesizer.py +184 -0
- package/plugins/testgen/framework_detector.py +271 -0
- package/plugins/testgen/skeleton_generator.py +219 -0
- package/plugins/viz/__init__.py +0 -0
- package/plugins/viz/__pycache__/__init__.cpython-313.pyc +0 -0
- package/plugins/viz/__pycache__/ast_parser.cpython-313.pyc +0 -0
- package/plugins/viz/__pycache__/diagram_generator.cpython-313.pyc +0 -0
- package/plugins/viz/__pycache__/graph_builder.cpython-313.pyc +0 -0
- package/plugins/viz/__pycache__/native_parsers.cpython-313.pyc +0 -0
- package/plugins/viz/__pycache__/regex_parser.cpython-313.pyc +0 -0
- package/plugins/viz/ast_parser.py +139 -0
- package/plugins/viz/diagram_generator.py +192 -0
- package/plugins/viz/graph_builder.py +444 -0
- package/plugins/viz/native_parsers.py +259 -0
- package/plugins/viz/regex_parser.py +112 -0
- package/pyproject.toml +143 -0
- package/registry/__init__.py +1 -0
- package/registry/__pycache__/__init__.cpython-313.pyc +0 -0
- package/registry/__pycache__/approval_artifact.cpython-313.pyc +0 -0
- package/registry/__pycache__/verify_artifact.cpython-313.pyc +0 -0
- package/registry/approval_artifact.py +236 -0
- package/registry/bundles/algorithms.yaml +45 -0
- package/registry/bundles/api-twin.yaml +48 -0
- package/registry/bundles/ast-pack.yaml +80 -0
- package/registry/bundles/claim-judge.yaml +49 -0
- package/registry/bundles/control-plane.yaml +192 -0
- package/registry/bundles/data-lineage.yaml +47 -0
- package/registry/bundles/delta-classifier.yaml +47 -0
- package/registry/bundles/eval-gate.yaml +47 -0
- package/registry/bundles/hash-edit.yaml +73 -0
- package/registry/bundles/health.yaml +45 -0
- package/registry/bundles/hook-governor.yaml +101 -0
- package/registry/bundles/incident-replay.yaml +47 -0
- package/registry/bundles/lsp-pack.yaml +80 -0
- package/registry/bundles/mcp-fabric.yaml +53 -0
- package/registry/bundles/plan-council.yaml +56 -0
- package/registry/bundles/preflight.yaml +48 -0
- package/registry/bundles/proof-gate.yaml +49 -0
- package/registry/bundles/remote-supervisor.yaml +49 -0
- package/registry/bundles/robotics.yaml +45 -0
- package/registry/bundles/secure-worktree-pipeline.yaml +69 -0
- package/registry/bundles/security-check.yaml +50 -0
- package/registry/bundles/terminal-lane.yaml +61 -0
- package/registry/bundles/test-intent-lock.yaml +49 -0
- package/registry/bundles/tracebank.yaml +47 -0
- package/registry/bundles/vision.yaml +45 -0
- package/registry/omg-capability.schema.json +378 -0
- package/registry/policy-packs/airgapped.lock.json +11 -0
- package/registry/policy-packs/airgapped.signature.json +10 -0
- package/registry/policy-packs/airgapped.yaml +16 -0
- package/registry/policy-packs/fintech.lock.json +11 -0
- package/registry/policy-packs/fintech.signature.json +10 -0
- package/registry/policy-packs/fintech.yaml +15 -0
- package/registry/policy-packs/locked-prod.lock.json +11 -0
- package/registry/policy-packs/locked-prod.signature.json +10 -0
- package/registry/policy-packs/locked-prod.yaml +18 -0
- package/registry/trusted_signers.json +44 -0
- package/registry/verify_artifact.py +493 -0
- package/runtime/__init__.py +36 -0
- package/runtime/__pycache__/__init__.cpython-313.pyc +0 -0
- package/runtime/__pycache__/adoption.cpython-313.pyc +0 -0
- package/runtime/__pycache__/agent_selector.cpython-313.pyc +0 -0
- package/runtime/__pycache__/api_twin.cpython-313.pyc +0 -0
- package/runtime/__pycache__/architecture_signal.cpython-313.pyc +0 -0
- package/runtime/__pycache__/artifact_parsers.cpython-313.pyc +0 -0
- package/runtime/__pycache__/asset_loader.cpython-313.pyc +0 -0
- package/runtime/__pycache__/background_verification.cpython-313.pyc +0 -0
- package/runtime/__pycache__/budget_envelopes.cpython-313.pyc +0 -0
- package/runtime/__pycache__/business_workflow.cpython-313.pyc +0 -0
- package/runtime/__pycache__/canonical_surface.cpython-313.pyc +0 -0
- package/runtime/__pycache__/canonical_taxonomy.cpython-313.pyc +0 -0
- package/runtime/__pycache__/claim_judge.cpython-313.pyc +0 -0
- package/runtime/__pycache__/cli_provider.cpython-313.pyc +0 -0
- package/runtime/__pycache__/compat.cpython-313.pyc +0 -0
- package/runtime/__pycache__/complexity_scorer.cpython-313.pyc +0 -0
- package/runtime/__pycache__/compliance_governor.cpython-313.pyc +0 -0
- package/runtime/__pycache__/config_transaction.cpython-313.pyc +0 -0
- package/runtime/__pycache__/context_compiler.cpython-313.pyc +0 -0
- package/runtime/__pycache__/context_engine.cpython-313.pyc +0 -0
- package/runtime/__pycache__/context_limits.cpython-313.pyc +0 -0
- package/runtime/__pycache__/contract_compiler.cpython-313.pyc +0 -0
- package/runtime/__pycache__/custom_agent_loader.cpython-313.pyc +0 -0
- package/runtime/__pycache__/data_lineage.cpython-313.pyc +0 -0
- package/runtime/__pycache__/defense_state.cpython-313.pyc +0 -0
- package/runtime/__pycache__/delta_classifier.cpython-313.pyc +0 -0
- package/runtime/__pycache__/dispatcher.cpython-313.pyc +0 -0
- package/runtime/__pycache__/doc_generator.cpython-313.pyc +0 -0
- package/runtime/__pycache__/domain_packs.cpython-313.pyc +0 -0
- package/runtime/__pycache__/ecosystem.cpython-313.pyc +0 -0
- package/runtime/__pycache__/equalizer.cpython-313.pyc +0 -0
- package/runtime/__pycache__/eval_gate.cpython-313.pyc +0 -0
- package/runtime/__pycache__/evidence_narrator.cpython-313.pyc +0 -0
- package/runtime/__pycache__/evidence_query.cpython-313.pyc +0 -0
- package/runtime/__pycache__/evidence_registry.cpython-313.pyc +0 -0
- package/runtime/__pycache__/evidence_requirements.cpython-313.pyc +0 -0
- package/runtime/__pycache__/exec_kernel.cpython-313.pyc +0 -0
- package/runtime/__pycache__/explainer_formatter.cpython-313.pyc +0 -0
- package/runtime/__pycache__/feature_registry.cpython-313.pyc +0 -0
- package/runtime/__pycache__/forge_agents.cpython-313.pyc +0 -0
- package/runtime/__pycache__/forge_contracts.cpython-313.pyc +0 -0
- package/runtime/__pycache__/forge_domains.cpython-313.pyc +0 -0
- package/runtime/__pycache__/forge_run_id.cpython-313.pyc +0 -0
- package/runtime/__pycache__/github_integration.cpython-313.pyc +0 -0
- package/runtime/__pycache__/github_review_bot.cpython-313.pyc +0 -0
- package/runtime/__pycache__/github_review_contract.cpython-313.pyc +0 -0
- package/runtime/__pycache__/github_review_formatter.cpython-313.pyc +0 -0
- package/runtime/__pycache__/guide_assert.cpython-313.pyc +0 -0
- package/runtime/__pycache__/hook_governor.cpython-313.pyc +0 -0
- package/runtime/__pycache__/host_parity.cpython-313.pyc +0 -0
- package/runtime/__pycache__/incident_replay.cpython-313.pyc +0 -0
- package/runtime/__pycache__/install_planner.cpython-313.pyc +0 -0
- package/runtime/__pycache__/interaction_journal.cpython-313.pyc +0 -0
- package/runtime/__pycache__/issue_surface.cpython-313.pyc +0 -0
- package/runtime/__pycache__/legacy_compat.cpython-313.pyc +0 -0
- package/runtime/__pycache__/mcp_config_writers.cpython-313.pyc +0 -0
- package/runtime/__pycache__/mcp_lifecycle.cpython-313.pyc +0 -0
- package/runtime/__pycache__/mcp_memory_server.cpython-313.pyc +0 -0
- package/runtime/__pycache__/memory_store.cpython-313.pyc +0 -0
- package/runtime/__pycache__/merge_writer.cpython-313.pyc +0 -0
- package/runtime/__pycache__/music_omr_testbed.cpython-313.pyc +0 -0
- package/runtime/__pycache__/mutation_gate.cpython-313.pyc +0 -0
- package/runtime/__pycache__/omc_compat.cpython-313.pyc +0 -0
- package/runtime/__pycache__/omg_browser_cli.cpython-313.pyc +0 -0
- package/runtime/__pycache__/omg_mcp_server.cpython-313.pyc +0 -0
- package/runtime/__pycache__/opus_plan.cpython-313.pyc +0 -0
- package/runtime/__pycache__/playwright_adapter.cpython-313.pyc +0 -0
- package/runtime/__pycache__/playwright_pack.cpython-313.pyc +0 -0
- package/runtime/__pycache__/plugin_diagnostics.cpython-313.pyc +0 -0
- package/runtime/__pycache__/plugin_interop.cpython-313.pyc +0 -0
- package/runtime/__pycache__/policy_pack_loader.cpython-313.pyc +0 -0
- package/runtime/__pycache__/preflight.cpython-313.pyc +0 -0
- package/runtime/__pycache__/profile_io.cpython-313.pyc +0 -0
- package/runtime/__pycache__/prompt_compiler.cpython-313.pyc +0 -0
- package/runtime/__pycache__/proof_chain.cpython-313.pyc +0 -0
- package/runtime/__pycache__/proof_gate.cpython-313.pyc +0 -0
- package/runtime/__pycache__/provider_parity_eval.cpython-313.pyc +0 -0
- package/runtime/__pycache__/release_artifact_audit.cpython-313.pyc +0 -0
- package/runtime/__pycache__/release_run_coordinator.cpython-313.pyc +0 -0
- package/runtime/__pycache__/release_surface_compiler.cpython-313.pyc +0 -0
- package/runtime/__pycache__/release_surface_registry.cpython-313.pyc +0 -0
- package/runtime/__pycache__/release_surfaces.cpython-313.pyc +0 -0
- package/runtime/__pycache__/remote_supervisor.cpython-313.pyc +0 -0
- package/runtime/__pycache__/repro_pack.cpython-313.pyc +0 -0
- package/runtime/__pycache__/rollback_manifest.cpython-313.pyc +0 -0
- package/runtime/__pycache__/router_critics.cpython-313.pyc +0 -0
- package/runtime/__pycache__/router_executor.cpython-313.pyc +0 -0
- package/runtime/__pycache__/router_selector.cpython-313.pyc +0 -0
- package/runtime/__pycache__/runtime_contracts.cpython-313.pyc +0 -0
- package/runtime/__pycache__/runtime_profile.cpython-313.pyc +0 -0
- package/runtime/__pycache__/security_check.cpython-313.pyc +0 -0
- package/runtime/__pycache__/session_health.cpython-313.pyc +0 -0
- package/runtime/__pycache__/skill_evolution.cpython-313.pyc +0 -0
- package/runtime/__pycache__/skill_registry.cpython-313.pyc +0 -0
- package/runtime/__pycache__/subagent_dispatcher.cpython-313.pyc +0 -0
- package/runtime/__pycache__/subscription_tiers.cpython-313.pyc +0 -0
- package/runtime/__pycache__/team_router.cpython-313.pyc +0 -0
- package/runtime/__pycache__/test_intent_lock.cpython-313-pytest-9.0.2.pyc +0 -0
- package/runtime/__pycache__/test_intent_lock.cpython-313.pyc +0 -0
- package/runtime/__pycache__/tmux_session_manager.cpython-313.pyc +0 -0
- package/runtime/__pycache__/tool_fabric.cpython-313.pyc +0 -0
- package/runtime/__pycache__/tool_plan_gate.cpython-313.pyc +0 -0
- package/runtime/__pycache__/tool_relevance.cpython-313.pyc +0 -0
- package/runtime/__pycache__/tracebank.cpython-313.pyc +0 -0
- package/runtime/__pycache__/untrusted_content.cpython-313.pyc +0 -0
- package/runtime/__pycache__/validate.cpython-313.pyc +0 -0
- package/runtime/__pycache__/verdict_schema.cpython-313.pyc +0 -0
- package/runtime/__pycache__/verification_controller.cpython-313.pyc +0 -0
- package/runtime/__pycache__/verification_loop.cpython-313.pyc +0 -0
- package/runtime/__pycache__/vision_artifacts.cpython-313.pyc +0 -0
- package/runtime/__pycache__/vision_cache.cpython-313.pyc +0 -0
- package/runtime/__pycache__/vision_jobs.cpython-313.pyc +0 -0
- package/runtime/__pycache__/worker_watchdog.cpython-313.pyc +0 -0
- package/runtime/adapters/__init__.py +13 -0
- package/runtime/adapters/__pycache__/__init__.cpython-313.pyc +0 -0
- package/runtime/adapters/__pycache__/claude.cpython-313.pyc +0 -0
- package/runtime/adapters/__pycache__/gpt.cpython-313.pyc +0 -0
- package/runtime/adapters/__pycache__/local.cpython-313.pyc +0 -0
- package/runtime/adapters/claude.py +63 -0
- package/runtime/adapters/gpt.py +56 -0
- package/runtime/adapters/local.py +56 -0
- package/runtime/adoption.py +280 -0
- package/runtime/api_twin.py +450 -0
- package/runtime/architecture_signal.py +226 -0
- package/runtime/artifact_parsers.py +161 -0
- package/runtime/asset_loader.py +62 -0
- package/runtime/background_verification.py +178 -0
- package/runtime/budget_envelopes.py +398 -0
- package/runtime/business_workflow.py +234 -0
- package/runtime/canonical_surface.py +53 -0
- package/runtime/canonical_taxonomy.py +27 -0
- package/runtime/claim_judge.py +648 -0
- package/runtime/cli_provider.py +105 -0
- package/runtime/compat.py +2222 -0
- package/runtime/complexity_scorer.py +148 -0
- package/runtime/compliance_governor.py +505 -0
- package/runtime/config_transaction.py +304 -0
- package/runtime/context_compiler.py +131 -0
- package/runtime/context_engine.py +708 -0
- package/runtime/context_limits.py +363 -0
- package/runtime/contract_compiler.py +3664 -0
- package/runtime/custom_agent_loader.py +366 -0
- package/runtime/data_lineage.py +244 -0
- package/runtime/defense_state.py +261 -0
- package/runtime/delta_classifier.py +231 -0
- package/runtime/dispatcher.py +47 -0
- package/runtime/doc_generator.py +319 -0
- package/runtime/domain_packs.py +75 -0
- package/runtime/ecosystem.py +371 -0
- package/runtime/equalizer.py +268 -0
- package/runtime/eval_gate.py +96 -0
- package/runtime/evidence_narrator.py +147 -0
- package/runtime/evidence_query.py +303 -0
- package/runtime/evidence_registry.py +16 -0
- package/runtime/evidence_requirements.py +157 -0
- package/runtime/exec_kernel.py +267 -0
- package/runtime/explainer_formatter.py +82 -0
- package/runtime/feature_registry.py +109 -0
- package/runtime/forge_agents.py +915 -0
- package/runtime/forge_contracts.py +519 -0
- package/runtime/forge_domains.py +68 -0
- package/runtime/forge_run_id.py +86 -0
- package/runtime/guide_assert.py +135 -0
- package/runtime/hook_governor.py +156 -0
- package/runtime/host_parity.py +373 -0
- package/runtime/incident_replay.py +310 -0
- package/runtime/install_planner.py +617 -0
- package/runtime/interaction_journal.py +566 -0
- package/runtime/issue_surface.py +472 -0
- package/runtime/legacy_compat.py +7 -0
- package/runtime/mcp_config_writers.py +360 -0
- package/runtime/mcp_lifecycle.py +175 -0
- package/runtime/mcp_memory_server.py +220 -0
- package/runtime/memory_parsers/__init__.py +0 -0
- package/runtime/memory_parsers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/runtime/memory_parsers/__pycache__/chatgpt_parser.cpython-313.pyc +0 -0
- package/runtime/memory_parsers/__pycache__/claude_import.cpython-313.pyc +0 -0
- package/runtime/memory_parsers/__pycache__/export.cpython-313.pyc +0 -0
- package/runtime/memory_parsers/__pycache__/gemini_import.cpython-313.pyc +0 -0
- package/runtime/memory_parsers/__pycache__/kimi_import.cpython-313.pyc +0 -0
- package/runtime/memory_parsers/chatgpt_parser.py +257 -0
- package/runtime/memory_parsers/claude_import.py +107 -0
- package/runtime/memory_parsers/export.py +97 -0
- package/runtime/memory_parsers/gemini_import.py +91 -0
- package/runtime/memory_parsers/kimi_import.py +91 -0
- package/runtime/memory_store.py +1182 -0
- package/runtime/merge_writer.py +445 -0
- package/runtime/music_omr_testbed.py +336 -0
- package/runtime/mutation_gate.py +320 -0
- package/runtime/omc_compat.py +7 -0
- package/runtime/omg_browser_cli.py +95 -0
- package/runtime/omg_compat_contract_snapshot.json +936 -0
- package/runtime/omg_contract_snapshot.json +936 -0
- package/runtime/omg_mcp_server.py +306 -0
- package/runtime/playwright_adapter.py +39 -0
- package/runtime/playwright_pack.py +253 -0
- package/runtime/plugin_diagnostics.py +308 -0
- package/runtime/plugin_interop.py +1060 -0
- package/runtime/policy_pack_loader.py +147 -0
- package/runtime/preflight.py +135 -0
- package/runtime/profile_io.py +328 -0
- package/runtime/proof_chain.py +472 -0
- package/runtime/proof_gate.py +442 -0
- package/runtime/provider_parity_eval.py +109 -0
- package/runtime/providers/__init__.py +0 -0
- package/runtime/providers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/runtime/providers/__pycache__/codex_provider.cpython-313.pyc +0 -0
- package/runtime/providers/__pycache__/gemini_provider.cpython-313.pyc +0 -0
- package/runtime/providers/__pycache__/kimi_provider.cpython-313.pyc +0 -0
- package/runtime/providers/__pycache__/opencode_provider.cpython-313.pyc +0 -0
- package/runtime/providers/codex_provider.py +129 -0
- package/runtime/providers/gemini_provider.py +143 -0
- package/runtime/providers/kimi_provider.py +167 -0
- package/runtime/providers/opencode_provider.py +99 -0
- package/runtime/release_artifact_audit.py +556 -0
- package/runtime/release_run_coordinator.py +574 -0
- package/runtime/release_surface_compiler.py +643 -0
- package/runtime/release_surface_registry.py +283 -0
- package/runtime/release_surfaces.py +320 -0
- package/runtime/remote_supervisor.py +79 -0
- package/runtime/repro_pack.py +398 -0
- package/runtime/rollback_manifest.py +143 -0
- package/runtime/router_critics.py +229 -0
- package/runtime/router_executor.py +142 -0
- package/runtime/router_selector.py +99 -0
- package/runtime/runtime_contracts.py +292 -0
- package/runtime/runtime_profile.py +133 -0
- package/runtime/security_check.py +1094 -0
- package/runtime/session_health.py +546 -0
- package/runtime/skill_evolution.py +221 -0
- package/runtime/skill_registry.py +53 -0
- package/runtime/subagent_dispatcher.py +604 -0
- package/runtime/subscription_tiers.py +258 -0
- package/runtime/team_router.py +1399 -0
- package/runtime/test_intent_lock.py +543 -0
- package/runtime/tmux_session_manager.py +172 -0
- package/runtime/tool_fabric.py +570 -0
- package/runtime/tool_plan_gate.py +460 -0
- package/runtime/tracebank.py +125 -0
- package/runtime/untrusted_content.py +360 -0
- package/runtime/validate.py +293 -0
- package/runtime/verdict_schema.py +198 -0
- package/runtime/verification_controller.py +235 -0
- package/runtime/verification_loop.py +73 -0
- package/runtime/vision_artifacts.py +31 -0
- package/runtime/vision_cache.py +38 -0
- package/runtime/vision_jobs.py +92 -0
- package/runtime/worker_watchdog.py +526 -0
- package/scripts/__pycache__/audit-published-artifact.cpython-313.pyc +0 -0
- package/scripts/__pycache__/check-doc-parity.cpython-313.pyc +0 -0
- package/scripts/__pycache__/check-omg-standalone-clean.cpython-313.pyc +0 -0
- package/scripts/__pycache__/github_review_helpers.cpython-313.pyc +0 -0
- package/scripts/__pycache__/omg.cpython-313.pyc +0 -0
- package/scripts/__pycache__/prepare-release-proof-fixtures.cpython-313.pyc +0 -0
- package/scripts/__pycache__/sync-release-identity.cpython-313.pyc +0 -0
- package/scripts/__pycache__/validate-release-identity.cpython-313.pyc +0 -0
- package/scripts/audit-published-artifact.py +59 -0
- package/scripts/check-omg-compat-contract-snapshot.py +137 -0
- package/scripts/check-omg-contract-snapshot.py +12 -0
- package/scripts/check-omg-public-ready.py +273 -0
- package/scripts/check-omg-standalone-clean.py +133 -0
- package/scripts/emit_host_parity.py +72 -0
- package/scripts/legacy_to_omg_migrate.py +29 -0
- package/scripts/migrate-legacy.py +464 -0
- package/scripts/omc_to_omg_migrate.py +12 -0
- package/scripts/omg.py +2962 -0
- package/scripts/pre-release-check.sh +38 -0
- package/scripts/prepare-release-proof-fixtures.py +602 -0
- package/scripts/print-canonical-version.py +80 -0
- package/scripts/settings-merge.py +289 -0
- package/scripts/sync-release-identity.py +481 -0
- package/scripts/validate-release-identity.py +632 -0
- package/scripts/verify-no-omc.sh +5 -0
- package/scripts/verify-standalone.sh +35 -0
- package/settings.json +751 -0
- package/tools/__init__.py +2 -0
- package/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- package/tools/__pycache__/browser_consent.cpython-313.pyc +0 -0
- package/tools/__pycache__/browser_stealth.cpython-313.pyc +0 -0
- package/tools/__pycache__/browser_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/changelog_generator.cpython-313.pyc +0 -0
- package/tools/__pycache__/commit_splitter.cpython-313.pyc +0 -0
- package/tools/__pycache__/config_discovery.cpython-313.pyc +0 -0
- package/tools/__pycache__/config_merger.cpython-313.pyc +0 -0
- package/tools/__pycache__/dashboard_generator.cpython-313.pyc +0 -0
- package/tools/__pycache__/git_inspector.cpython-313.pyc +0 -0
- package/tools/__pycache__/lsp_client.cpython-313.pyc +0 -0
- package/tools/__pycache__/lsp_operations.cpython-313.pyc +0 -0
- package/tools/__pycache__/pr_generator.cpython-313.pyc +0 -0
- package/tools/__pycache__/python_repl.cpython-313.pyc +0 -0
- package/tools/__pycache__/python_sandbox.cpython-313.pyc +0 -0
- package/tools/__pycache__/session_snapshot.cpython-313.pyc +0 -0
- package/tools/__pycache__/ssh_manager.cpython-313.pyc +0 -0
- package/tools/__pycache__/theme_engine.cpython-313.pyc +0 -0
- package/tools/__pycache__/theme_selector.cpython-313.pyc +0 -0
- package/tools/__pycache__/web_search.cpython-313.pyc +0 -0
- package/tools/browser_consent.py +289 -0
- package/tools/browser_stealth.py +481 -0
- package/tools/browser_tool.py +448 -0
- package/tools/changelog_generator.py +347 -0
- package/tools/commit_splitter.py +749 -0
- package/tools/config_discovery.py +151 -0
- package/tools/config_merger.py +449 -0
- package/tools/dashboard_generator.py +300 -0
- package/tools/git_inspector.py +298 -0
- package/tools/lsp_client.py +275 -0
- package/tools/lsp_discovery.py +231 -0
- package/tools/lsp_operations.py +392 -0
- package/tools/pr_generator.py +404 -0
- package/tools/python_repl.py +712 -0
- package/tools/python_sandbox.py +768 -0
- package/tools/search_providers/__init__.py +77 -0
- package/tools/search_providers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/tools/search_providers/__pycache__/brave.cpython-313.pyc +0 -0
- package/tools/search_providers/__pycache__/exa.cpython-313.pyc +0 -0
- package/tools/search_providers/__pycache__/jina.cpython-313.pyc +0 -0
- package/tools/search_providers/__pycache__/perplexity.cpython-313.pyc +0 -0
- package/tools/search_providers/__pycache__/synthetic.cpython-313.pyc +0 -0
- package/tools/search_providers/brave.py +115 -0
- package/tools/search_providers/exa.py +116 -0
- package/tools/search_providers/jina.py +104 -0
- package/tools/search_providers/perplexity.py +139 -0
- package/tools/search_providers/synthetic.py +74 -0
- package/tools/session_snapshot.py +851 -0
- package/tools/ssh_manager.py +912 -0
- package/tools/theme_engine.py +296 -0
- package/tools/theme_selector.py +137 -0
- package/tools/web_search.py +675 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""Codex CLI provider — implements CLIProvider for the ``codex`` binary."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import shlex
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
import uuid
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from runtime.cli_provider import CLIProvider, register_provider
|
|
14
|
+
from runtime.host_parity import normalize_output
|
|
15
|
+
from runtime.mcp_config_writers import write_codex_mcp_config
|
|
16
|
+
from runtime.release_run_coordinator import build_release_env_prefix
|
|
17
|
+
from runtime.tmux_session_manager import TmuxSessionManager
|
|
18
|
+
|
|
19
|
+
_logger = logging.getLogger(__name__)
|
|
20
|
+
_AUTH_CHECK_TIMEOUT_SECONDS = 5
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _attach_normalized_output(payload: dict[str, Any], *, prompt: str, project_dir: str) -> dict[str, Any]:
|
|
24
|
+
normalized = normalize_output(
|
|
25
|
+
"codex",
|
|
26
|
+
payload,
|
|
27
|
+
context={"prompt": prompt, "project_dir": project_dir},
|
|
28
|
+
)
|
|
29
|
+
merged = dict(payload)
|
|
30
|
+
merged["normalized_output"] = normalized
|
|
31
|
+
return merged
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CodexProvider(CLIProvider):
|
|
35
|
+
"""CLIProvider implementation for the Codex CLI (``codex``)."""
|
|
36
|
+
|
|
37
|
+
# -- identity -----------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
def get_name(self) -> str: # noqa: D401
|
|
40
|
+
"""Return the canonical provider name."""
|
|
41
|
+
return "codex"
|
|
42
|
+
|
|
43
|
+
# -- detection ----------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
def detect(self) -> bool:
|
|
46
|
+
"""Return ``True`` when the ``codex`` binary is available on PATH."""
|
|
47
|
+
return shutil.which("codex") is not None
|
|
48
|
+
|
|
49
|
+
# -- authentication -----------------------------------------------------
|
|
50
|
+
|
|
51
|
+
def check_auth(self) -> tuple[bool | None, str]:
|
|
52
|
+
"""Check Codex authentication status via ``codex auth status``."""
|
|
53
|
+
try:
|
|
54
|
+
result = self.run_tool(["codex", "auth", "status"], timeout=_AUTH_CHECK_TIMEOUT_SECONDS)
|
|
55
|
+
if result.returncode == 0:
|
|
56
|
+
return True, result.stdout.strip()
|
|
57
|
+
return False, result.stderr.strip() or result.stdout.strip()
|
|
58
|
+
except Exception as exc:
|
|
59
|
+
return None, f"codex auth check failed: {exc}"
|
|
60
|
+
|
|
61
|
+
# -- invocation ---------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
def invoke(self, prompt: str, project_dir: str, timeout: int = 120) -> dict[str, Any]: # pyright: ignore[reportExplicitAny]
|
|
64
|
+
"""Invoke ``codex exec --json`` via subprocess."""
|
|
65
|
+
try:
|
|
66
|
+
result = self.run_tool(
|
|
67
|
+
["codex", "exec", "--json", prompt],
|
|
68
|
+
timeout=timeout,
|
|
69
|
+
cwd=project_dir,
|
|
70
|
+
env={"CLAUDE_PROJECT_DIR": project_dir},
|
|
71
|
+
)
|
|
72
|
+
return _attach_normalized_output({
|
|
73
|
+
"model": "codex-cli",
|
|
74
|
+
"output": result.stdout,
|
|
75
|
+
"exit_code": result.returncode,
|
|
76
|
+
}, prompt=prompt, project_dir=project_dir)
|
|
77
|
+
except subprocess.TimeoutExpired:
|
|
78
|
+
return {"error": "codex-cli timeout", "fallback": "claude"}
|
|
79
|
+
except FileNotFoundError:
|
|
80
|
+
return {"error": "codex-cli not found", "fallback": "claude"}
|
|
81
|
+
except Exception as exc:
|
|
82
|
+
return {"error": str(exc), "fallback": "claude"}
|
|
83
|
+
|
|
84
|
+
def invoke_tmux(self, prompt: str, project_dir: str, timeout: int = 120) -> dict[str, Any]: # pyright: ignore[reportExplicitAny]
|
|
85
|
+
"""Invoke ``codex exec --json`` via a persistent tmux session.
|
|
86
|
+
|
|
87
|
+
Falls back to :meth:`invoke` on failure.
|
|
88
|
+
"""
|
|
89
|
+
try:
|
|
90
|
+
mgr = TmuxSessionManager()
|
|
91
|
+
session_name = mgr.make_session_name("codex", unique_id=str(uuid.uuid4())[:8])
|
|
92
|
+
session = mgr.get_or_create_session(session_name, cwd=project_dir)
|
|
93
|
+
output = mgr.send_command(
|
|
94
|
+
session,
|
|
95
|
+
(
|
|
96
|
+
f"{build_release_env_prefix(project_dir)}"
|
|
97
|
+
f"codex exec --json {shlex.quote(prompt)}"
|
|
98
|
+
),
|
|
99
|
+
timeout=timeout,
|
|
100
|
+
)
|
|
101
|
+
mgr.kill_session(session)
|
|
102
|
+
return _attach_normalized_output(
|
|
103
|
+
{"model": "codex-cli", "output": output, "exit_code": 0},
|
|
104
|
+
prompt=prompt,
|
|
105
|
+
project_dir=project_dir,
|
|
106
|
+
)
|
|
107
|
+
except Exception as exc:
|
|
108
|
+
_logger.warning("tmux codex invocation failed, falling back to subprocess: %s", exc)
|
|
109
|
+
return self.invoke(prompt, project_dir, timeout=timeout)
|
|
110
|
+
|
|
111
|
+
# -- command helpers ----------------------------------------------------
|
|
112
|
+
|
|
113
|
+
def get_non_interactive_cmd(self, prompt: str) -> list[str]:
|
|
114
|
+
"""Return the non-interactive command for codex."""
|
|
115
|
+
return ["codex", "exec", "--json", prompt]
|
|
116
|
+
|
|
117
|
+
# -- configuration ------------------------------------------------------
|
|
118
|
+
|
|
119
|
+
def get_config_path(self) -> str:
|
|
120
|
+
"""Return the Codex configuration file path."""
|
|
121
|
+
return os.path.expanduser("~/.codex/config.toml")
|
|
122
|
+
|
|
123
|
+
def write_mcp_config(self, server_url: str, server_name: str = "memory-server") -> None:
|
|
124
|
+
"""Write an MCP server entry to ``~/.codex/config.toml``."""
|
|
125
|
+
write_codex_mcp_config(server_url, server_name, config_path=self.get_config_path())
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# -- auto-register on import -----------------------------------------------
|
|
129
|
+
register_provider(CodexProvider())
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""Gemini CLI provider — implements CLIProvider for the ``gemini`` binary."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import shlex
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
import uuid
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from runtime.cli_provider import CLIProvider, register_provider
|
|
14
|
+
from runtime.host_parity import normalize_output
|
|
15
|
+
from runtime.mcp_config_writers import write_gemini_mcp_config
|
|
16
|
+
from runtime.release_run_coordinator import build_release_env_prefix
|
|
17
|
+
from runtime.tmux_session_manager import TmuxSessionManager
|
|
18
|
+
|
|
19
|
+
_logger = logging.getLogger(__name__)
|
|
20
|
+
_AUTH_CHECK_TIMEOUT_SECONDS = 5
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _attach_normalized_output(payload: dict[str, Any], *, prompt: str, project_dir: str) -> dict[str, Any]:
|
|
24
|
+
normalized = normalize_output(
|
|
25
|
+
"gemini",
|
|
26
|
+
payload,
|
|
27
|
+
context={"prompt": prompt, "project_dir": project_dir, "no_json_mode": True},
|
|
28
|
+
)
|
|
29
|
+
merged = dict(payload)
|
|
30
|
+
merged["normalized_output"] = normalized
|
|
31
|
+
return merged
|
|
32
|
+
|
|
33
|
+
HOST_RULES = {
|
|
34
|
+
"compilation_targets": [".gemini/settings.json"],
|
|
35
|
+
"mcp": ["omg-control"],
|
|
36
|
+
"skills": ["omg/control-plane", "omg/mcp-fabric"],
|
|
37
|
+
"automations": ["contract-validate", "provider-routing"],
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class GeminiProvider(CLIProvider):
|
|
42
|
+
"""CLIProvider implementation for the Gemini CLI (``gemini``)."""
|
|
43
|
+
|
|
44
|
+
# -- identity -----------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
def get_name(self) -> str: # noqa: D401
|
|
47
|
+
"""Return the canonical provider name."""
|
|
48
|
+
return "gemini"
|
|
49
|
+
|
|
50
|
+
# -- detection ----------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
def detect(self) -> bool:
|
|
53
|
+
"""Return ``True`` when the ``gemini`` binary is available on PATH."""
|
|
54
|
+
return shutil.which("gemini") is not None
|
|
55
|
+
|
|
56
|
+
# -- authentication -----------------------------------------------------
|
|
57
|
+
|
|
58
|
+
def check_auth(self) -> tuple[bool | None, str]:
|
|
59
|
+
"""Check Gemini authentication status via ``gemini auth status``."""
|
|
60
|
+
try:
|
|
61
|
+
result = self.run_tool(["gemini", "auth", "status"], timeout=_AUTH_CHECK_TIMEOUT_SECONDS)
|
|
62
|
+
if result.returncode == 0:
|
|
63
|
+
return True, result.stdout.strip()
|
|
64
|
+
return False, result.stderr.strip() or result.stdout.strip()
|
|
65
|
+
except Exception as exc:
|
|
66
|
+
return None, f"gemini auth check failed: {exc}"
|
|
67
|
+
|
|
68
|
+
# -- invocation ---------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
def invoke(self, prompt: str, project_dir: str, timeout: int = 120) -> dict[str, Any]: # pyright: ignore[reportExplicitAny]
|
|
71
|
+
"""Invoke ``gemini -p`` via subprocess.
|
|
72
|
+
|
|
73
|
+
Gemini CLI has no ``--json`` flag — output is plain text stdout.
|
|
74
|
+
"""
|
|
75
|
+
try:
|
|
76
|
+
result = self.run_tool(
|
|
77
|
+
["gemini", "-p", prompt],
|
|
78
|
+
timeout=timeout,
|
|
79
|
+
cwd=project_dir,
|
|
80
|
+
env={"CLAUDE_PROJECT_DIR": project_dir},
|
|
81
|
+
)
|
|
82
|
+
return _attach_normalized_output({
|
|
83
|
+
"model": "gemini-cli",
|
|
84
|
+
"output": result.stdout,
|
|
85
|
+
"exit_code": result.returncode,
|
|
86
|
+
}, prompt=prompt, project_dir=project_dir)
|
|
87
|
+
except subprocess.TimeoutExpired:
|
|
88
|
+
return {"error": "gemini-cli timeout", "fallback": "claude"}
|
|
89
|
+
except FileNotFoundError:
|
|
90
|
+
return {"error": "gemini-cli not found", "fallback": "claude"}
|
|
91
|
+
except Exception as exc:
|
|
92
|
+
return {"error": str(exc), "fallback": "claude"}
|
|
93
|
+
|
|
94
|
+
def invoke_tmux(self, prompt: str, project_dir: str, timeout: int = 120) -> dict[str, Any]: # pyright: ignore[reportExplicitAny]
|
|
95
|
+
"""Invoke ``gemini -p`` via a persistent tmux session.
|
|
96
|
+
|
|
97
|
+
Falls back to :meth:`invoke` on failure.
|
|
98
|
+
"""
|
|
99
|
+
try:
|
|
100
|
+
mgr = TmuxSessionManager()
|
|
101
|
+
session_name = mgr.make_session_name("gemini", unique_id=str(uuid.uuid4())[:8])
|
|
102
|
+
session = mgr.get_or_create_session(session_name, cwd=project_dir)
|
|
103
|
+
output = mgr.send_command(
|
|
104
|
+
session,
|
|
105
|
+
(
|
|
106
|
+
f"{build_release_env_prefix(project_dir)}"
|
|
107
|
+
f"gemini -p {shlex.quote(prompt)}"
|
|
108
|
+
),
|
|
109
|
+
timeout=timeout,
|
|
110
|
+
)
|
|
111
|
+
mgr.kill_session(session)
|
|
112
|
+
return _attach_normalized_output(
|
|
113
|
+
{"model": "gemini-cli", "output": output, "exit_code": 0},
|
|
114
|
+
prompt=prompt,
|
|
115
|
+
project_dir=project_dir,
|
|
116
|
+
)
|
|
117
|
+
except Exception as exc:
|
|
118
|
+
_logger.warning("tmux gemini invocation failed, falling back to subprocess: %s", exc)
|
|
119
|
+
return self.invoke(prompt, project_dir, timeout=timeout)
|
|
120
|
+
|
|
121
|
+
# -- command helpers ----------------------------------------------------
|
|
122
|
+
|
|
123
|
+
def get_non_interactive_cmd(self, prompt: str) -> list[str]:
|
|
124
|
+
"""Return the non-interactive command for gemini."""
|
|
125
|
+
return ["gemini", "-p", prompt]
|
|
126
|
+
|
|
127
|
+
# -- configuration ------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
def get_config_path(self) -> str:
|
|
130
|
+
"""Return the Gemini configuration file path."""
|
|
131
|
+
return os.path.expanduser("~/.gemini/settings.json")
|
|
132
|
+
|
|
133
|
+
def write_mcp_config(self, server_url: str, server_name: str = "memory-server") -> None:
|
|
134
|
+
"""Write an MCP server entry to ``~/.gemini/settings.json``.
|
|
135
|
+
|
|
136
|
+
Uses JSON format with ``mcpServers`` key and ``httpUrl`` field,
|
|
137
|
+
merging into any existing configuration.
|
|
138
|
+
"""
|
|
139
|
+
write_gemini_mcp_config(server_url, server_name, config_path=self.get_config_path())
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# -- auto-register on import -----------------------------------------------
|
|
143
|
+
register_provider(GeminiProvider())
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""Kimi Code CLI provider -- implements CLIProvider for the ``kimi`` binary."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import shlex
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
import uuid
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from runtime.cli_provider import CLIProvider, register_provider
|
|
14
|
+
from runtime.host_parity import normalize_output
|
|
15
|
+
from runtime.mcp_config_writers import write_kimi_mcp_config
|
|
16
|
+
from runtime.release_run_coordinator import build_release_env_prefix
|
|
17
|
+
from runtime.tmux_session_manager import TmuxSessionManager
|
|
18
|
+
|
|
19
|
+
_logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _attach_normalized_output(payload: dict[str, Any], *, prompt: str, project_dir: str) -> dict[str, Any]:
|
|
23
|
+
normalized = normalize_output(
|
|
24
|
+
"kimi",
|
|
25
|
+
payload,
|
|
26
|
+
context={"prompt": prompt, "project_dir": project_dir},
|
|
27
|
+
)
|
|
28
|
+
merged = dict(payload)
|
|
29
|
+
merged["normalized_output"] = normalized
|
|
30
|
+
return merged
|
|
31
|
+
|
|
32
|
+
HOST_RULES = {
|
|
33
|
+
"compilation_targets": [".kimi/mcp.json"],
|
|
34
|
+
"mcp": ["omg-control"],
|
|
35
|
+
"skills": ["omg/control-plane", "omg/mcp-fabric"],
|
|
36
|
+
"automations": ["contract-validate", "provider-routing"],
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class KimiCodeProvider(CLIProvider):
|
|
41
|
+
"""CLIProvider implementation for the Kimi Code CLI (``kimi``)."""
|
|
42
|
+
|
|
43
|
+
# -- identity -----------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
def get_name(self) -> str: # noqa: D401
|
|
46
|
+
"""Return the canonical provider name."""
|
|
47
|
+
return "kimi"
|
|
48
|
+
|
|
49
|
+
# -- detection ----------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
def detect(self) -> bool:
|
|
52
|
+
"""Return ``True`` when the ``kimi`` binary is available on PATH."""
|
|
53
|
+
return shutil.which("kimi") is not None
|
|
54
|
+
|
|
55
|
+
# -- authentication -----------------------------------------------------
|
|
56
|
+
|
|
57
|
+
def check_auth(self) -> tuple[bool | None, str]:
|
|
58
|
+
"""Check Kimi authentication by parsing ``~/.kimi/config.toml`` for stored credentials."""
|
|
59
|
+
try:
|
|
60
|
+
config_path = os.path.expanduser("~/.kimi/config.toml")
|
|
61
|
+
if not os.path.exists(config_path):
|
|
62
|
+
return False, "not authenticated — config file not found"
|
|
63
|
+
|
|
64
|
+
with open(config_path) as fh:
|
|
65
|
+
content = fh.read()
|
|
66
|
+
|
|
67
|
+
# Look for a token entry in the TOML file
|
|
68
|
+
if "token" in content:
|
|
69
|
+
return True, "authenticated"
|
|
70
|
+
return False, "not authenticated — no token in config"
|
|
71
|
+
except Exception as exc:
|
|
72
|
+
return None, f"kimi auth check failed: {exc}"
|
|
73
|
+
|
|
74
|
+
# -- invocation ---------------------------------------------------------
|
|
75
|
+
|
|
76
|
+
def invoke(self, prompt: str, project_dir: str, timeout: int = 120) -> dict[str, Any]: # pyright: ignore[reportExplicitAny]
|
|
77
|
+
"""Invoke ``kimi --print -p`` via subprocess."""
|
|
78
|
+
try:
|
|
79
|
+
result = self.run_tool(
|
|
80
|
+
["kimi", "--print", "-p", prompt],
|
|
81
|
+
timeout=timeout,
|
|
82
|
+
cwd=project_dir,
|
|
83
|
+
env={"CLAUDE_PROJECT_DIR": project_dir},
|
|
84
|
+
)
|
|
85
|
+
return _attach_normalized_output({
|
|
86
|
+
"model": "kimi-cli",
|
|
87
|
+
"output": result.stdout,
|
|
88
|
+
"exit_code": result.returncode,
|
|
89
|
+
}, prompt=prompt, project_dir=project_dir)
|
|
90
|
+
except subprocess.TimeoutExpired:
|
|
91
|
+
return {"error": "kimi-cli timeout", "fallback": "claude"}
|
|
92
|
+
except FileNotFoundError:
|
|
93
|
+
return {"error": "kimi-cli not found", "fallback": "claude"}
|
|
94
|
+
except Exception as exc:
|
|
95
|
+
return {"error": str(exc), "fallback": "claude"}
|
|
96
|
+
|
|
97
|
+
def invoke_json(self, prompt: str, project_dir: str, timeout: int = 120) -> dict[str, Any]: # pyright: ignore[reportExplicitAny]
|
|
98
|
+
"""Invoke ``kimi --print --output-format stream-json -p`` for JSONL event stream output."""
|
|
99
|
+
try:
|
|
100
|
+
result = self.run_tool(
|
|
101
|
+
["kimi", "--print", "--output-format", "stream-json", "-p", prompt],
|
|
102
|
+
timeout=timeout,
|
|
103
|
+
cwd=project_dir,
|
|
104
|
+
env={"CLAUDE_PROJECT_DIR": project_dir},
|
|
105
|
+
)
|
|
106
|
+
return _attach_normalized_output({
|
|
107
|
+
"model": "kimi-cli",
|
|
108
|
+
"output": result.stdout,
|
|
109
|
+
"exit_code": result.returncode,
|
|
110
|
+
}, prompt=prompt, project_dir=project_dir)
|
|
111
|
+
except subprocess.TimeoutExpired:
|
|
112
|
+
return {"error": "kimi-cli timeout", "fallback": "claude"}
|
|
113
|
+
except FileNotFoundError:
|
|
114
|
+
return {"error": "kimi-cli not found", "fallback": "claude"}
|
|
115
|
+
except Exception as exc:
|
|
116
|
+
return {"error": str(exc), "fallback": "claude"}
|
|
117
|
+
|
|
118
|
+
def invoke_tmux(self, prompt: str, project_dir: str, timeout: int = 120) -> dict[str, Any]: # pyright: ignore[reportExplicitAny]
|
|
119
|
+
"""Invoke ``kimi --print -p`` via a persistent tmux session.
|
|
120
|
+
|
|
121
|
+
Falls back to :meth:`invoke` on failure.
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
mgr = TmuxSessionManager()
|
|
125
|
+
session_name = mgr.make_session_name("kimi", unique_id=str(uuid.uuid4())[:8])
|
|
126
|
+
session = mgr.get_or_create_session(session_name, cwd=project_dir)
|
|
127
|
+
output = mgr.send_command(
|
|
128
|
+
session,
|
|
129
|
+
(
|
|
130
|
+
f"{build_release_env_prefix(project_dir)}"
|
|
131
|
+
f"kimi --print -p {shlex.quote(prompt)}"
|
|
132
|
+
),
|
|
133
|
+
timeout=timeout,
|
|
134
|
+
)
|
|
135
|
+
mgr.kill_session(session)
|
|
136
|
+
return _attach_normalized_output(
|
|
137
|
+
{"model": "kimi-cli", "output": output, "exit_code": 0},
|
|
138
|
+
prompt=prompt,
|
|
139
|
+
project_dir=project_dir,
|
|
140
|
+
)
|
|
141
|
+
except Exception as exc:
|
|
142
|
+
_logger.warning("tmux kimi invocation failed, falling back to subprocess: %s", exc)
|
|
143
|
+
return self.invoke(prompt, project_dir, timeout=timeout)
|
|
144
|
+
|
|
145
|
+
# -- command helpers ----------------------------------------------------
|
|
146
|
+
|
|
147
|
+
def get_non_interactive_cmd(self, prompt: str) -> list[str]:
|
|
148
|
+
"""Return the non-interactive command for kimi."""
|
|
149
|
+
return ["kimi", "--print", "-p", prompt]
|
|
150
|
+
|
|
151
|
+
# -- configuration ------------------------------------------------------
|
|
152
|
+
|
|
153
|
+
def get_config_path(self) -> str:
|
|
154
|
+
"""Return the Kimi MCP configuration file path."""
|
|
155
|
+
return os.path.expanduser("~/.kimi/mcp.json")
|
|
156
|
+
|
|
157
|
+
def write_mcp_config(self, server_url: str, server_name: str = "memory-server") -> None:
|
|
158
|
+
"""Write an MCP server entry to ``~/.kimi/mcp.json``.
|
|
159
|
+
|
|
160
|
+
Uses standard ``mcpServers`` JSON format with ``type: "http"`` and ``url`` field,
|
|
161
|
+
merging into any existing configuration.
|
|
162
|
+
"""
|
|
163
|
+
write_kimi_mcp_config(server_url, server_name, config_path=self.get_config_path())
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# -- auto-register on import -----------------------------------------------
|
|
167
|
+
register_provider(KimiCodeProvider())
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import shutil
|
|
6
|
+
import subprocess
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import cast
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from runtime.cli_provider import CLIProvider, register_provider
|
|
12
|
+
from runtime.mcp_config_writers import _atomic_write_text # pyright: ignore[reportPrivateUsage]
|
|
13
|
+
|
|
14
|
+
HOST_RULES = {
|
|
15
|
+
"compilation_targets": ["opencode.json"],
|
|
16
|
+
"mcp": ["omg-control"],
|
|
17
|
+
"mcp_key": "mcp",
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class OpenCodeProvider(CLIProvider):
|
|
22
|
+
def get_name(self) -> str: # pyright: ignore[reportImplicitOverride]
|
|
23
|
+
return "opencode"
|
|
24
|
+
|
|
25
|
+
def detect(self) -> bool: # pyright: ignore[reportImplicitOverride]
|
|
26
|
+
return shutil.which("opencode") is not None
|
|
27
|
+
|
|
28
|
+
def check_auth(self) -> tuple[bool | None, str]: # pyright: ignore[reportImplicitOverride]
|
|
29
|
+
auth_path = Path(os.path.expanduser("~/.local/share/opencode/auth.json"))
|
|
30
|
+
if not auth_path.exists():
|
|
31
|
+
return False, f"auth not found: missing {auth_path}"
|
|
32
|
+
try:
|
|
33
|
+
parsed = cast(object, json.loads(auth_path.read_text()))
|
|
34
|
+
except (json.JSONDecodeError, ValueError) as exc:
|
|
35
|
+
return False, f"auth not found: invalid json: {exc}"
|
|
36
|
+
except OSError as exc:
|
|
37
|
+
return False, f"auth not found: unreadable file: {exc}"
|
|
38
|
+
|
|
39
|
+
if not parsed:
|
|
40
|
+
return False, "auth not found: empty auth content"
|
|
41
|
+
return True, "auth found"
|
|
42
|
+
|
|
43
|
+
def invoke(self, prompt: str, project_dir: str, timeout: int = 120) -> dict[str, Any]: # pyright: ignore[reportExplicitAny, reportImplicitOverride]
|
|
44
|
+
try:
|
|
45
|
+
result = self.run_tool(
|
|
46
|
+
["opencode", prompt],
|
|
47
|
+
timeout=timeout,
|
|
48
|
+
cwd=project_dir,
|
|
49
|
+
env={"CLAUDE_PROJECT_DIR": project_dir},
|
|
50
|
+
)
|
|
51
|
+
return {
|
|
52
|
+
"model": "opencode-cli",
|
|
53
|
+
"output": result.stdout,
|
|
54
|
+
"exit_code": result.returncode,
|
|
55
|
+
}
|
|
56
|
+
except subprocess.TimeoutExpired:
|
|
57
|
+
return {"error": "opencode-cli timeout", "fallback": "claude"}
|
|
58
|
+
except FileNotFoundError:
|
|
59
|
+
return {"error": "opencode-cli not found", "fallback": "claude"}
|
|
60
|
+
except Exception as exc:
|
|
61
|
+
return {"error": str(exc), "fallback": "claude"}
|
|
62
|
+
|
|
63
|
+
def invoke_tmux(self, prompt: str, project_dir: str, timeout: int = 120) -> dict[str, Any]: # pyright: ignore[reportExplicitAny, reportImplicitOverride]
|
|
64
|
+
return self.invoke(prompt, project_dir, timeout=timeout)
|
|
65
|
+
|
|
66
|
+
def get_non_interactive_cmd(self, prompt: str) -> list[str]: # pyright: ignore[reportImplicitOverride]
|
|
67
|
+
return ["opencode", prompt]
|
|
68
|
+
|
|
69
|
+
def get_config_path(self) -> str: # pyright: ignore[reportImplicitOverride]
|
|
70
|
+
return os.path.expanduser("~/.config/opencode/opencode.json")
|
|
71
|
+
|
|
72
|
+
def get_project_config_path(self, root: str = ".") -> str:
|
|
73
|
+
return str(Path(root) / "opencode.json")
|
|
74
|
+
|
|
75
|
+
def get_plugin_dir(self, root: str = ".") -> str:
|
|
76
|
+
return str(Path(root) / ".opencode" / "plugins")
|
|
77
|
+
|
|
78
|
+
def write_mcp_config(self, server_url: str, server_name: str = "memory-server") -> None: # pyright: ignore[reportImplicitOverride]
|
|
79
|
+
config_path = Path(self.get_config_path())
|
|
80
|
+
config: dict[str, object]
|
|
81
|
+
if config_path.exists():
|
|
82
|
+
try:
|
|
83
|
+
loaded = cast(object, json.loads(config_path.read_text()))
|
|
84
|
+
config = cast(dict[str, object], loaded) if isinstance(loaded, dict) else {}
|
|
85
|
+
except (json.JSONDecodeError, ValueError):
|
|
86
|
+
config = {}
|
|
87
|
+
else:
|
|
88
|
+
config = {}
|
|
89
|
+
|
|
90
|
+
mcp = config.get("mcp")
|
|
91
|
+
if not isinstance(mcp, dict):
|
|
92
|
+
mcp = {}
|
|
93
|
+
config["mcp"] = mcp
|
|
94
|
+
|
|
95
|
+
mcp[server_name] = {"type": "http", "url": server_url}
|
|
96
|
+
_atomic_write_text(config_path, json.dumps(config, indent=2) + "\n")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
register_provider(OpenCodeProvider())
|