multi-forge 0.9.2__tar.gz → 0.9.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- multi_forge-0.9.3/PKG-INFO +348 -0
- multi_forge-0.9.3/README.md +307 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/pyproject.toml +1 -1
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session.py +1 -0
- multi_forge-0.9.3/src/forge/cli/session_adopt.py +332 -0
- multi_forge-0.9.3/src/forge/core/ops/codex_adopt.py +287 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/codex_interactive.py +14 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/codex_session.py +14 -0
- multi_forge-0.9.3/src/forge/core/ops/session_adopt.py +768 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/session_context.py +172 -2
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/runtime/codex_rollouts.py +32 -11
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/__init__.py +5 -2
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/artifacts.py +6 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/cleanup.py +3 -1
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/exceptions.py +14 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/index.py +58 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/manager.py +186 -34
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/models.py +49 -3
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/store.py +41 -2
- multi_forge-0.9.2/PKG-INFO +0 -275
- multi_forge-0.9.2/README.md +0 -234
- {multi_forge-0.9.2 → multi_forge-0.9.3}/.gitignore +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/LICENSE +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/NOTICE +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/agents/.gitkeep +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/commands/.gitkeep +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/backend/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/backend/adapters/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/backend/adapters/litellm.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/backend/creation.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/backend/registry.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/backend/remote/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/backend/remote/base.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/backend/remote/openrouter.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/backend/sources.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/activity.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/auth.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/backend.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/claude.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/codex.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/config_cmd.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/consumer_lane_freeze.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/editor.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/extensions.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/gc.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/guards.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/_group.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/_helpers.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/codex_patch.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/codex_policy.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/codex_transfer.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/commands.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/direct_commands.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/policy.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/protocols.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/read_hygiene.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/hooks/verification.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/logs.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/main.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/memory.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/memory_report.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/memory_writer.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/model.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/output.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/policy.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/proxy.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/proxy_audit.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/proxy_costs.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/runtime.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/search.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_codex.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_fork.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_lane.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_lifecycle.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_manage.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_memory.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_model_pin.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_resume_modes.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_rewind.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_routing.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/session_supervisor_options.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/status_line.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/statusline/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/statusline/context.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/statusline/names.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/statusline/palette.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/statusline/registry.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/statusline/throttle.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/telemetry.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/trace.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/transfer.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/cli/workflow.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/dataclass_utils.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/backends/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/backends/litellm.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/anthropic-passthrough.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/codex-responses-local.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/litellm-anthropic-local.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/litellm-anthropic.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/litellm-gemini-flash-local.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/litellm-gemini-local.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/litellm-gemini-test.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/litellm-gemini.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/litellm-openai-codex-local.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/litellm-openai-local.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/litellm-openai.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-anthropic.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-deepseek.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-gemini-flash.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-gemini.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-glm.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-kimi.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-minimax.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-openai-codex.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-openai.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/defaults/templates/openrouter-qwen.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/loader.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/config/schema.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/auth/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/auth/capabilities.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/auth/credentials_file.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/auth/protocols.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/auth/secrets.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/auth/template_secrets.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/backend_dependency.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/credential_registry.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/data/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/data/model_catalog.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/data/system_prompt_addendums/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/data/system_prompt_addendums/gemini.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/data/system_prompt_addendums/openai.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/effort.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/invoker/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/invoker/_lifecycle.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/invoker/claude.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/invoker/codex.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/invoker/codex_stream.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/invoker/types.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/lanes.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/clients/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/clients/base.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/clients/litellm.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/clients/openai_compat.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/clients/openrouter.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/credentials.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/detection.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/errors.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/protocols.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/llm/types.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/logging.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/models/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/models/catalog.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/models/direct_model.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/models/types.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/naming.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/backend_reconcile.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/claude_session.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/codex_bridge.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/codex_enrollment.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/context.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/gc.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/policy.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/provider_trace.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/proxy.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/resolution.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/session.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/transfer.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/ops/usage_summary.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/paths.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/process.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/provider_types.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/cost_tracking.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/env.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/headless_json.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/llm_call.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/proxy.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/routing.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/session_runner.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/structured_output.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/tagger.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/reactive/throttle.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/run_id.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/runtime/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/runtime/codex_preflight.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/runtime/codex_preflight_cache.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/runtime/registry.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/runtime_vocab.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/state/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/state/exceptions.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/state/io.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/state/lock.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/state/retention.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/state/timestamps.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/state/versioned_store.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/telemetry/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/telemetry/caps.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/telemetry/downstream.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/telemetry/jsonl_io.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/telemetry/upstream.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/telemetry/vocabulary.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/tiers.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/transcript.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/typing_helpers.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/usage/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/usage/billing.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/usage/correlation.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/usage/emit.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/usage/ledger.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/usage/measurement.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/usage/vocabulary.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/workqueue/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/workqueue/queue.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/core/workqueue/types.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/cli.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/codex_hooks.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/doctor.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/exceptions.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/hook_dispatcher.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/hook_migration.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/hooks.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/installer.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/models.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/preset.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/project_compat.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/project_registry.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/settings_merge.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/skill_cache.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/skill_compiler.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/skill_planning.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/skill_validation.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/tracking.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/unmanaged.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/install/version.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/deterministic/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/deterministic/base.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/deterministic/coding_standards.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/deterministic/registry.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/deterministic/tdd.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/engine.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/protocols.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/queries.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/semantic/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/semantic/plan_check.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/semantic/shadow.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/semantic/shadow_runner.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/semantic/supervisor.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/semantic/verdict.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/store.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/supervisor_lane_degrade.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/team/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/team/config.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/team/handlers.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/team/prompts.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/types.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/workflow/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/workflow/branches.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/workflow/config.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/workflow/divergence.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/workflow/policy.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/policy/workflow/stages.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/audit_logger.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/base_client.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/client_adapter.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/client_factory.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/converters.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/cost_logger.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/cost_tracker.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/data_models.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/error_hints.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/intercept.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/metrics.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/model_spec.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/passthrough.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/ports.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/provider_trace_logger.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/proxies.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/proxy_identity.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/proxy_orchestrator.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/proxy_startup.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/reasoning.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/responses_ingress.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/responses_passthrough.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/server.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/stream_relay.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/proxy/utils.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/adversarial.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/consensus.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/engine.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/models.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/code_consensus_evaluation.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/code_debate_evaluation.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/codereview-performance.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/codereview-quick.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/codereview-security.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/codereview.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/consensus_evaluation.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/debate_evaluation.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/docreview-quick.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/docreview.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/resources/thinkdeep.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/routing.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/review/synthesis.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/runtime_config.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/search/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/search/bm25_store.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/search/content_store.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/search/engine.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/search/exceptions.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/search/extractor.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/search/index_state.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/search/store.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/search/tokenizer.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/active.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/addendum.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/claude/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/claude/cleanup.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/claude/invoke.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/claude/paths.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/claude/relocate.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/codex_handoff.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/codex_invoke.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/config.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/consumer_lanes.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/context_limit.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/effective.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/hooks/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/hooks/models.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/hooks/session_start.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/identity.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/launch.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/launch_confirmation.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/memory_inheritance.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/memory_writer.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/model_pin.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/overrides.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/passport.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/plan_resolution.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/prev_sessions.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/project_memory.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/rewind.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/shadow_curation.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/transfer.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/validation.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/worktree/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/worktree/cleanup.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/worktree/config_copy.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/session/worktree/create.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/sidecar/__init__.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/sidecar/container.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/forge/sidecar/docker.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/analyze/content.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/analyze/forge-skill.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/challenge/content.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/challenge/forge-skill.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/consensus/content.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/consensus/forge-skill.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/consensus/resources/synthesis.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/debate/content.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/debate/forge-skill.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/panel/content.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/panel/forge-skill.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/panel/resources/synthesis.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/SKILL.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/0-enable.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/1-preflight.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/10-resume.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/11-config.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/12-search.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/13-policy.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/14-workflow.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/15-skills.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/16-memory.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/17-info.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/18-disable.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/19-uninstall.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/2-extension.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/20-cleanup.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/3-authentication.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/4-proxy.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/5-session.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/6-hook.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/7-costs.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/8-status-line.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist/9-direct-commands.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/checklist.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/resources/report-template.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/scripts/start-container.sh +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/qa/scripts/walkthrough-state.py +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/content.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/forge-skill.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/references/claude-4.6.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/references/claude-4.8.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/references/gemini-3.1.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/references/gpt-5.5.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/references/skills-writing-guide.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/resources/code-anthropic.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/resources/code-gemini.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/resources/code-openai.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review/resources/code.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review-docs/content.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review-docs/forge-skill.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review-docs/resources/docs-anthropic.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review-docs/resources/docs-gemini.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review-docs/resources/docs-openai.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/review-docs/resources/docs.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/smoke-test/content.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/smoke-test/forge-skill.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/smoke-test/scripts/smoke-test.sh +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/content.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/forge-skill.yaml +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/resources/code-anthropic.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/resources/code-gemini.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/resources/code-openai.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/resources/code.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/resources/docs-anthropic.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/resources/docs-gemini.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/resources/docs-openai.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/understand/resources/docs.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/walkthrough/SKILL.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/walkthrough/resources/checklist.md +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/walkthrough/scripts/run-in-repo.sh +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/walkthrough/scripts/setup-test-repo.sh +0 -0
- {multi_forge-0.9.2 → multi_forge-0.9.3}/src/skills/walkthrough/scripts/walkthrough-state.py +0 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: multi-forge
|
|
3
|
+
Version: 0.9.3
|
|
4
|
+
Summary: Multi-runtime agent toolkit: proxy routing, cost control, session management, policy enforcement, and workflow orchestration
|
|
5
|
+
Project-URL: Homepage, https://github.com/hapa1i/multi-forge
|
|
6
|
+
Project-URL: Repository, https://github.com/hapa1i/multi-forge
|
|
7
|
+
Project-URL: Issues, https://github.com/hapa1i/multi-forge/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/hapa1i/multi-forge/tree/main/docs
|
|
9
|
+
Author-email: Habib Farr <hapali@pm.me>
|
|
10
|
+
License-Expression: Apache-2.0
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
License-File: NOTICE
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Software Development
|
|
23
|
+
Requires-Python: <3.14,>=3.11
|
|
24
|
+
Requires-Dist: click>=8.3.1
|
|
25
|
+
Requires-Dist: coolname<6,>=5.0.0
|
|
26
|
+
Requires-Dist: dacite>=1.8.0
|
|
27
|
+
Requires-Dist: fastapi>=0.115.14
|
|
28
|
+
Requires-Dist: httpx>=0.25.0
|
|
29
|
+
Requires-Dist: litellm[proxy]>=1.88.0
|
|
30
|
+
Requires-Dist: openai>=1.0.0
|
|
31
|
+
Requires-Dist: packaging>=21.0
|
|
32
|
+
Requires-Dist: pydantic>=2.0.0
|
|
33
|
+
Requires-Dist: python-dotenv>=1.2.2
|
|
34
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
35
|
+
Requires-Dist: rich>=13.9.0
|
|
36
|
+
Requires-Dist: ruamel-yaml>=0.18.0
|
|
37
|
+
Requires-Dist: tenacity>=8.0.0
|
|
38
|
+
Requires-Dist: uvicorn>=0.31.1
|
|
39
|
+
Requires-Dist: watchfiles>=0.20
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
# Multi-Forge
|
|
43
|
+
|
|
44
|
+
<p align="left">
|
|
45
|
+
<img src="assets/logo.jpg" alt="Dusk" width=240">
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
[](https://pypi.org/project/multi-forge/)
|
|
49
|
+
[](https://pypi.org/project/multi-forge/)
|
|
50
|
+
[](LICENSE)
|
|
51
|
+
|
|
52
|
+
> [!WARNING]
|
|
53
|
+
> **Research Preview** -- Forge is under active development. APIs, commands, and file formats may change without notice
|
|
54
|
+
> between releases. Not recommended for production use.
|
|
55
|
+
|
|
56
|
+
**Multi-runtime control plane for coding agents: put one vendor's model to work checking another's.**
|
|
57
|
+
|
|
58
|
+
Forge runs Claude Code or Codex as a managed session, then dispatches other models around it -- supervising writes
|
|
59
|
+
against an approved plan, curating handoffs across the vendor boundary, reviewing in a multi-model panel, and metering
|
|
60
|
+
what all of it cost. You launch through `forge session start` instead of invoking the runtime directly. Claude sessions
|
|
61
|
+
can route to a chosen provider through a local proxy; both runtimes share Forge's session state and policy model.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Claude with session tracking (no proxy needed)
|
|
65
|
+
forge session start
|
|
66
|
+
|
|
67
|
+
# Route through a different provider -- --proxy takes a template name and starts it
|
|
68
|
+
forge session start planner --proxy openrouter-openai
|
|
69
|
+
|
|
70
|
+
# Have OpenAI's Codex police a Claude session's edits against the approved plan
|
|
71
|
+
forge session fork planner -n executor -w --supervise --supervisor-runtime codex --no-launch
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Why Forge?
|
|
75
|
+
|
|
76
|
+
Claude Code talks to Anthropic and tracks conversations. Forge adds an operational layer on top:
|
|
77
|
+
|
|
78
|
+
- **Cross-Vendor Supervision** -- Bind the plan supervisor or memory writer to a different consumer lane, or select a
|
|
79
|
+
different runtime per review worker. The policy can evaluate every Write/Edit against the approved plan with a
|
|
80
|
+
read-only `codex exec`; exact repeats may reuse its short-lived verdict cache.
|
|
81
|
+
- **Two Runtimes, One Session Graph** -- Claude sessions fork and resume; Codex sessions resume, and new Codex branches
|
|
82
|
+
use `forge session start --runtime codex --resume-from <parent>` to carry curated context across the boundary.
|
|
83
|
+
`forge session adopt` binds a conversation you started outside Forge.
|
|
84
|
+
- **Multi-Model Routing** -- Route to GPT, Gemini, or any model via OpenRouter or LiteLLM through a local proxy. Forge
|
|
85
|
+
sets `CLAUDE_CODE_AUTO_COMPACT_WINDOW` so compaction timing matches the routed model's context window.
|
|
86
|
+
- **Cost Control** -- `forge telemetry costs show` reports what each proxy actually spent; per-proxy daily and monthly
|
|
87
|
+
caps reject or warn at the ceiling. Cost is reported or marked unavailable -- never inferred from token counts.
|
|
88
|
+
- **Sessions That Outlive Context** -- Named sessions persist artifacts, plans, and transcripts. When context fills up,
|
|
89
|
+
hand off to a fresh session with structured or AI-curated history you can edit before it lands.
|
|
90
|
+
- **Policy, Review, and Verification** -- TDD and coding-standard bundles, semantic alignment checks, multi-model review
|
|
91
|
+
fan-out, and verification loops that keep an agent working until tests pass.
|
|
92
|
+
|
|
93
|
+
### Why launch through Forge?
|
|
94
|
+
|
|
95
|
+
Running `claude` directly bypasses session tracking. When you launch through Forge (`forge session start`), you get:
|
|
96
|
+
|
|
97
|
+
| Feature | `claude` directly | `forge session start` |
|
|
98
|
+
| ---------------------- | ----------------- | ------------------------------------------------- |
|
|
99
|
+
| Session tracking | No | Yes -- named sessions, artifacts, transcripts |
|
|
100
|
+
| Session resume | No | Yes -- editable handoff to fresh context |
|
|
101
|
+
| Status line | No | Yes -- proxy, session, policy info |
|
|
102
|
+
| Hook-driven artifacts | No | Yes -- plan snapshots, transcript capture |
|
|
103
|
+
| Policy enforcement | No | Yes -- TDD, coding standards, supervisor |
|
|
104
|
+
| Search across sessions | No | Yes -- `forge search` indexes transcripts |
|
|
105
|
+
| Project memory | No | Yes -- opt-in; passported docs curated after exit |
|
|
106
|
+
| Adopt an existing chat | n/a | Yes -- `forge session adopt <conversation-id>` |
|
|
107
|
+
|
|
108
|
+
Already deep into a bare `claude` or `codex` conversation? `forge session adopt` binds it to a managed session instead
|
|
109
|
+
of making you start over -- run it from the directory the conversation was launched in.
|
|
110
|
+
|
|
111
|
+
## How it Works
|
|
112
|
+
|
|
113
|
+
Forge sits between you and the agent runtime. It owns session state and policy, dispatches auxiliary consumers through
|
|
114
|
+
persisted lane bindings, selects review workers independently per workflow, and optionally routes model traffic through
|
|
115
|
+
a local proxy.
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
You -> forge session -> Claude Code | Codex
|
|
119
|
+
|
|
|
120
|
+
+-- consumer lanes -> supervisor (claude | codex)
|
|
121
|
+
| memory_writer (claude | codex)
|
|
122
|
+
| shadow_curation (claude | codex)
|
|
123
|
+
| team_supervisor (claude)
|
|
124
|
+
|
|
|
125
|
+
+-- workflow workers -> panel | analyze | debate | consensus
|
|
126
|
+
| (claude | opt-in codex)
|
|
127
|
+
|
|
|
128
|
+
+-- proxy -> OpenRouter | LiteLLM -> any model
|
|
129
|
+
+-- state -> artifacts, policy, telemetry
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Claude direct mode** (the default for Claude sessions) skips the proxy and talks to Anthropic directly; you still get
|
|
133
|
+
sessions, hooks, consumer lanes, and the status line. Add `--proxy` for routing. **OpenRouter** templates call the
|
|
134
|
+
OpenRouter API directly -- one API key covers Anthropic, OpenAI, Google, and more. **LiteLLM** templates route through a
|
|
135
|
+
[LiteLLM](https://github.com/BerriAI/litellm) proxy, remote or a local subprocess. Twenty user-facing templates ship;
|
|
136
|
+
see [docs/end-user/proxy.md](docs/end-user/proxy.md).
|
|
137
|
+
|
|
138
|
+
## Requirements
|
|
139
|
+
|
|
140
|
+
- **Platform**: macOS or Linux
|
|
141
|
+
- **Python**: 3.11-3.13 (3.14 blocked on upstream `uvloop` wheels -- see #1)
|
|
142
|
+
- **Installer**: [`uv`](https://docs.astral.sh/uv/) or [`pipx`](https://pipx.pypa.io/) for the recommended global
|
|
143
|
+
install
|
|
144
|
+
- **Claude Code**: required for the default and other Claude-backed workflows; a Codex-only session or skill path does
|
|
145
|
+
not require it
|
|
146
|
+
- **Codex** (optional): needed for `--runtime codex` sessions, `forge codex start`, Codex-backed consumer lanes, and the
|
|
147
|
+
opt-in Codex workflow worker. Check readiness with `forge runtime preflight codex`; proxy-routed `forge codex start`
|
|
148
|
+
needs codex >= 0.141.0.
|
|
149
|
+
- **Provider auth**: Claude Code login is enough for direct interactive sessions. Proxies and headless workflows need a
|
|
150
|
+
supported API or gateway credential such as `OPENROUTER_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`,
|
|
151
|
+
`OPENAI_API_KEY`, or LiteLLM auth.
|
|
152
|
+
|
|
153
|
+
## Quick Start
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Install Forge as a global tool (recommended -- puts `forge` on your PATH)
|
|
157
|
+
uv tool install multi-forge
|
|
158
|
+
# or: pipx install multi-forge
|
|
159
|
+
|
|
160
|
+
# Make uv's tool bin available in this shell and future shells
|
|
161
|
+
uv tool update-shell
|
|
162
|
+
export PATH="$(uv tool dir --bin):$PATH"
|
|
163
|
+
|
|
164
|
+
# Confirm how forge is installed and whether it is globally reachable
|
|
165
|
+
forge extension doctor
|
|
166
|
+
|
|
167
|
+
# Register runtime hooks once, at user scope
|
|
168
|
+
forge extension enable --scope user --profile minimal --with hooks,codex-hooks --without commands
|
|
169
|
+
|
|
170
|
+
# Then, inside a project: install project-owned assets and settings
|
|
171
|
+
forge extension enable
|
|
172
|
+
|
|
173
|
+
# Launch Claude with session tracking (no proxy needed)
|
|
174
|
+
forge session start
|
|
175
|
+
|
|
176
|
+
# Or with multi-model routing -- --proxy accepts a template name and starts the proxy for you
|
|
177
|
+
forge auth login -c openrouter # store OPENROUTER_API_KEY
|
|
178
|
+
forge session start --proxy openrouter-anthropic
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Developing on Forge itself? See [CONTRIBUTING.md](CONTRIBUTING.md) for the editable install.
|
|
182
|
+
|
|
183
|
+
Once running, try `/forge:smoke-test` (Claude) or `$smoke-test` (Codex) for a read-only health check, or
|
|
184
|
+
`/forge:walkthrough` for a guided tour in a sandboxed test repo.
|
|
185
|
+
|
|
186
|
+
## Plan, Execute, Review
|
|
187
|
+
|
|
188
|
+
A typical feature workflow assigns different model roles to planning, execution, and review. The supervisor is a *lane*,
|
|
189
|
+
not a fixed model -- pin it to `codex` and a second vendor grades the first.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# 1. Plan with a high-reasoning model (--proxy takes a template; Forge starts it)
|
|
193
|
+
forge session start planner --proxy openrouter-openai
|
|
194
|
+
# ... Claude writes a plan, you approve it, /exit
|
|
195
|
+
|
|
196
|
+
# 2. Execute in a worktree, with the policy evaluating every Write/Edit against
|
|
197
|
+
# the approved plan through read-only Codex (exact repeats may reuse its cache).
|
|
198
|
+
forge runtime preflight codex # cache the readiness the lane reads
|
|
199
|
+
forge session fork planner -n executor -w --supervise --supervisor-runtime codex --no-launch
|
|
200
|
+
forge policy supervisor reload -s executor # REQUIRED: codex has no --resume, so the
|
|
201
|
+
# approved plan must reach it in-band
|
|
202
|
+
cd ../multi-forge-executor # worktrees land at ../<repo-name>-<session-name>
|
|
203
|
+
forge session resume executor
|
|
204
|
+
|
|
205
|
+
# 3. Context filling up? Resume fresh -- supervisor config carries over.
|
|
206
|
+
forge session resume executor --fresh --strategy ai-curated
|
|
207
|
+
|
|
208
|
+
# 4. Review from the planner's perspective, inside the executor's worktree
|
|
209
|
+
forge session fork planner --into ../multi-forge-executor
|
|
210
|
+
|
|
211
|
+
# 5. Push and open a PR
|
|
212
|
+
git push origin feature-branch
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Two prerequisites keep the Codex lane enforcing instead of failing open with a warning:
|
|
216
|
+
|
|
217
|
+
- **The plan reload is mandatory.** Codex has no `--resume`, so it cannot read the planning conversation. With no plan
|
|
218
|
+
in-band, Forge fails the check open *without spawning Codex* -- it warns, it does not block. Use
|
|
219
|
+
`forge policy supervisor reload`, or `%policy supervisor reload` from inside the session.
|
|
220
|
+
- **Preflight is cached, never probed during a check.** `codex doctor` is slow, but it is the probe that discovers
|
|
221
|
+
stored ChatGPT-login auth. The policy hook therefore reads the full result cached by `forge runtime preflight codex`
|
|
222
|
+
instead of rerunning it. A cold or stale cache fails open and prints a refresh hint.
|
|
223
|
+
|
|
224
|
+
`forge policy supervisor status` shows the bound `(runtime, backend, model)` lane. When preflight selects stored ChatGPT
|
|
225
|
+
tokens as the auth source, the check is labeled `subscription_quota` rather than Anthropic usage. Full details in
|
|
226
|
+
[docs/end-user/policy.md](docs/end-user/policy.md).
|
|
227
|
+
|
|
228
|
+
### Codex as a worker runtime
|
|
229
|
+
|
|
230
|
+
Codex is not only an alternate frontend -- it is a runtime Forge dispatches work to:
|
|
231
|
+
|
|
232
|
+
- **Other lanes.** `forge session lane set --consumer memory_writer --runtime codex` (also `shadow_curation`) moves that
|
|
233
|
+
consumer onto `codex exec`. `team_supervisor` has no Codex lane and rejects it.
|
|
234
|
+
- **A whole task, seeded from a Claude parent.**
|
|
235
|
+
`forge session start impl --runtime codex --resume-from planner --task "Implement the plan."` carries curated context
|
|
236
|
+
across the vendor boundary; continue with `forge session resume impl --task "Now add tests."`.
|
|
237
|
+
- **Codex TUI through a Forge proxy.** `forge codex start --proxy <id>` -- the proxy owns upstream auth, so no OpenAI
|
|
238
|
+
login is required or leaked.
|
|
239
|
+
- **Capability matrix.** `forge runtime list` shows what each detected runtime supports.
|
|
240
|
+
|
|
241
|
+
## Cost and Wire Control
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
forge telemetry costs show --period month --by-model # authoritative proxy-scoped spend
|
|
245
|
+
forge telemetry activity planner # what Forge's automation did in one session
|
|
246
|
+
forge proxy set openrouter-openai costs.caps.per_day=20
|
|
247
|
+
forge proxy set openrouter-openai costs.on_cap_hit=reject # or 'warn' for a header-only alert
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Caps take effect when the proxy next starts, and are enforced *after* each completed request -- one request can cross a
|
|
251
|
+
cap and finish before the next is refused. `forge session start --subprocess-proxy <id>` keeps the interactive session
|
|
252
|
+
on direct Anthropic routing while supervisor, panel, and memory-writer subprocesses run metered through a proxy (it is
|
|
253
|
+
mutually exclusive with `--proxy`). Direct routing does not by itself guarantee subscription billing: the default
|
|
254
|
+
`interactive_anthropic_api_key=inherit` passes a resolvable API key. To force the interactive process to use its Claude
|
|
255
|
+
login, run `forge config set interactive_anthropic_api_key=omit`; see
|
|
256
|
+
[authentication.md](docs/end-user/authentication.md#keeping-a-key-out-of-interactive-sessions-interactive_anthropic_api_key).
|
|
257
|
+
|
|
258
|
+
A Forge proxy can also be an audit chokepoint. The default wire shape translates Anthropic to OpenAI and **drops
|
|
259
|
+
`thinking` blocks**; the shipped `anthropic-passthrough` template forwards the raw body byte-for-byte and already ships
|
|
260
|
+
`intercept.mode: inspect`, which hashes the system prompt and tool surface and flags drift when either changes
|
|
261
|
+
underneath you. `forge proxy audit show|diff` renders the timeline. Records are redacted before they reach disk --
|
|
262
|
+
hashes, lengths, and counts, never prompt or completion text.
|
|
263
|
+
|
|
264
|
+
## Skills
|
|
265
|
+
|
|
266
|
+
Nine skills compile for **both** runtimes -- Claude invokes `/forge:<name>`, Codex invokes `$<name>`: `analyze`,
|
|
267
|
+
`challenge`, `consensus`, `debate`, `panel`, `review`, `review-docs`, `smoke-test`, `understand`. Only
|
|
268
|
+
`/forge:walkthrough` and `/forge:qa` are Claude-only.
|
|
269
|
+
|
|
270
|
+
The same runners are available from the terminal, and `--check` turns one into an exit-code gate you can script:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
forge workflow panel src/forge/session/ --code # fan a review out to several models
|
|
274
|
+
forge workflow debate "Should we rewrite this in Rust?"
|
|
275
|
+
forge workflow panel src/ --code --check # exit 0 if every worker accepts, else 1
|
|
276
|
+
forge workflow list-models # which workers are ready right now
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
See [docs/end-user/skills.md](docs/end-user/skills.md) and [docs/end-user/workflow.md](docs/end-user/workflow.md).
|
|
280
|
+
|
|
281
|
+
## CLI Overview
|
|
282
|
+
|
|
283
|
+
| Command Group | Purpose |
|
|
284
|
+
| ----------------- | ----------------------------------------------------- |
|
|
285
|
+
| `forge session` | Named sessions, worktrees, resume, fork, adopt, lanes |
|
|
286
|
+
| `forge claude` | Bare launch, settings preset management |
|
|
287
|
+
| `forge codex` | Codex status, proxy-routed TUI launch |
|
|
288
|
+
| `forge runtime` | Runtime inventory and readiness preflight |
|
|
289
|
+
| `forge proxy` | Model routing, templates, tier mappings, wire audit |
|
|
290
|
+
| `forge model` | Model catalog, backends, local backend lifecycle |
|
|
291
|
+
| `forge telemetry` | Costs, per-session activity, provider traces |
|
|
292
|
+
| `forge policy` | Policy enforcement, plan supervision, shadow audit |
|
|
293
|
+
| `forge workflow` | Workflow runners (panel, analyze, debate, consensus) |
|
|
294
|
+
| `forge memory` | Project memory passports, shadow proposals |
|
|
295
|
+
| `forge search` | Transcript search across sessions |
|
|
296
|
+
| `forge auth` | Credential management (`credentials.yaml`) |
|
|
297
|
+
| `forge config` | Runtime preferences (`~/.forge/config.yaml`) |
|
|
298
|
+
| `forge extension` | Enable/sync/disable extensions |
|
|
299
|
+
| `forge clean` | Preview and remove orphaned Forge state |
|
|
300
|
+
| `forge logs` | Log file locations and cleanup |
|
|
301
|
+
| `forge info` | System health and installation info |
|
|
302
|
+
|
|
303
|
+
Run `forge <command> --help` for details on any command.
|
|
304
|
+
|
|
305
|
+
## Documentation
|
|
306
|
+
|
|
307
|
+
| Audience | Location | Contents |
|
|
308
|
+
| ------------------- | ---------------------------------------------------- | ----------------------------------------------------- |
|
|
309
|
+
| **Users** | [docs/end-user/](docs/end-user/) | 13 guides -- start with the Day 1 workflow |
|
|
310
|
+
| **Developers** | [docs/developer/](docs/developer/) | Setup, coding standards, testing guidelines |
|
|
311
|
+
| **Architecture** | [docs/design.md](docs/design.md) | Core system narrative, data flow, invariants |
|
|
312
|
+
| **Workflow design** | [docs/design_workflows.md](docs/design_workflows.md) | Policy, skills, workflow runners, memory architecture |
|
|
313
|
+
| **CLI reference** | [docs/cli_reference.md](docs/cli_reference.md) | Terminal and direct-command inventory |
|
|
314
|
+
| **Work Board** | [docs/board/](docs/board/) | Cards, checklists, change log, implementation memory |
|
|
315
|
+
|
|
316
|
+
Common starting points: [sessions](docs/end-user/session.md), [proxies](docs/end-user/proxy.md),
|
|
317
|
+
[policy and supervision](docs/end-user/policy.md), [model selection](docs/end-user/model_selection.md),
|
|
318
|
+
[transfer context](docs/end-user/transfer.md), and [project memory](docs/end-user/memory.md).
|
|
319
|
+
|
|
320
|
+
## Troubleshooting
|
|
321
|
+
|
|
322
|
+
> [!NOTE]
|
|
323
|
+
> **Corrupt state?** If Forge reports that its state is corrupt, it names the offending file and stops -- it never
|
|
324
|
+
> silently runs on bad state. Run `forge clean` to preview what would be removed, then `forge clean --yes` to remove it
|
|
325
|
+
> (add `--scope all` to cover every project). For a full reset, delete `.forge` (project-local) or `~/.forge` (global)
|
|
326
|
+
> and re-run `forge extension enable`. Your own files and `proxy.yaml` config are never touched by `forge clean`.
|
|
327
|
+
|
|
328
|
+
`forge extension doctor` reports how Forge is installed, whether the launcher is reachable, and the state of the hook
|
|
329
|
+
dispatcher. Upgrading from a pre-OSS Forge install? See
|
|
330
|
+
[docs/end-user/README.md](docs/end-user/README.md#upgrading-from-pre-oss-forge).
|
|
331
|
+
|
|
332
|
+
## Contributing
|
|
333
|
+
|
|
334
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and PR guidelines.
|
|
335
|
+
|
|
336
|
+
## Uninstall
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
forge extension disable
|
|
340
|
+
uv tool uninstall multi-forge # or: pipx uninstall multi-forge
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## License
|
|
344
|
+
|
|
345
|
+
Apache 2.0 -- see [LICENSE](LICENSE).
|
|
346
|
+
|
|
347
|
+
Originally developed as Claude Forge at [Thomson Reuters](https://github.com/thomsonreuters/claude-forge) and
|
|
348
|
+
open-sourced under Apache 2.0. Continued as Multi-Forge by the original author.
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Multi-Forge
|
|
2
|
+
|
|
3
|
+
<p align="left">
|
|
4
|
+
<img src="assets/logo.jpg" alt="Dusk" width=240">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/multi-forge/)
|
|
8
|
+
[](https://pypi.org/project/multi-forge/)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
> [!WARNING]
|
|
12
|
+
> **Research Preview** -- Forge is under active development. APIs, commands, and file formats may change without notice
|
|
13
|
+
> between releases. Not recommended for production use.
|
|
14
|
+
|
|
15
|
+
**Multi-runtime control plane for coding agents: put one vendor's model to work checking another's.**
|
|
16
|
+
|
|
17
|
+
Forge runs Claude Code or Codex as a managed session, then dispatches other models around it -- supervising writes
|
|
18
|
+
against an approved plan, curating handoffs across the vendor boundary, reviewing in a multi-model panel, and metering
|
|
19
|
+
what all of it cost. You launch through `forge session start` instead of invoking the runtime directly. Claude sessions
|
|
20
|
+
can route to a chosen provider through a local proxy; both runtimes share Forge's session state and policy model.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Claude with session tracking (no proxy needed)
|
|
24
|
+
forge session start
|
|
25
|
+
|
|
26
|
+
# Route through a different provider -- --proxy takes a template name and starts it
|
|
27
|
+
forge session start planner --proxy openrouter-openai
|
|
28
|
+
|
|
29
|
+
# Have OpenAI's Codex police a Claude session's edits against the approved plan
|
|
30
|
+
forge session fork planner -n executor -w --supervise --supervisor-runtime codex --no-launch
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Why Forge?
|
|
34
|
+
|
|
35
|
+
Claude Code talks to Anthropic and tracks conversations. Forge adds an operational layer on top:
|
|
36
|
+
|
|
37
|
+
- **Cross-Vendor Supervision** -- Bind the plan supervisor or memory writer to a different consumer lane, or select a
|
|
38
|
+
different runtime per review worker. The policy can evaluate every Write/Edit against the approved plan with a
|
|
39
|
+
read-only `codex exec`; exact repeats may reuse its short-lived verdict cache.
|
|
40
|
+
- **Two Runtimes, One Session Graph** -- Claude sessions fork and resume; Codex sessions resume, and new Codex branches
|
|
41
|
+
use `forge session start --runtime codex --resume-from <parent>` to carry curated context across the boundary.
|
|
42
|
+
`forge session adopt` binds a conversation you started outside Forge.
|
|
43
|
+
- **Multi-Model Routing** -- Route to GPT, Gemini, or any model via OpenRouter or LiteLLM through a local proxy. Forge
|
|
44
|
+
sets `CLAUDE_CODE_AUTO_COMPACT_WINDOW` so compaction timing matches the routed model's context window.
|
|
45
|
+
- **Cost Control** -- `forge telemetry costs show` reports what each proxy actually spent; per-proxy daily and monthly
|
|
46
|
+
caps reject or warn at the ceiling. Cost is reported or marked unavailable -- never inferred from token counts.
|
|
47
|
+
- **Sessions That Outlive Context** -- Named sessions persist artifacts, plans, and transcripts. When context fills up,
|
|
48
|
+
hand off to a fresh session with structured or AI-curated history you can edit before it lands.
|
|
49
|
+
- **Policy, Review, and Verification** -- TDD and coding-standard bundles, semantic alignment checks, multi-model review
|
|
50
|
+
fan-out, and verification loops that keep an agent working until tests pass.
|
|
51
|
+
|
|
52
|
+
### Why launch through Forge?
|
|
53
|
+
|
|
54
|
+
Running `claude` directly bypasses session tracking. When you launch through Forge (`forge session start`), you get:
|
|
55
|
+
|
|
56
|
+
| Feature | `claude` directly | `forge session start` |
|
|
57
|
+
| ---------------------- | ----------------- | ------------------------------------------------- |
|
|
58
|
+
| Session tracking | No | Yes -- named sessions, artifacts, transcripts |
|
|
59
|
+
| Session resume | No | Yes -- editable handoff to fresh context |
|
|
60
|
+
| Status line | No | Yes -- proxy, session, policy info |
|
|
61
|
+
| Hook-driven artifacts | No | Yes -- plan snapshots, transcript capture |
|
|
62
|
+
| Policy enforcement | No | Yes -- TDD, coding standards, supervisor |
|
|
63
|
+
| Search across sessions | No | Yes -- `forge search` indexes transcripts |
|
|
64
|
+
| Project memory | No | Yes -- opt-in; passported docs curated after exit |
|
|
65
|
+
| Adopt an existing chat | n/a | Yes -- `forge session adopt <conversation-id>` |
|
|
66
|
+
|
|
67
|
+
Already deep into a bare `claude` or `codex` conversation? `forge session adopt` binds it to a managed session instead
|
|
68
|
+
of making you start over -- run it from the directory the conversation was launched in.
|
|
69
|
+
|
|
70
|
+
## How it Works
|
|
71
|
+
|
|
72
|
+
Forge sits between you and the agent runtime. It owns session state and policy, dispatches auxiliary consumers through
|
|
73
|
+
persisted lane bindings, selects review workers independently per workflow, and optionally routes model traffic through
|
|
74
|
+
a local proxy.
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
You -> forge session -> Claude Code | Codex
|
|
78
|
+
|
|
|
79
|
+
+-- consumer lanes -> supervisor (claude | codex)
|
|
80
|
+
| memory_writer (claude | codex)
|
|
81
|
+
| shadow_curation (claude | codex)
|
|
82
|
+
| team_supervisor (claude)
|
|
83
|
+
|
|
|
84
|
+
+-- workflow workers -> panel | analyze | debate | consensus
|
|
85
|
+
| (claude | opt-in codex)
|
|
86
|
+
|
|
|
87
|
+
+-- proxy -> OpenRouter | LiteLLM -> any model
|
|
88
|
+
+-- state -> artifacts, policy, telemetry
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Claude direct mode** (the default for Claude sessions) skips the proxy and talks to Anthropic directly; you still get
|
|
92
|
+
sessions, hooks, consumer lanes, and the status line. Add `--proxy` for routing. **OpenRouter** templates call the
|
|
93
|
+
OpenRouter API directly -- one API key covers Anthropic, OpenAI, Google, and more. **LiteLLM** templates route through a
|
|
94
|
+
[LiteLLM](https://github.com/BerriAI/litellm) proxy, remote or a local subprocess. Twenty user-facing templates ship;
|
|
95
|
+
see [docs/end-user/proxy.md](docs/end-user/proxy.md).
|
|
96
|
+
|
|
97
|
+
## Requirements
|
|
98
|
+
|
|
99
|
+
- **Platform**: macOS or Linux
|
|
100
|
+
- **Python**: 3.11-3.13 (3.14 blocked on upstream `uvloop` wheels -- see #1)
|
|
101
|
+
- **Installer**: [`uv`](https://docs.astral.sh/uv/) or [`pipx`](https://pipx.pypa.io/) for the recommended global
|
|
102
|
+
install
|
|
103
|
+
- **Claude Code**: required for the default and other Claude-backed workflows; a Codex-only session or skill path does
|
|
104
|
+
not require it
|
|
105
|
+
- **Codex** (optional): needed for `--runtime codex` sessions, `forge codex start`, Codex-backed consumer lanes, and the
|
|
106
|
+
opt-in Codex workflow worker. Check readiness with `forge runtime preflight codex`; proxy-routed `forge codex start`
|
|
107
|
+
needs codex >= 0.141.0.
|
|
108
|
+
- **Provider auth**: Claude Code login is enough for direct interactive sessions. Proxies and headless workflows need a
|
|
109
|
+
supported API or gateway credential such as `OPENROUTER_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`,
|
|
110
|
+
`OPENAI_API_KEY`, or LiteLLM auth.
|
|
111
|
+
|
|
112
|
+
## Quick Start
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Install Forge as a global tool (recommended -- puts `forge` on your PATH)
|
|
116
|
+
uv tool install multi-forge
|
|
117
|
+
# or: pipx install multi-forge
|
|
118
|
+
|
|
119
|
+
# Make uv's tool bin available in this shell and future shells
|
|
120
|
+
uv tool update-shell
|
|
121
|
+
export PATH="$(uv tool dir --bin):$PATH"
|
|
122
|
+
|
|
123
|
+
# Confirm how forge is installed and whether it is globally reachable
|
|
124
|
+
forge extension doctor
|
|
125
|
+
|
|
126
|
+
# Register runtime hooks once, at user scope
|
|
127
|
+
forge extension enable --scope user --profile minimal --with hooks,codex-hooks --without commands
|
|
128
|
+
|
|
129
|
+
# Then, inside a project: install project-owned assets and settings
|
|
130
|
+
forge extension enable
|
|
131
|
+
|
|
132
|
+
# Launch Claude with session tracking (no proxy needed)
|
|
133
|
+
forge session start
|
|
134
|
+
|
|
135
|
+
# Or with multi-model routing -- --proxy accepts a template name and starts the proxy for you
|
|
136
|
+
forge auth login -c openrouter # store OPENROUTER_API_KEY
|
|
137
|
+
forge session start --proxy openrouter-anthropic
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Developing on Forge itself? See [CONTRIBUTING.md](CONTRIBUTING.md) for the editable install.
|
|
141
|
+
|
|
142
|
+
Once running, try `/forge:smoke-test` (Claude) or `$smoke-test` (Codex) for a read-only health check, or
|
|
143
|
+
`/forge:walkthrough` for a guided tour in a sandboxed test repo.
|
|
144
|
+
|
|
145
|
+
## Plan, Execute, Review
|
|
146
|
+
|
|
147
|
+
A typical feature workflow assigns different model roles to planning, execution, and review. The supervisor is a *lane*,
|
|
148
|
+
not a fixed model -- pin it to `codex` and a second vendor grades the first.
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# 1. Plan with a high-reasoning model (--proxy takes a template; Forge starts it)
|
|
152
|
+
forge session start planner --proxy openrouter-openai
|
|
153
|
+
# ... Claude writes a plan, you approve it, /exit
|
|
154
|
+
|
|
155
|
+
# 2. Execute in a worktree, with the policy evaluating every Write/Edit against
|
|
156
|
+
# the approved plan through read-only Codex (exact repeats may reuse its cache).
|
|
157
|
+
forge runtime preflight codex # cache the readiness the lane reads
|
|
158
|
+
forge session fork planner -n executor -w --supervise --supervisor-runtime codex --no-launch
|
|
159
|
+
forge policy supervisor reload -s executor # REQUIRED: codex has no --resume, so the
|
|
160
|
+
# approved plan must reach it in-band
|
|
161
|
+
cd ../multi-forge-executor # worktrees land at ../<repo-name>-<session-name>
|
|
162
|
+
forge session resume executor
|
|
163
|
+
|
|
164
|
+
# 3. Context filling up? Resume fresh -- supervisor config carries over.
|
|
165
|
+
forge session resume executor --fresh --strategy ai-curated
|
|
166
|
+
|
|
167
|
+
# 4. Review from the planner's perspective, inside the executor's worktree
|
|
168
|
+
forge session fork planner --into ../multi-forge-executor
|
|
169
|
+
|
|
170
|
+
# 5. Push and open a PR
|
|
171
|
+
git push origin feature-branch
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Two prerequisites keep the Codex lane enforcing instead of failing open with a warning:
|
|
175
|
+
|
|
176
|
+
- **The plan reload is mandatory.** Codex has no `--resume`, so it cannot read the planning conversation. With no plan
|
|
177
|
+
in-band, Forge fails the check open *without spawning Codex* -- it warns, it does not block. Use
|
|
178
|
+
`forge policy supervisor reload`, or `%policy supervisor reload` from inside the session.
|
|
179
|
+
- **Preflight is cached, never probed during a check.** `codex doctor` is slow, but it is the probe that discovers
|
|
180
|
+
stored ChatGPT-login auth. The policy hook therefore reads the full result cached by `forge runtime preflight codex`
|
|
181
|
+
instead of rerunning it. A cold or stale cache fails open and prints a refresh hint.
|
|
182
|
+
|
|
183
|
+
`forge policy supervisor status` shows the bound `(runtime, backend, model)` lane. When preflight selects stored ChatGPT
|
|
184
|
+
tokens as the auth source, the check is labeled `subscription_quota` rather than Anthropic usage. Full details in
|
|
185
|
+
[docs/end-user/policy.md](docs/end-user/policy.md).
|
|
186
|
+
|
|
187
|
+
### Codex as a worker runtime
|
|
188
|
+
|
|
189
|
+
Codex is not only an alternate frontend -- it is a runtime Forge dispatches work to:
|
|
190
|
+
|
|
191
|
+
- **Other lanes.** `forge session lane set --consumer memory_writer --runtime codex` (also `shadow_curation`) moves that
|
|
192
|
+
consumer onto `codex exec`. `team_supervisor` has no Codex lane and rejects it.
|
|
193
|
+
- **A whole task, seeded from a Claude parent.**
|
|
194
|
+
`forge session start impl --runtime codex --resume-from planner --task "Implement the plan."` carries curated context
|
|
195
|
+
across the vendor boundary; continue with `forge session resume impl --task "Now add tests."`.
|
|
196
|
+
- **Codex TUI through a Forge proxy.** `forge codex start --proxy <id>` -- the proxy owns upstream auth, so no OpenAI
|
|
197
|
+
login is required or leaked.
|
|
198
|
+
- **Capability matrix.** `forge runtime list` shows what each detected runtime supports.
|
|
199
|
+
|
|
200
|
+
## Cost and Wire Control
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
forge telemetry costs show --period month --by-model # authoritative proxy-scoped spend
|
|
204
|
+
forge telemetry activity planner # what Forge's automation did in one session
|
|
205
|
+
forge proxy set openrouter-openai costs.caps.per_day=20
|
|
206
|
+
forge proxy set openrouter-openai costs.on_cap_hit=reject # or 'warn' for a header-only alert
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Caps take effect when the proxy next starts, and are enforced *after* each completed request -- one request can cross a
|
|
210
|
+
cap and finish before the next is refused. `forge session start --subprocess-proxy <id>` keeps the interactive session
|
|
211
|
+
on direct Anthropic routing while supervisor, panel, and memory-writer subprocesses run metered through a proxy (it is
|
|
212
|
+
mutually exclusive with `--proxy`). Direct routing does not by itself guarantee subscription billing: the default
|
|
213
|
+
`interactive_anthropic_api_key=inherit` passes a resolvable API key. To force the interactive process to use its Claude
|
|
214
|
+
login, run `forge config set interactive_anthropic_api_key=omit`; see
|
|
215
|
+
[authentication.md](docs/end-user/authentication.md#keeping-a-key-out-of-interactive-sessions-interactive_anthropic_api_key).
|
|
216
|
+
|
|
217
|
+
A Forge proxy can also be an audit chokepoint. The default wire shape translates Anthropic to OpenAI and **drops
|
|
218
|
+
`thinking` blocks**; the shipped `anthropic-passthrough` template forwards the raw body byte-for-byte and already ships
|
|
219
|
+
`intercept.mode: inspect`, which hashes the system prompt and tool surface and flags drift when either changes
|
|
220
|
+
underneath you. `forge proxy audit show|diff` renders the timeline. Records are redacted before they reach disk --
|
|
221
|
+
hashes, lengths, and counts, never prompt or completion text.
|
|
222
|
+
|
|
223
|
+
## Skills
|
|
224
|
+
|
|
225
|
+
Nine skills compile for **both** runtimes -- Claude invokes `/forge:<name>`, Codex invokes `$<name>`: `analyze`,
|
|
226
|
+
`challenge`, `consensus`, `debate`, `panel`, `review`, `review-docs`, `smoke-test`, `understand`. Only
|
|
227
|
+
`/forge:walkthrough` and `/forge:qa` are Claude-only.
|
|
228
|
+
|
|
229
|
+
The same runners are available from the terminal, and `--check` turns one into an exit-code gate you can script:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
forge workflow panel src/forge/session/ --code # fan a review out to several models
|
|
233
|
+
forge workflow debate "Should we rewrite this in Rust?"
|
|
234
|
+
forge workflow panel src/ --code --check # exit 0 if every worker accepts, else 1
|
|
235
|
+
forge workflow list-models # which workers are ready right now
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
See [docs/end-user/skills.md](docs/end-user/skills.md) and [docs/end-user/workflow.md](docs/end-user/workflow.md).
|
|
239
|
+
|
|
240
|
+
## CLI Overview
|
|
241
|
+
|
|
242
|
+
| Command Group | Purpose |
|
|
243
|
+
| ----------------- | ----------------------------------------------------- |
|
|
244
|
+
| `forge session` | Named sessions, worktrees, resume, fork, adopt, lanes |
|
|
245
|
+
| `forge claude` | Bare launch, settings preset management |
|
|
246
|
+
| `forge codex` | Codex status, proxy-routed TUI launch |
|
|
247
|
+
| `forge runtime` | Runtime inventory and readiness preflight |
|
|
248
|
+
| `forge proxy` | Model routing, templates, tier mappings, wire audit |
|
|
249
|
+
| `forge model` | Model catalog, backends, local backend lifecycle |
|
|
250
|
+
| `forge telemetry` | Costs, per-session activity, provider traces |
|
|
251
|
+
| `forge policy` | Policy enforcement, plan supervision, shadow audit |
|
|
252
|
+
| `forge workflow` | Workflow runners (panel, analyze, debate, consensus) |
|
|
253
|
+
| `forge memory` | Project memory passports, shadow proposals |
|
|
254
|
+
| `forge search` | Transcript search across sessions |
|
|
255
|
+
| `forge auth` | Credential management (`credentials.yaml`) |
|
|
256
|
+
| `forge config` | Runtime preferences (`~/.forge/config.yaml`) |
|
|
257
|
+
| `forge extension` | Enable/sync/disable extensions |
|
|
258
|
+
| `forge clean` | Preview and remove orphaned Forge state |
|
|
259
|
+
| `forge logs` | Log file locations and cleanup |
|
|
260
|
+
| `forge info` | System health and installation info |
|
|
261
|
+
|
|
262
|
+
Run `forge <command> --help` for details on any command.
|
|
263
|
+
|
|
264
|
+
## Documentation
|
|
265
|
+
|
|
266
|
+
| Audience | Location | Contents |
|
|
267
|
+
| ------------------- | ---------------------------------------------------- | ----------------------------------------------------- |
|
|
268
|
+
| **Users** | [docs/end-user/](docs/end-user/) | 13 guides -- start with the Day 1 workflow |
|
|
269
|
+
| **Developers** | [docs/developer/](docs/developer/) | Setup, coding standards, testing guidelines |
|
|
270
|
+
| **Architecture** | [docs/design.md](docs/design.md) | Core system narrative, data flow, invariants |
|
|
271
|
+
| **Workflow design** | [docs/design_workflows.md](docs/design_workflows.md) | Policy, skills, workflow runners, memory architecture |
|
|
272
|
+
| **CLI reference** | [docs/cli_reference.md](docs/cli_reference.md) | Terminal and direct-command inventory |
|
|
273
|
+
| **Work Board** | [docs/board/](docs/board/) | Cards, checklists, change log, implementation memory |
|
|
274
|
+
|
|
275
|
+
Common starting points: [sessions](docs/end-user/session.md), [proxies](docs/end-user/proxy.md),
|
|
276
|
+
[policy and supervision](docs/end-user/policy.md), [model selection](docs/end-user/model_selection.md),
|
|
277
|
+
[transfer context](docs/end-user/transfer.md), and [project memory](docs/end-user/memory.md).
|
|
278
|
+
|
|
279
|
+
## Troubleshooting
|
|
280
|
+
|
|
281
|
+
> [!NOTE]
|
|
282
|
+
> **Corrupt state?** If Forge reports that its state is corrupt, it names the offending file and stops -- it never
|
|
283
|
+
> silently runs on bad state. Run `forge clean` to preview what would be removed, then `forge clean --yes` to remove it
|
|
284
|
+
> (add `--scope all` to cover every project). For a full reset, delete `.forge` (project-local) or `~/.forge` (global)
|
|
285
|
+
> and re-run `forge extension enable`. Your own files and `proxy.yaml` config are never touched by `forge clean`.
|
|
286
|
+
|
|
287
|
+
`forge extension doctor` reports how Forge is installed, whether the launcher is reachable, and the state of the hook
|
|
288
|
+
dispatcher. Upgrading from a pre-OSS Forge install? See
|
|
289
|
+
[docs/end-user/README.md](docs/end-user/README.md#upgrading-from-pre-oss-forge).
|
|
290
|
+
|
|
291
|
+
## Contributing
|
|
292
|
+
|
|
293
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and PR guidelines.
|
|
294
|
+
|
|
295
|
+
## Uninstall
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
forge extension disable
|
|
299
|
+
uv tool uninstall multi-forge # or: pipx uninstall multi-forge
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
Apache 2.0 -- see [LICENSE](LICENSE).
|
|
305
|
+
|
|
306
|
+
Originally developed as Claude Forge at [Thomson Reuters](https://github.com/thomsonreuters/claude-forge) and
|
|
307
|
+
open-sourced under Apache 2.0. Continued as Multi-Forge by the original author.
|