multi-forge 0.9.0__tar.gz → 0.9.1__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.
Files changed (435) hide show
  1. {multi_forge-0.9.0 → multi_forge-0.9.1}/PKG-INFO +1 -1
  2. {multi_forge-0.9.0 → multi_forge-0.9.1}/pyproject.toml +2 -1
  3. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/extensions.py +135 -21
  4. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/gc.py +1 -0
  5. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/workflow.py +43 -21
  6. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/invoker/__init__.py +2 -0
  7. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/invoker/_lifecycle.py +179 -169
  8. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/invoker/codex.py +6 -2
  9. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/invoker/types.py +4 -5
  10. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/gc.py +217 -2
  11. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/routing.py +6 -2
  12. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/installer.py +93 -15
  13. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/models.py +3 -0
  14. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/skill_compiler.py +108 -2
  15. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/skill_planning.py +58 -4
  16. multi_forge-0.9.1/src/forge/install/unmanaged.py +1025 -0
  17. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/adversarial.py +1 -0
  18. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/consensus.py +3 -1
  19. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/engine.py +147 -25
  20. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/models.py +50 -0
  21. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/routing.py +51 -16
  22. multi_forge-0.9.1/src/skills/analyze/content.md +72 -0
  23. multi_forge-0.9.1/src/skills/analyze/forge-skill.yaml +11 -0
  24. multi_forge-0.9.1/src/skills/consensus/content.md +85 -0
  25. multi_forge-0.9.1/src/skills/consensus/forge-skill.yaml +11 -0
  26. multi_forge-0.9.1/src/skills/debate/content.md +87 -0
  27. multi_forge-0.9.1/src/skills/debate/forge-skill.yaml +11 -0
  28. multi_forge-0.9.1/src/skills/panel/content.md +88 -0
  29. multi_forge-0.9.1/src/skills/panel/forge-skill.yaml +10 -0
  30. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/14-workflow.md +50 -9
  31. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/15-skills.md +10 -6
  32. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/17-info.md +7 -6
  33. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/18-disable.md +4 -2
  34. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/19-uninstall.md +2 -2
  35. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/2-extension.md +70 -17
  36. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist.md +17 -13
  37. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/walkthrough/resources/checklist.md +15 -14
  38. multi_forge-0.9.0/src/skills/analyze/SKILL.md +0 -87
  39. multi_forge-0.9.0/src/skills/consensus/SKILL.md +0 -120
  40. multi_forge-0.9.0/src/skills/debate/SKILL.md +0 -116
  41. multi_forge-0.9.0/src/skills/panel/SKILL.md +0 -141
  42. {multi_forge-0.9.0 → multi_forge-0.9.1}/.gitignore +0 -0
  43. {multi_forge-0.9.0 → multi_forge-0.9.1}/LICENSE +0 -0
  44. {multi_forge-0.9.0 → multi_forge-0.9.1}/NOTICE +0 -0
  45. {multi_forge-0.9.0 → multi_forge-0.9.1}/README.md +0 -0
  46. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/agents/.gitkeep +0 -0
  47. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/commands/.gitkeep +0 -0
  48. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/__init__.py +0 -0
  49. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/backend/__init__.py +0 -0
  50. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/backend/adapters/__init__.py +0 -0
  51. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/backend/adapters/litellm.py +0 -0
  52. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/backend/creation.py +0 -0
  53. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/backend/registry.py +0 -0
  54. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/backend/remote/__init__.py +0 -0
  55. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/backend/remote/base.py +0 -0
  56. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/backend/remote/openrouter.py +0 -0
  57. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/backend/sources.py +0 -0
  58. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/__init__.py +0 -0
  59. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/activity.py +0 -0
  60. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/auth.py +0 -0
  61. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/backend.py +0 -0
  62. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/claude.py +0 -0
  63. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/codex.py +0 -0
  64. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/config_cmd.py +0 -0
  65. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/consumer_lane_freeze.py +0 -0
  66. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/editor.py +0 -0
  67. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/guards.py +0 -0
  68. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/__init__.py +0 -0
  69. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/_group.py +0 -0
  70. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/_helpers.py +0 -0
  71. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/codex_patch.py +0 -0
  72. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/codex_policy.py +0 -0
  73. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/codex_transfer.py +0 -0
  74. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/commands.py +0 -0
  75. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/direct_commands.py +0 -0
  76. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/policy.py +0 -0
  77. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/protocols.py +0 -0
  78. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/read_hygiene.py +0 -0
  79. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/hooks/verification.py +0 -0
  80. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/logs.py +0 -0
  81. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/main.py +0 -0
  82. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/memory.py +0 -0
  83. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/memory_report.py +0 -0
  84. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/memory_writer.py +0 -0
  85. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/model.py +0 -0
  86. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/output.py +0 -0
  87. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/policy.py +0 -0
  88. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/proxy.py +0 -0
  89. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/proxy_audit.py +0 -0
  90. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/proxy_costs.py +0 -0
  91. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/runtime.py +0 -0
  92. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/search.py +0 -0
  93. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session.py +0 -0
  94. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_codex.py +0 -0
  95. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_fork.py +0 -0
  96. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_lane.py +0 -0
  97. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_lifecycle.py +0 -0
  98. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_manage.py +0 -0
  99. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_memory.py +0 -0
  100. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_model_pin.py +0 -0
  101. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_resume_modes.py +0 -0
  102. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_rewind.py +0 -0
  103. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_routing.py +0 -0
  104. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/session_supervisor_options.py +0 -0
  105. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/status_line.py +0 -0
  106. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/statusline/__init__.py +0 -0
  107. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/statusline/context.py +0 -0
  108. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/statusline/names.py +0 -0
  109. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/statusline/palette.py +0 -0
  110. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/statusline/registry.py +0 -0
  111. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/statusline/throttle.py +0 -0
  112. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/telemetry.py +0 -0
  113. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/trace.py +0 -0
  114. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/cli/transfer.py +0 -0
  115. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/__init__.py +0 -0
  116. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/dataclass_utils.py +0 -0
  117. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/__init__.py +0 -0
  118. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/backends/__init__.py +0 -0
  119. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/backends/litellm.yaml +0 -0
  120. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/__init__.py +0 -0
  121. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/anthropic-passthrough.yaml +0 -0
  122. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/codex-responses-local.yaml +0 -0
  123. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/litellm-anthropic-local.yaml +0 -0
  124. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/litellm-anthropic.yaml +0 -0
  125. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/litellm-gemini-flash-local.yaml +0 -0
  126. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/litellm-gemini-local.yaml +0 -0
  127. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/litellm-gemini-test.yaml +0 -0
  128. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/litellm-gemini.yaml +0 -0
  129. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/litellm-openai-codex-local.yaml +0 -0
  130. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/litellm-openai-local.yaml +0 -0
  131. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/litellm-openai.yaml +0 -0
  132. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-anthropic.yaml +0 -0
  133. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-deepseek.yaml +0 -0
  134. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-gemini-flash.yaml +0 -0
  135. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-gemini.yaml +0 -0
  136. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-glm.yaml +0 -0
  137. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-kimi.yaml +0 -0
  138. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-minimax.yaml +0 -0
  139. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-openai-codex.yaml +0 -0
  140. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-openai.yaml +0 -0
  141. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/defaults/templates/openrouter-qwen.yaml +0 -0
  142. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/loader.py +0 -0
  143. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/config/schema.py +0 -0
  144. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/__init__.py +0 -0
  145. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/auth/__init__.py +0 -0
  146. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/auth/capabilities.py +0 -0
  147. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/auth/credentials_file.py +0 -0
  148. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/auth/protocols.py +0 -0
  149. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/auth/secrets.py +0 -0
  150. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/auth/template_secrets.py +0 -0
  151. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/backend_dependency.py +0 -0
  152. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/credential_registry.py +0 -0
  153. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/data/__init__.py +0 -0
  154. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/data/model_catalog.yaml +0 -0
  155. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/data/system_prompt_addendums/__init__.py +0 -0
  156. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/data/system_prompt_addendums/gemini.md +0 -0
  157. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/data/system_prompt_addendums/openai.md +0 -0
  158. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/effort.py +0 -0
  159. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/invoker/claude.py +0 -0
  160. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/invoker/codex_stream.py +0 -0
  161. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/lanes.py +0 -0
  162. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/__init__.py +0 -0
  163. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/clients/__init__.py +0 -0
  164. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/clients/base.py +0 -0
  165. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/clients/litellm.py +0 -0
  166. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/clients/openai_compat.py +0 -0
  167. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/clients/openrouter.py +0 -0
  168. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/credentials.py +0 -0
  169. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/detection.py +0 -0
  170. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/errors.py +0 -0
  171. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/protocols.py +0 -0
  172. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/llm/types.py +0 -0
  173. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/logging.py +0 -0
  174. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/models/__init__.py +0 -0
  175. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/models/catalog.py +0 -0
  176. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/models/direct_model.py +0 -0
  177. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/models/types.py +0 -0
  178. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/naming.py +0 -0
  179. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/__init__.py +0 -0
  180. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/backend_reconcile.py +0 -0
  181. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/claude_session.py +0 -0
  182. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/codex_bridge.py +0 -0
  183. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/codex_enrollment.py +0 -0
  184. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/codex_interactive.py +0 -0
  185. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/codex_session.py +0 -0
  186. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/context.py +0 -0
  187. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/policy.py +0 -0
  188. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/provider_trace.py +0 -0
  189. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/proxy.py +0 -0
  190. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/resolution.py +0 -0
  191. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/session.py +0 -0
  192. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/session_context.py +0 -0
  193. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/transfer.py +0 -0
  194. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/ops/usage_summary.py +0 -0
  195. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/paths.py +0 -0
  196. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/process.py +0 -0
  197. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/provider_types.py +0 -0
  198. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/__init__.py +0 -0
  199. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/cost_tracking.py +0 -0
  200. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/env.py +0 -0
  201. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/headless_json.py +0 -0
  202. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/proxy.py +0 -0
  203. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/session_runner.py +0 -0
  204. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/structured_output.py +0 -0
  205. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/tagger.py +0 -0
  206. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/reactive/throttle.py +0 -0
  207. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/run_id.py +0 -0
  208. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/runtime/__init__.py +0 -0
  209. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/runtime/codex_preflight.py +0 -0
  210. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/runtime/codex_preflight_cache.py +0 -0
  211. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/runtime/codex_rollouts.py +0 -0
  212. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/runtime/registry.py +0 -0
  213. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/runtime_vocab.py +0 -0
  214. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/state/__init__.py +0 -0
  215. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/state/exceptions.py +0 -0
  216. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/state/io.py +0 -0
  217. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/state/lock.py +0 -0
  218. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/state/retention.py +0 -0
  219. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/state/timestamps.py +0 -0
  220. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/state/versioned_store.py +0 -0
  221. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/telemetry/__init__.py +0 -0
  222. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/telemetry/caps.py +0 -0
  223. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/telemetry/downstream.py +0 -0
  224. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/telemetry/jsonl_io.py +0 -0
  225. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/telemetry/upstream.py +0 -0
  226. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/telemetry/vocabulary.py +0 -0
  227. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/tiers.py +0 -0
  228. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/transcript.py +0 -0
  229. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/typing_helpers.py +0 -0
  230. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/usage/__init__.py +0 -0
  231. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/usage/billing.py +0 -0
  232. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/usage/correlation.py +0 -0
  233. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/usage/emit.py +0 -0
  234. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/usage/ledger.py +0 -0
  235. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/usage/measurement.py +0 -0
  236. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/usage/vocabulary.py +0 -0
  237. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/workqueue/__init__.py +0 -0
  238. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/workqueue/queue.py +0 -0
  239. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/core/workqueue/types.py +0 -0
  240. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/__init__.py +0 -0
  241. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/cli.py +0 -0
  242. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/codex_hooks.py +0 -0
  243. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/doctor.py +0 -0
  244. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/exceptions.py +0 -0
  245. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/hook_dispatcher.py +0 -0
  246. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/hook_migration.py +0 -0
  247. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/hooks.py +0 -0
  248. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/preset.py +0 -0
  249. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/project_compat.py +0 -0
  250. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/project_registry.py +0 -0
  251. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/settings_merge.py +0 -0
  252. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/skill_cache.py +0 -0
  253. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/skill_validation.py +0 -0
  254. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/tracking.py +0 -0
  255. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/install/version.py +0 -0
  256. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/__init__.py +0 -0
  257. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/deterministic/__init__.py +0 -0
  258. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/deterministic/base.py +0 -0
  259. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/deterministic/coding_standards.py +0 -0
  260. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/deterministic/registry.py +0 -0
  261. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/deterministic/tdd.py +0 -0
  262. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/engine.py +0 -0
  263. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/protocols.py +0 -0
  264. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/queries.py +0 -0
  265. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/semantic/__init__.py +0 -0
  266. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/semantic/plan_check.py +0 -0
  267. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/semantic/shadow.py +0 -0
  268. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/semantic/shadow_runner.py +0 -0
  269. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/semantic/supervisor.py +0 -0
  270. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/semantic/verdict.py +0 -0
  271. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/store.py +0 -0
  272. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/supervisor_lane_degrade.py +0 -0
  273. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/team/__init__.py +0 -0
  274. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/team/config.py +0 -0
  275. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/team/handlers.py +0 -0
  276. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/team/prompts.py +0 -0
  277. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/types.py +0 -0
  278. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/workflow/__init__.py +0 -0
  279. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/workflow/branches.py +0 -0
  280. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/workflow/config.py +0 -0
  281. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/workflow/divergence.py +0 -0
  282. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/workflow/policy.py +0 -0
  283. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/policy/workflow/stages.py +0 -0
  284. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/__init__.py +0 -0
  285. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/audit_logger.py +0 -0
  286. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/base_client.py +0 -0
  287. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/client_adapter.py +0 -0
  288. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/client_factory.py +0 -0
  289. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/converters.py +0 -0
  290. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/cost_logger.py +0 -0
  291. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/cost_tracker.py +0 -0
  292. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/data_models.py +0 -0
  293. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/error_hints.py +0 -0
  294. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/intercept.py +0 -0
  295. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/metrics.py +0 -0
  296. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/model_spec.py +0 -0
  297. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/passthrough.py +0 -0
  298. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/ports.py +0 -0
  299. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/provider_trace_logger.py +0 -0
  300. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/proxies.py +0 -0
  301. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/proxy_identity.py +0 -0
  302. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/proxy_orchestrator.py +0 -0
  303. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/proxy_startup.py +0 -0
  304. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/responses_ingress.py +0 -0
  305. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/responses_passthrough.py +0 -0
  306. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/server.py +0 -0
  307. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/stream_relay.py +0 -0
  308. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/proxy/utils.py +0 -0
  309. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/__init__.py +0 -0
  310. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/__init__.py +0 -0
  311. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/code_consensus_evaluation.md +0 -0
  312. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/code_debate_evaluation.md +0 -0
  313. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/codereview-performance.md +0 -0
  314. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/codereview-quick.md +0 -0
  315. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/codereview-security.md +0 -0
  316. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/codereview.md +0 -0
  317. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/consensus_evaluation.md +0 -0
  318. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/debate_evaluation.md +0 -0
  319. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/docreview-quick.md +0 -0
  320. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/docreview.md +0 -0
  321. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/resources/thinkdeep.md +0 -0
  322. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/review/synthesis.py +0 -0
  323. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/runtime_config.py +0 -0
  324. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/search/__init__.py +0 -0
  325. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/search/bm25_store.py +0 -0
  326. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/search/content_store.py +0 -0
  327. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/search/engine.py +0 -0
  328. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/search/exceptions.py +0 -0
  329. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/search/extractor.py +0 -0
  330. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/search/index_state.py +0 -0
  331. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/search/store.py +0 -0
  332. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/search/tokenizer.py +0 -0
  333. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/__init__.py +0 -0
  334. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/active.py +0 -0
  335. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/addendum.py +0 -0
  336. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/artifacts.py +0 -0
  337. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/claude/__init__.py +0 -0
  338. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/claude/cleanup.py +0 -0
  339. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/claude/invoke.py +0 -0
  340. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/claude/paths.py +0 -0
  341. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/claude/relocate.py +0 -0
  342. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/cleanup.py +0 -0
  343. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/codex_handoff.py +0 -0
  344. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/codex_invoke.py +0 -0
  345. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/config.py +0 -0
  346. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/consumer_lanes.py +0 -0
  347. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/context_limit.py +0 -0
  348. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/effective.py +0 -0
  349. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/exceptions.py +0 -0
  350. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/hooks/__init__.py +0 -0
  351. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/hooks/models.py +0 -0
  352. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/hooks/session_start.py +0 -0
  353. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/identity.py +0 -0
  354. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/index.py +0 -0
  355. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/launch.py +0 -0
  356. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/launch_confirmation.py +0 -0
  357. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/manager.py +0 -0
  358. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/memory_inheritance.py +0 -0
  359. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/memory_writer.py +0 -0
  360. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/model_pin.py +0 -0
  361. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/models.py +0 -0
  362. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/overrides.py +0 -0
  363. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/passport.py +0 -0
  364. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/plan_resolution.py +0 -0
  365. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/prev_sessions.py +0 -0
  366. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/project_memory.py +0 -0
  367. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/rewind.py +0 -0
  368. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/shadow_curation.py +0 -0
  369. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/store.py +0 -0
  370. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/transfer.py +0 -0
  371. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/validation.py +0 -0
  372. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/worktree/__init__.py +0 -0
  373. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/worktree/cleanup.py +0 -0
  374. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/worktree/config_copy.py +0 -0
  375. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/session/worktree/create.py +0 -0
  376. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/sidecar/__init__.py +0 -0
  377. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/sidecar/container.py +0 -0
  378. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/forge/sidecar/docker.py +0 -0
  379. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/challenge/content.md +0 -0
  380. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/challenge/forge-skill.yaml +0 -0
  381. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/consensus/resources/synthesis.md +0 -0
  382. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/panel/resources/synthesis.md +0 -0
  383. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/SKILL.md +0 -0
  384. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/0-enable.md +0 -0
  385. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/1-preflight.md +0 -0
  386. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/10-resume.md +0 -0
  387. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/11-config.md +0 -0
  388. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/12-search.md +0 -0
  389. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/13-policy.md +0 -0
  390. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/16-memory.md +0 -0
  391. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/20-cleanup.md +0 -0
  392. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/3-authentication.md +0 -0
  393. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/4-proxy.md +0 -0
  394. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/5-session.md +0 -0
  395. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/6-hook.md +0 -0
  396. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/7-costs.md +0 -0
  397. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/8-status-line.md +0 -0
  398. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/checklist/9-direct-commands.md +0 -0
  399. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/resources/report-template.md +0 -0
  400. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/scripts/start-container.sh +0 -0
  401. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/qa/scripts/walkthrough-state.py +0 -0
  402. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/content.md +0 -0
  403. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/forge-skill.yaml +0 -0
  404. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/references/claude-4.6.md +0 -0
  405. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/references/claude-4.8.md +0 -0
  406. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/references/gemini-3.1.md +0 -0
  407. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/references/gpt-5.5.md +0 -0
  408. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/references/skills-writing-guide.md +0 -0
  409. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/resources/code-anthropic.md +0 -0
  410. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/resources/code-gemini.md +0 -0
  411. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/resources/code-openai.md +0 -0
  412. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review/resources/code.md +0 -0
  413. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review-docs/content.md +0 -0
  414. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review-docs/forge-skill.yaml +0 -0
  415. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review-docs/resources/docs-anthropic.md +0 -0
  416. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review-docs/resources/docs-gemini.md +0 -0
  417. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review-docs/resources/docs-openai.md +0 -0
  418. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/review-docs/resources/docs.md +0 -0
  419. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/smoke-test/content.md +0 -0
  420. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/smoke-test/forge-skill.yaml +0 -0
  421. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/smoke-test/scripts/smoke-test.sh +0 -0
  422. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/content.md +0 -0
  423. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/forge-skill.yaml +0 -0
  424. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/resources/code-anthropic.md +0 -0
  425. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/resources/code-gemini.md +0 -0
  426. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/resources/code-openai.md +0 -0
  427. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/resources/code.md +0 -0
  428. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/resources/docs-anthropic.md +0 -0
  429. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/resources/docs-gemini.md +0 -0
  430. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/resources/docs-openai.md +0 -0
  431. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/understand/resources/docs.md +0 -0
  432. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/walkthrough/SKILL.md +0 -0
  433. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/walkthrough/scripts/run-in-repo.sh +0 -0
  434. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/walkthrough/scripts/setup-test-repo.sh +0 -0
  435. {multi_forge-0.9.0 → multi_forge-0.9.1}/src/skills/walkthrough/scripts/walkthrough-state.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multi-forge
3
- Version: 0.9.0
3
+ Version: 0.9.1
4
4
  Summary: Multi-runtime agent toolkit: proxy routing, cost control, session management, policy enforcement, and workflow orchestration
5
5
  Project-URL: Homepage, https://github.com/hapa1i/multi-forge
6
6
  Project-URL: Repository, https://github.com/hapa1i/multi-forge
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "multi-forge"
3
- version = "0.9.0"
3
+ version = "0.9.1"
4
4
  description = "Multi-runtime agent toolkit: proxy routing, cost control, session management, policy enforcement, and workflow orchestration"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -124,6 +124,7 @@ constraint-dependencies = [
124
124
  "virtualenv>=20.36.1",
125
125
  "aiohttp>=3.14.1",
126
126
  "cryptography>=48.0.1",
127
+ "mcp>=1.28.1",
127
128
  "python-multipart>=0.0.31",
128
129
  "Pygments>=2.20.0",
129
130
  "PyJWT>=2.13.0",
@@ -43,17 +43,20 @@ from forge.install.installer import (
43
43
  Installer,
44
44
  find_claude_root,
45
45
  find_forge_installation,
46
+ get_extensions_root,
46
47
  inspect_skill_package_status,
47
48
  )
48
49
  from forge.install.models import (
49
50
  FILE_MODULES,
50
51
  PROFILE_RANK,
52
+ InstalledManifest,
51
53
  InstallMode,
52
54
  InstallModule,
53
55
  InstallPlan,
54
56
  InstallProfile,
55
57
  InstallScope,
56
58
  get_gated_skills,
59
+ parse_installation_key,
57
60
  )
58
61
  from forge.install.project_compat import (
59
62
  ProjectCompatibilityError,
@@ -61,7 +64,13 @@ from forge.install.project_compat import (
61
64
  format_project_compatibility_recovery,
62
65
  )
63
66
  from forge.install.project_registry import EnrollmentSource, ProjectRegistryStore
67
+ from forge.install.skill_compiler import discover_skill_source_names
64
68
  from forge.install.tracking import TrackingStore
69
+ from forge.install.unmanaged import (
70
+ runtime_skill_scan_roots,
71
+ scan_unmanaged_skill_state,
72
+ )
73
+ from forge.session.claude.paths import get_claude_home
65
74
 
66
75
  console = Console()
67
76
  _log = logging.getLogger(__name__)
@@ -561,6 +570,11 @@ def _print_plan(plan: InstallPlan, dry_run: bool = False) -> None:
561
570
  style=style,
562
571
  )
563
572
  console.print(table)
573
+ for package in plan.skill_packages:
574
+ if package.recovery:
575
+ console.print(
576
+ f" [yellow]{package.runtime}/{package.skill} recovery:[/yellow] {escape(package.recovery)}"
577
+ )
564
578
 
565
579
  if plan.files:
566
580
  console.print(f"\n{prefix}[bold]Files:[/bold]")
@@ -726,14 +740,21 @@ def _can_resolve_project_root(scope: InstallScope, *, anchor: Path | None = None
726
740
  return False
727
741
 
728
742
 
729
- def _resolve_status_project_root(scope: InstallScope, anchor: Path | None) -> Path | None:
743
+ def _resolve_status_project_root(
744
+ scope: InstallScope,
745
+ anchor: Path | None,
746
+ tracking_snapshot: InstalledManifest | None = None,
747
+ ) -> Path | None:
730
748
  """Resolve a status lookup root, including tracked installs without ``.claude``."""
731
749
 
732
750
  try:
733
751
  return _resolve_project_root(scope, anchor=anchor)
734
752
  except NoClaudeDirectoryError:
735
753
  try:
736
- detected_scope, detected_root = find_forge_installation(start=anchor)
754
+ detected_scope, detected_root = find_forge_installation(
755
+ start=anchor,
756
+ tracking_snapshot=tracking_snapshot,
757
+ )
737
758
  except NoForgeInstallationError:
738
759
  return None
739
760
  return detected_root if detected_scope == scope else None
@@ -1346,7 +1367,10 @@ def status_cmd(scope: str | None, path: str | None, show_all: bool, as_json: boo
1346
1367
  # A corrupt installed.json raises TrackingCorruptedError (a StateCorruptedError);
1347
1368
  # it propagates to the top-level handler for the uniform reset tip.
1348
1369
  tracking = TrackingStore()
1349
- tracked_installations = tracking.list_installations()
1370
+ manifest = tracking.read()
1371
+ tracked_installations = [
1372
+ (*parse_installation_key(key), installation) for key, installation in manifest.installations.items()
1373
+ ]
1350
1374
  installations_by_target = {
1351
1375
  (tracked_scope, project_path): installation
1352
1376
  for tracked_scope, project_path, installation in tracked_installations
@@ -1363,7 +1387,7 @@ def status_cmd(scope: str | None, path: str | None, show_all: bool, as_json: boo
1363
1387
  scopes = [InstallScope.USER, InstallScope.PROJECT, InstallScope.LOCAL]
1364
1388
  elif scope is None and anchor is None:
1365
1389
  try:
1366
- detected_scope, detected_root = find_forge_installation()
1390
+ detected_scope, detected_root = find_forge_installation(tracking_snapshot=manifest)
1367
1391
  detected_scope_name = detected_scope.value
1368
1392
  scopes = [detected_scope]
1369
1393
  except NoForgeInstallationError:
@@ -1371,7 +1395,10 @@ def status_cmd(scope: str | None, path: str | None, show_all: bool, as_json: boo
1371
1395
  elif scope is None and anchor is not None:
1372
1396
  # --root without --scope: auto-detect scope at that path
1373
1397
  try:
1374
- detected_scope, detected_root = find_forge_installation(start=anchor)
1398
+ detected_scope, detected_root = find_forge_installation(
1399
+ start=anchor,
1400
+ tracking_snapshot=manifest,
1401
+ )
1375
1402
  detected_scope_name = detected_scope.value
1376
1403
  scopes = [detected_scope]
1377
1404
  except NoForgeInstallationError:
@@ -1382,12 +1409,59 @@ def status_cmd(scope: str | None, path: str | None, show_all: bool, as_json: boo
1382
1409
  # Use the detected root (from walk-up) over the raw anchor for lookups.
1383
1410
  effective_anchor = detected_root if detected_root is not None else anchor
1384
1411
 
1412
+ scope_contexts = [
1413
+ (
1414
+ selected_scope,
1415
+ _resolve_status_project_root(
1416
+ selected_scope,
1417
+ effective_anchor,
1418
+ tracking_snapshot=manifest,
1419
+ ),
1420
+ )
1421
+ for selected_scope in scopes
1422
+ ]
1423
+ non_user_scopes = [selected_scope for selected_scope in scopes if selected_scope != InstallScope.USER]
1424
+ shared_scan_root = next(
1425
+ (
1426
+ project_root
1427
+ for selected_scope, project_root in scope_contexts
1428
+ if selected_scope != InstallScope.USER and project_root
1429
+ ),
1430
+ None,
1431
+ )
1432
+ scanner_scope_roots: list[tuple[InstallScope, Path | None]] = []
1433
+ for selected_scope, project_root in scope_contexts:
1434
+ if selected_scope == InstallScope.USER:
1435
+ scanner_scope_roots.append((selected_scope, None))
1436
+ elif project_root is not None:
1437
+ scanner_scope_roots.append((selected_scope, project_root))
1438
+ elif len(non_user_scopes) > 1 and shared_scan_root is not None:
1439
+ # `--all` scans both logical Claude scopes at the effective root
1440
+ # even when only one scope has a tracking/sidecar signal.
1441
+ scanner_scope_roots.append((selected_scope, shared_scan_root))
1442
+ try:
1443
+ current_skill_names = discover_skill_source_names(get_extensions_root() / InstallModule.SKILLS.value)
1444
+ except (OSError, ValueError) as exc:
1445
+ _log.warning("extension status: current skill names unavailable; using historical names only: %s", exc)
1446
+ current_skill_names = ()
1447
+ scan_roots = runtime_skill_scan_roots(
1448
+ scanner_scope_roots,
1449
+ user_home=Path.home(),
1450
+ claude_home=get_claude_home(),
1451
+ )
1452
+ unmanaged_scan = scan_unmanaged_skill_state(
1453
+ scan_roots,
1454
+ current_skill_names=current_skill_names,
1455
+ tracking=manifest,
1456
+ )
1457
+ unmanaged_packages = unmanaged_scan.packages
1458
+ unmanaged_root_issues = unmanaged_scan.root_issues
1459
+
1385
1460
  if as_json:
1386
1461
  import json
1387
1462
 
1388
- data = []
1389
- for s in scopes:
1390
- project_root = _resolve_status_project_root(s, effective_anchor)
1463
+ installations = []
1464
+ for s, project_root in scope_contexts:
1391
1465
  project_path_str = str(project_root) if project_root else None
1392
1466
 
1393
1467
  inst = installations_by_target.get((s.value, project_path_str))
@@ -1399,7 +1473,7 @@ def status_cmd(scope: str | None, path: str | None, show_all: bool, as_json: boo
1399
1473
  project_root,
1400
1474
  tracked_installations=tracked_installations,
1401
1475
  )
1402
- data.append(
1476
+ installations.append(
1403
1477
  {
1404
1478
  "scope": s.value,
1405
1479
  "profile": inst.profile,
@@ -1427,7 +1501,17 @@ def status_cmd(scope: str | None, path: str | None, show_all: bool, as_json: boo
1427
1501
  "updated_at": inst.updated_at,
1428
1502
  }
1429
1503
  )
1430
- click.echo(json.dumps(data, indent=2, default=str))
1504
+ click.echo(
1505
+ json.dumps(
1506
+ {
1507
+ "schema_version": 2,
1508
+ "installations": installations,
1509
+ "unmanaged_skill_packages": [package.to_dict() for package in unmanaged_packages],
1510
+ },
1511
+ indent=2,
1512
+ default=str,
1513
+ )
1514
+ )
1431
1515
  return
1432
1516
 
1433
1517
  if detected_scope_name:
@@ -1437,8 +1521,7 @@ def status_cmd(scope: str | None, path: str | None, show_all: bool, as_json: boo
1437
1521
  console.print(f"[dim]No extensions detected in {location}[/dim]")
1438
1522
  console.print("[dim]Showing all scopes for this location:[/dim]")
1439
1523
 
1440
- for s in scopes:
1441
- project_root = _resolve_status_project_root(s, effective_anchor)
1524
+ for s, project_root in scope_contexts:
1442
1525
  project_path_str = str(project_root) if project_root else None
1443
1526
 
1444
1527
  installation = installations_by_target.get((s.value, project_path_str))
@@ -1526,20 +1609,51 @@ def status_cmd(scope: str | None, path: str | None, show_all: bool, as_json: boo
1526
1609
  for f in installation.files:
1527
1610
  console.print(f" - {display_path(f.target_path)}")
1528
1611
 
1612
+ console.print("\n[bold]Unmanaged runtime skill packages[/bold]")
1613
+ if not unmanaged_packages and not unmanaged_root_issues:
1614
+ console.print(" [dim]None found in the selected runtime roots.[/dim]")
1615
+ elif unmanaged_packages:
1616
+ table = Table(show_header=True, header_style="bold", box=None, padding=(0, 1))
1617
+ table.add_column("RUNTIME")
1618
+ table.add_column("SKILL")
1619
+ table.add_column("SHAPE")
1620
+ table.add_column("PROVENANCE")
1621
+ table.add_column("TARGET")
1622
+ table.add_column("CLEANUP")
1623
+ for package in unmanaged_packages:
1624
+ table.add_row(
1625
+ package.runtime,
1626
+ package.skill,
1627
+ package.shape,
1628
+ package.provenance,
1629
+ display_path(package.target_dir),
1630
+ package.cleanup_scope or "report only",
1631
+ style="yellow" if package.cleanup_eligible else "red",
1632
+ )
1633
+ console.print(table)
1634
+ for package in unmanaged_packages:
1635
+ if package.collision_dirs:
1636
+ console.print(
1637
+ f" [red]{package.runtime}/{package.skill} collisions:[/red] "
1638
+ + ", ".join(display_path(path) for path in package.collision_dirs)
1639
+ )
1640
+ console.print(f" [dim]{package.runtime}/{package.skill}:[/dim] {package.cleanup_reason}")
1641
+ if package.recovery:
1642
+ console.print(f" [yellow]{package.runtime}/{package.skill}:[/yellow] {package.recovery}")
1643
+ for issue in unmanaged_root_issues:
1644
+ console.print(
1645
+ f" [red]Root not scanned:[/red] {display_path(issue.root_dir)} " f"({issue.runtime}): {issue.reason}"
1646
+ )
1647
+
1529
1648
  if scope is None and not show_all and anchor is None:
1530
1649
  local_installed = any(
1531
- tracking.get_installation(
1532
- s.value,
1533
- str(_resolve_project_root(s)) if s != InstallScope.USER else None,
1534
- )
1535
- for s in scopes
1536
- if s == InstallScope.USER or _can_resolve_project_root(s)
1650
+ (selected_scope.value, str(project_root) if project_root is not None else None) in installations_by_target
1651
+ for selected_scope, project_root in scope_contexts
1537
1652
  )
1538
1653
  if not local_installed:
1539
- all_installations = tracking.list_installations()
1540
- if all_installations:
1654
+ if tracked_installations:
1541
1655
  print_tip(
1542
- f"{len(all_installations)} installation(s) exist elsewhere. Run 'forge info' to see all.",
1656
+ f"{len(tracked_installations)} installation(s) exist elsewhere. Run 'forge info' to see all.",
1543
1657
  console=console,
1544
1658
  )
1545
1659
  else:
@@ -208,5 +208,6 @@ def _category_label(category: str) -> str:
208
208
  "search_docs": "Orphan search docs:",
209
209
  "dead_installations": "Dead installations:",
210
210
  "corrupt_state": "Corrupt state files:",
211
+ "unmanaged_skill_packages": "Unmanaged skill packages:",
211
212
  }
212
213
  return labels.get(category, f"{category}:")
@@ -87,11 +87,12 @@ def _run_preflight(
87
87
  *,
88
88
  as_json: bool = False,
89
89
  routing_plan: Any | None = None,
90
+ resume_id: str | None = None,
90
91
  ) -> None:
91
92
  """Check resolved routing/auth before spawning workers. Exit 1 on failure."""
92
93
  from forge.review.engine import preflight_check
93
94
 
94
- errors = preflight_check(specs, routing_plan=routing_plan)
95
+ errors = preflight_check(specs, routing_plan=routing_plan, resume_id=resume_id)
95
96
  warnings = _routing_plan_warnings(specs, routing_plan)
96
97
  if not errors:
97
98
  if not as_json:
@@ -107,12 +108,17 @@ def _run_preflight(
107
108
  print_error("Workflow preflight failed:")
108
109
  for err in errors:
109
110
  console.print(f" - {err}")
111
+ runtime_tips: list[str] = []
112
+ if any(spec.runtime == "claude_code" for spec in specs):
113
+ runtime_tips.append("Run 'command -v claude' to check the Claude worker runtime.")
114
+ if any(spec.runtime == "codex" for spec in specs):
115
+ runtime_tips.append("Run 'forge runtime preflight codex' to refresh Codex readiness.")
110
116
  print_tip(
111
117
  "Run 'forge workflow list-models' to check model availability.",
112
118
  "Run 'forge proxy list' to check proxy status.",
113
119
  "Run 'forge auth status' to check auth status.",
114
120
  "Run 'forge proxy create <template>' to create a proxy.",
115
- "Run 'command -v claude' to check worker runtime.",
121
+ *runtime_tips,
116
122
  console=console,
117
123
  )
118
124
  sys.exit(1)
@@ -151,16 +157,20 @@ def _resolved_models_summary(
151
157
  summary: dict[str, dict[str, Any]] = {}
152
158
  for idx, (spec, result) in enumerate(zip(specs, routing_plan.routes)):
153
159
  route = result.route
160
+ runtime_native = result.source == "runtime_native"
154
161
  worker_id = worker_ids[idx] if worker_ids and idx < len(worker_ids) else spec.effective_worker_id
155
162
  entry: dict[str, Any] = {
156
163
  "requested_model": spec.name,
157
164
  "model_id": spec.model_id,
158
165
  "resolved_model": route.model_ref if route else None,
159
- "provider": route.provider if route else None,
166
+ "provider": "openai" if runtime_native else (route.provider if route else None),
167
+ "runtime": spec.runtime,
160
168
  "source": result.source,
161
169
  "proxy": result.proxy_id,
162
170
  "template": result.template or (route.template_id if route else None),
163
171
  }
172
+ if runtime_native:
173
+ entry["model_selection"] = "runtime_default"
164
174
  if roles and worker_id in roles:
165
175
  entry[role_field] = roles[worker_id]
166
176
  if result.warning:
@@ -176,8 +186,13 @@ def _format_resolved_models(summary: dict[str, dict[str, Any]]) -> str:
176
186
 
177
187
  lines = ["Resolved models:"]
178
188
  for worker_id, item in summary.items():
179
- resolved = item.get("resolved_model") or "(unresolved)"
189
+ resolved = (
190
+ "(runtime default)"
191
+ if item.get("model_selection") == "runtime_default"
192
+ else item.get("resolved_model") or "(unresolved)"
193
+ )
180
194
  provider = item.get("provider") or "unknown"
195
+ runtime = item.get("runtime") or "unknown"
181
196
  proxy = item.get("proxy") or "(direct)"
182
197
  template = item.get("template") or "(direct)"
183
198
  requested = item.get("requested_model") or worker_id
@@ -185,7 +200,7 @@ def _format_resolved_models(summary: dict[str, dict[str, Any]]) -> str:
185
200
  stance = f", stance={item['stance']}" if item.get("stance") else ""
186
201
  lines.append(
187
202
  f"- {worker_id}: requested={requested}, resolved={resolved}, "
188
- f"provider={provider}, proxy={proxy}, template={template}{role}{stance}"
203
+ f"provider={provider}, runtime={runtime}, proxy={proxy}, template={template}{role}{stance}"
189
204
  )
190
205
  return "\n".join(lines) + "\n\n"
191
206
 
@@ -238,10 +253,10 @@ def workflow_cmd() -> None:
238
253
  "--available",
239
254
  "available_only",
240
255
  is_flag=True,
241
- help="Show only ready models (credentials configured and routing usable)",
256
+ help="Show only ready workers (runtime prerequisites and routing usable)",
242
257
  )
243
258
  def list_models(as_json: bool, available_only: bool) -> None:
244
- """Show workflow model readiness."""
259
+ """Show workflow worker readiness."""
245
260
  from forge.review.models import available_model_specs, check_model_availability
246
261
 
247
262
  availabilities = check_model_availability(available_model_specs())
@@ -255,6 +270,7 @@ def list_models(as_json: bool, available_only: bool) -> None:
255
270
  "name": a.spec.name,
256
271
  "model_id": a.spec.model_id,
257
272
  "family": a.spec.family,
273
+ "runtime": a.spec.runtime,
258
274
  "provider_refs": list(a.spec.provider_refs),
259
275
  "preferred_proxy": a.spec.preferred_proxy,
260
276
  "description": a.spec.description,
@@ -284,6 +300,9 @@ def _primary_credential(spec: ModelSpec) -> str:
284
300
  Uses derive_model_routes() to get the first route's credential,
285
301
  which is stable and deterministic (no registry read).
286
302
  """
303
+ if spec.runtime == "codex":
304
+ return "runtime-native"
305
+
287
306
  from forge.review.routing import derive_model_routes
288
307
 
289
308
  routes = derive_model_routes(spec)
@@ -328,11 +347,14 @@ def _print_grouped_models(availabilities: list) -> None:
328
347
  console.print("\n[bold]Available Models[/bold]\n")
329
348
 
330
349
  for cred_name, items in groups.items():
331
- env_var = _credential_env_var(cred_name)
332
- configured = _credential_configured(cred_name)
333
- config_tag = "[green]configured[/green]" if configured else "[yellow]not configured[/yellow]"
334
- env_display = f" ({env_var})" if env_var else ""
335
- console.print(f" [bold]{cred_name}[/bold]{env_display} [{config_tag}]")
350
+ if cred_name == "runtime-native":
351
+ console.print(" [bold]runtime-native[/bold] [[green]runtime preflight[/green]]")
352
+ else:
353
+ env_var = _credential_env_var(cred_name)
354
+ configured = _credential_configured(cred_name)
355
+ config_tag = "[green]configured[/green]" if configured else "[yellow]not configured[/yellow]"
356
+ env_display = f" ({env_var})" if env_var else ""
357
+ console.print(f" [bold]{cred_name}[/bold]{env_display} [{config_tag}]")
336
358
 
337
359
  for a in items:
338
360
  style = _STATUS_STYLES.get(a.status, "")
@@ -364,7 +386,7 @@ def _print_grouped_models(availabilities: list) -> None:
364
386
  "-m",
365
387
  type=str,
366
388
  default=None,
367
- help="Comma-separated model names (default: all)",
389
+ help="Comma-separated worker names across Claude/Codex runtimes (default: workflow quorum)",
368
390
  )
369
391
  @click.option("--timeout", "-t", type=int, default=600, help="Per-model timeout in seconds")
370
392
  @click.option("--json", "as_json", is_flag=True, help="Output as JSON")
@@ -405,7 +427,7 @@ def _print_grouped_models(availabilities: list) -> None:
405
427
  "effort",
406
428
  type=click.Choice(list(CLAUDE_EFFORT_LEVELS)),
407
429
  default=None,
408
- help="Per-worker reasoning effort (claude --effort: low/medium/high/xhigh/max)",
430
+ help="Claude workers only: reasoning effort (low/medium/high/xhigh/max)",
409
431
  )
410
432
  @click.pass_context
411
433
  def panel(
@@ -510,7 +532,7 @@ def panel(
510
532
  _handle_routing_error(e, as_json=as_json)
511
533
  return
512
534
 
513
- _run_preflight(specs, as_json=as_json, routing_plan=routing_plan)
535
+ _run_preflight(specs, as_json=as_json, routing_plan=routing_plan, resume_id=resume_id)
514
536
 
515
537
  from forge.core.invoker import Attribution
516
538
 
@@ -831,7 +853,7 @@ def _handle_review_output(
831
853
  "-m",
832
854
  type=str,
833
855
  default="claude-opus",
834
- help="Comma-separated model names (default: claude-opus)",
856
+ help="Comma-separated worker names across Claude/Codex runtimes (default: claude-opus)",
835
857
  )
836
858
  @click.option("--timeout", "-t", type=int, default=600, help="Per-model timeout in seconds")
837
859
  @click.option("--json", "as_json", is_flag=True, help="Output as JSON")
@@ -854,7 +876,7 @@ def _handle_review_output(
854
876
  "effort",
855
877
  type=click.Choice(list(CLAUDE_EFFORT_LEVELS)),
856
878
  default=None,
857
- help="Per-worker reasoning effort (claude --effort: low/medium/high/xhigh/max)",
879
+ help="Claude workers only: reasoning effort (low/medium/high/xhigh/max)",
858
880
  )
859
881
  @click.pass_context
860
882
  def analyze(
@@ -1036,7 +1058,7 @@ def _resolve_debate_prompt(
1036
1058
  "-m",
1037
1059
  type=str,
1038
1060
  default=None,
1039
- help="Comma-separated model names (default: all)",
1061
+ help="Comma-separated worker names across Claude/Codex runtimes (default: workflow quorum)",
1040
1062
  )
1041
1063
  @click.option("--timeout", "-t", type=int, default=600, help="Per-model timeout in seconds")
1042
1064
  @click.option("--json", "as_json", is_flag=True, help="Output as JSON")
@@ -1066,7 +1088,7 @@ def _resolve_debate_prompt(
1066
1088
  "effort",
1067
1089
  type=click.Choice(list(CLAUDE_EFFORT_LEVELS)),
1068
1090
  default=None,
1069
- help="Per-worker reasoning effort (claude --effort: low/medium/high/xhigh/max)",
1091
+ help="Claude workers only: reasoning effort (low/medium/high/xhigh/max)",
1070
1092
  )
1071
1093
  @click.pass_context
1072
1094
  def debate(
@@ -1567,7 +1589,7 @@ def _print_consensus_text(output: ConsensusOutput, resolved_models: dict[str, di
1567
1589
  "-m",
1568
1590
  type=str,
1569
1591
  default=None,
1570
- help="Comma-separated model names (default: all)",
1592
+ help="Comma-separated worker names across Claude/Codex runtimes (default: workflow quorum)",
1571
1593
  )
1572
1594
  @click.option(
1573
1595
  "--timeout",
@@ -1603,7 +1625,7 @@ def _print_consensus_text(output: ConsensusOutput, resolved_models: dict[str, di
1603
1625
  "effort",
1604
1626
  type=click.Choice(list(CLAUDE_EFFORT_LEVELS)),
1605
1627
  default=None,
1606
- help="Per-worker reasoning effort (claude --effort: low/medium/high/xhigh/max)",
1628
+ help="Claude workers only: reasoning effort (low/medium/high/xhigh/max)",
1607
1629
  )
1608
1630
  @click.pass_context
1609
1631
  def consensus(
@@ -8,6 +8,7 @@ ordered fan-out, timeouts) and per-job usage emission. Phase 5 adds a
8
8
 
9
9
  from .claude import ClaudeHeadlessInvoker
10
10
  from .codex import CodexHeadlessInvoker, prepare_codex_request
11
+ from ._lifecycle import run_grouped_parallel
11
12
  from .types import (
12
13
  Attribution,
13
14
  HeadlessInvoker,
@@ -23,4 +24,5 @@ __all__ = [
23
24
  "HeadlessRequest",
24
25
  "HeadlessResult",
25
26
  "prepare_codex_request",
27
+ "run_grouped_parallel",
26
28
  ]