ouroboros-ai 0.26.4.dev1__tar.gz → 0.26.5.dev2__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.

Potentially problematic release.


This version of ouroboros-ai might be problematic. Click here for more details.

Files changed (566) hide show
  1. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.claude-plugin/marketplace.json +1 -1
  2. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.claude-plugin/plugin.json +1 -1
  3. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/PKG-INFO +1 -1
  4. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/setup/SKILL.md +1 -1
  5. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/_version.py +2 -2
  6. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/init.py +3 -44
  7. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/pm.py +20 -4
  8. ouroboros_ai-0.26.5.dev2/src/ouroboros/cli/formatters/prompting.py +38 -0
  9. ouroboros_ai-0.26.5.dev2/tests/unit/cli/formatters/test_prompting.py +45 -0
  10. ouroboros_ai-0.26.5.dev2/tests/unit/cli/test_pm.py +39 -0
  11. ouroboros_ai-0.26.5.dev2/tests/unit/cli/test_pm_interactive_logging.py +212 -0
  12. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.claude/settings.json +0 -0
  13. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.claude-plugin/.mcp.json +0 -0
  14. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.env.example +0 -0
  15. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  16. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  17. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  18. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  19. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.github/workflows/dev-publish.yml +0 -0
  20. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.github/workflows/lint.yml +0 -0
  21. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.github/workflows/release.yml +0 -0
  22. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.github/workflows/test.yml +0 -0
  23. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.gitignore +0 -0
  24. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.mcp.json +0 -0
  25. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.ouroboros/mechanical.toml +0 -0
  26. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.pre-commit-config.yaml +0 -0
  27. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/.python-version +0 -0
  28. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/CHANGELOG.md +0 -0
  29. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/CLAUDE.md +0 -0
  30. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/CODE_OF_CONDUCT.md +0 -0
  31. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/CONTRIBUTING.md +0 -0
  32. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/HANDOFF.md +0 -0
  33. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/LICENSE +0 -0
  34. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/README.ko.md +0 -0
  35. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/README.md +0 -0
  36. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/SECURITY.md +0 -0
  37. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/UNINSTALL.md +0 -0
  38. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/cancel.md +0 -0
  39. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/evaluate.md +0 -0
  40. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/evolve.md +0 -0
  41. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/help.md +0 -0
  42. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/interview.md +0 -0
  43. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/ralph.md +0 -0
  44. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/run.md +0 -0
  45. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/seed.md +0 -0
  46. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/setup.md +0 -0
  47. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/status.md +0 -0
  48. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/tutorial.md +0 -0
  49. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/unstuck.md +0 -0
  50. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/commands/welcome.md +0 -0
  51. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/.gitignore +0 -0
  52. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/Cargo.lock +0 -0
  53. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/Cargo.toml +0 -0
  54. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/README.md +0 -0
  55. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/db.rs +0 -0
  56. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/main.rs +0 -0
  57. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/mock.rs +0 -0
  58. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/state.rs +0 -0
  59. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/views/dashboard.rs +0 -0
  60. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/views/execution.rs +0 -0
  61. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/views/lineage.rs +0 -0
  62. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/views/logs.rs +0 -0
  63. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/views/mod.rs +0 -0
  64. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/crates/ouroboros-tui/src/views/session_selector.rs +0 -0
  65. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/README.md +0 -0
  66. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/api/README.md +0 -0
  67. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/api/core.md +0 -0
  68. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/api/mcp.md +0 -0
  69. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/architecture.md +0 -0
  70. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/cli-reference.md +0 -0
  71. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/config-reference.md +0 -0
  72. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/contributing/architecture-overview.md +0 -0
  73. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/contributing/findings-registry.md +0 -0
  74. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/contributing/issue-quality-policy.md +0 -0
  75. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/contributing/key-patterns.md +0 -0
  76. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/contributing/testing-guide.md +0 -0
  77. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/examples/mcp-config.yaml +0 -0
  78. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/getting-started.md +0 -0
  79. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/guides/evaluation-pipeline.md +0 -0
  80. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/guides/evolution-loop.md +0 -0
  81. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/guides/issue-176-subagent-mcp-inheritance.md +0 -0
  82. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/guides/seed-authoring.md +0 -0
  83. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/guides/tui-usage.md +0 -0
  84. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/images/PLACEHOLDER_README.md +0 -0
  85. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/images/ouroboros.png +0 -0
  86. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/platform-support.md +0 -0
  87. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/runtime-capability-matrix.md +0 -0
  88. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/runtime-guides/claude-code.md +0 -0
  89. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/docs/runtime-guides/codex.md +0 -0
  90. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/coordinator_test_seed.yaml +0 -0
  91. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/dummy_seed.yaml +0 -0
  92. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/parallel_subac_test_seed.yaml +0 -0
  93. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/subac_test_seed.yaml +0 -0
  94. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/task_manager/README.md +0 -0
  95. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/task_manager/__init__.py +0 -0
  96. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/task_manager/__main__.py +0 -0
  97. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/task_manager/cli.py +0 -0
  98. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/task_manager/models.py +0 -0
  99. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/task_manager/storage.py +0 -0
  100. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/examples/test_display.py +0 -0
  101. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/hooks/hooks.json +0 -0
  102. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/llms-full.txt +0 -0
  103. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/llms.txt +0 -0
  104. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/project-context.md +0 -0
  105. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/pyproject.toml +0 -0
  106. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/drift-monitor.py +0 -0
  107. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/install.sh +0 -0
  108. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/keyword-detector.py +0 -0
  109. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/mcp-serve.sh +0 -0
  110. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/ralph-rewind.py +0 -0
  111. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/ralph.py +0 -0
  112. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/ralph.sh +0 -0
  113. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/session-start.py +0 -0
  114. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/sync-plugin-version.py +0 -0
  115. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/scripts/version-check.py +0 -0
  116. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/brownfield/SKILL.md +0 -0
  117. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/cancel/SKILL.md +0 -0
  118. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/evaluate/SKILL.md +0 -0
  119. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/evolve/SKILL.md +0 -0
  120. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/help/SKILL.md +0 -0
  121. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/interview/SKILL.md +0 -0
  122. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/pm/SKILL.md +0 -0
  123. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/qa/SKILL.md +0 -0
  124. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/ralph/SKILL.md +0 -0
  125. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/run/SKILL.md +0 -0
  126. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/seed/SKILL.md +0 -0
  127. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/status/SKILL.md +0 -0
  128. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/tutorial/SKILL.md +0 -0
  129. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/unstuck/SKILL.md +0 -0
  130. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/update/SKILL.md +0 -0
  131. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/skills/welcome/SKILL.md +0 -0
  132. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/__init__.py +0 -0
  133. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/__main__.py +0 -0
  134. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/__init__.py +0 -0
  135. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/advocate.md +0 -0
  136. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/analysis-agent.md +0 -0
  137. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/architect.md +0 -0
  138. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/breadth-keeper.md +0 -0
  139. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/code-executor.md +0 -0
  140. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/codebase-explorer.md +0 -0
  141. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/consensus-reviewer.md +0 -0
  142. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/contrarian.md +0 -0
  143. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/evaluator.md +0 -0
  144. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/hacker.md +0 -0
  145. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/judge.md +0 -0
  146. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/loader.py +0 -0
  147. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/ontologist.md +0 -0
  148. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/ontology-analyst.md +0 -0
  149. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/qa-judge.md +0 -0
  150. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/research-agent.md +0 -0
  151. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/researcher.md +0 -0
  152. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/seed-architect.md +0 -0
  153. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/seed-closer.md +0 -0
  154. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/semantic-evaluator.md +0 -0
  155. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/simplifier.md +0 -0
  156. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/agents/socratic-interviewer.md +0 -0
  157. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/__init__.py +0 -0
  158. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/ambiguity.py +0 -0
  159. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/brownfield.py +0 -0
  160. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/explore.py +0 -0
  161. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/interview.py +0 -0
  162. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/pm_document.py +0 -0
  163. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/pm_interview.py +0 -0
  164. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/pm_seed.py +0 -0
  165. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/question_classifier.py +0 -0
  166. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/bigbang/seed_generator.py +0 -0
  167. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/__init__.py +0 -0
  168. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/__init__.py +0 -0
  169. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/cancel.py +0 -0
  170. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/config.py +0 -0
  171. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/mcp.py +0 -0
  172. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/run.py +0 -0
  173. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/setup.py +0 -0
  174. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/status.py +0 -0
  175. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/tui.py +0 -0
  176. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/commands/uninstall.py +0 -0
  177. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/formatters/__init__.py +0 -0
  178. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/formatters/panels.py +0 -0
  179. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/formatters/progress.py +0 -0
  180. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/formatters/tables.py +0 -0
  181. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/formatters/workflow_display.py +0 -0
  182. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/cli/main.py +0 -0
  183. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/codex/__init__.py +0 -0
  184. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/codex/artifacts.py +0 -0
  185. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/codex/ouroboros.md +0 -0
  186. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/codex_permissions.py +0 -0
  187. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/config/__init__.py +0 -0
  188. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/config/loader.py +0 -0
  189. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/config/models.py +0 -0
  190. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/__init__.py +0 -0
  191. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/ac_tree.py +0 -0
  192. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/context.py +0 -0
  193. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/errors.py +0 -0
  194. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/file_lock.py +0 -0
  195. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/git_workflow.py +0 -0
  196. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/lineage.py +0 -0
  197. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/ontology_aspect.py +0 -0
  198. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/ontology_questions.py +0 -0
  199. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/project_paths.py +0 -0
  200. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/security.py +0 -0
  201. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/seed.py +0 -0
  202. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/text.py +0 -0
  203. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/types.py +0 -0
  204. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/core/worktree.py +0 -0
  205. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/__init__.py +0 -0
  206. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/artifact_collector.py +0 -0
  207. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/consensus.py +0 -0
  208. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/json_utils.py +0 -0
  209. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/languages.py +0 -0
  210. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/mechanical.py +0 -0
  211. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/models.py +0 -0
  212. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/pipeline.py +0 -0
  213. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/semantic.py +0 -0
  214. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/trigger.py +0 -0
  215. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evaluation/verification_artifacts.py +0 -0
  216. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/events/__init__.py +0 -0
  217. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/events/base.py +0 -0
  218. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/events/decomposition.py +0 -0
  219. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/events/evaluation.py +0 -0
  220. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/events/interview.py +0 -0
  221. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/events/lineage.py +0 -0
  222. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/events/ontology.py +0 -0
  223. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evolution/__init__.py +0 -0
  224. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evolution/convergence.py +0 -0
  225. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evolution/loop.py +0 -0
  226. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evolution/projector.py +0 -0
  227. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evolution/reflect.py +0 -0
  228. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evolution/regression.py +0 -0
  229. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/evolution/wonder.py +0 -0
  230. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/execution/__init__.py +0 -0
  231. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/execution/atomicity.py +0 -0
  232. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/execution/decomposition.py +0 -0
  233. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/execution/double_diamond.py +0 -0
  234. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/execution/subagent.py +0 -0
  235. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/__init__.py +0 -0
  236. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/client/__init__.py +0 -0
  237. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/client/adapter.py +0 -0
  238. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/client/manager.py +0 -0
  239. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/client/protocol.py +0 -0
  240. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/errors.py +0 -0
  241. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/job_manager.py +0 -0
  242. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/resources/__init__.py +0 -0
  243. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/resources/handlers.py +0 -0
  244. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/server/__init__.py +0 -0
  245. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/server/adapter.py +0 -0
  246. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/server/protocol.py +0 -0
  247. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/server/security.py +0 -0
  248. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/__init__.py +0 -0
  249. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/authoring_handlers.py +0 -0
  250. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/brownfield_handler.py +0 -0
  251. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/dashboard.py +0 -0
  252. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/definitions.py +0 -0
  253. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/evaluation_handlers.py +0 -0
  254. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/evolution_handlers.py +0 -0
  255. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/execution_handlers.py +0 -0
  256. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/job_handlers.py +0 -0
  257. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/pm_handler.py +0 -0
  258. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/qa.py +0 -0
  259. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/query_handlers.py +0 -0
  260. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/tools/registry.py +0 -0
  261. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/mcp/types.py +0 -0
  262. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/observability/__init__.py +0 -0
  263. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/observability/drift.py +0 -0
  264. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/observability/logging.py +0 -0
  265. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/observability/retrospective.py +0 -0
  266. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/__init__.py +0 -0
  267. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/adapter.py +0 -0
  268. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/codex_cli_runtime.py +0 -0
  269. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/command_dispatcher.py +0 -0
  270. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/coordinator.py +0 -0
  271. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/dependency_analyzer.py +0 -0
  272. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/events.py +0 -0
  273. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/execution_runtime_scope.py +0 -0
  274. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/execution_strategy.py +0 -0
  275. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/heartbeat.py +0 -0
  276. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/level_context.py +0 -0
  277. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/mcp_config.py +0 -0
  278. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/mcp_tools.py +0 -0
  279. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/parallel_executor.py +0 -0
  280. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/parallel_executor_models.py +0 -0
  281. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/runner.py +0 -0
  282. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/runtime_factory.py +0 -0
  283. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/runtime_message_projection.py +0 -0
  284. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/session.py +0 -0
  285. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/orchestrator/workflow_state.py +0 -0
  286. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/__init__.py +0 -0
  287. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/brownfield.py +0 -0
  288. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/checkpoint.py +0 -0
  289. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/event_store.py +0 -0
  290. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/migrations/__init__.py +0 -0
  291. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/migrations/runner.py +0 -0
  292. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/migrations/scripts/001_initial.sql +0 -0
  293. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/migrations/scripts/002_brownfield.sql +0 -0
  294. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/schema.py +0 -0
  295. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/persistence/uow.py +0 -0
  296. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/__init__.py +0 -0
  297. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/agents/__init__.py +0 -0
  298. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/agents/pool.py +0 -0
  299. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/agents/registry.py +0 -0
  300. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/orchestration/__init__.py +0 -0
  301. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/orchestration/router.py +0 -0
  302. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/orchestration/scheduler.py +0 -0
  303. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/skills/__init__.py +0 -0
  304. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/skills/docs.py +0 -0
  305. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/skills/executor.py +0 -0
  306. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/skills/keywords.py +0 -0
  307. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/plugin/skills/registry.py +0 -0
  308. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/pm/__init__.py +0 -0
  309. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/pm/renderer.py +0 -0
  310. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/providers/__init__.py +0 -0
  311. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/providers/anthropic_adapter.py +0 -0
  312. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/providers/base.py +0 -0
  313. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/providers/claude_code_adapter.py +0 -0
  314. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/providers/codex_cli_adapter.py +0 -0
  315. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/providers/codex_cli_stream.py +0 -0
  316. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/providers/factory.py +0 -0
  317. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/providers/litellm_adapter.py +0 -0
  318. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/py.typed +0 -0
  319. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/resilience/__init__.py +0 -0
  320. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/resilience/lateral.py +0 -0
  321. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/resilience/stagnation.py +0 -0
  322. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/routing/__init__.py +0 -0
  323. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/routing/complexity.py +0 -0
  324. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/routing/downgrade.py +0 -0
  325. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/routing/escalation.py +0 -0
  326. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/routing/router.py +0 -0
  327. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/routing/tiers.py +0 -0
  328. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/secondary/__init__.py +0 -0
  329. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/secondary/scheduler.py +0 -0
  330. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/secondary/todo_registry.py +0 -0
  331. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/strategies/__init__.py +0 -0
  332. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/strategies/devil_advocate.py +0 -0
  333. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/__init__.py +0 -0
  334. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/app.py +0 -0
  335. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/components/__init__.py +0 -0
  336. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/components/agents_panel.py +0 -0
  337. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/components/event_log.py +0 -0
  338. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/components/progress.py +0 -0
  339. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/components/token_tracker.py +0 -0
  340. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/events.py +0 -0
  341. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/__init__.py +0 -0
  342. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/confirm_rewind.py +0 -0
  343. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/dashboard.py +0 -0
  344. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/dashboard_v2.py +0 -0
  345. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/dashboard_v3.py +0 -0
  346. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/debug.py +0 -0
  347. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/execution.py +0 -0
  348. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/hud_dashboard.py +0 -0
  349. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/lineage_detail.py +0 -0
  350. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/lineage_selector.py +0 -0
  351. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/logs.py +0 -0
  352. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/screens/session_selector.py +0 -0
  353. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/widgets/__init__.py +0 -0
  354. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/widgets/ac_progress.py +0 -0
  355. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/widgets/ac_tree.py +0 -0
  356. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/widgets/agent_activity.py +0 -0
  357. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/widgets/cost_tracker.py +0 -0
  358. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/widgets/drift_meter.py +0 -0
  359. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/widgets/lineage_tree.py +0 -0
  360. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/widgets/parallel_graph.py +0 -0
  361. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/tui/widgets/phase_progress.py +0 -0
  362. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/verification/__init__.py +0 -0
  363. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/verification/extractor.py +0 -0
  364. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/verification/models.py +0 -0
  365. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/src/ouroboros/verification/verifier.py +0 -0
  366. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/__init__.py +0 -0
  367. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/conftest.py +0 -0
  368. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/e2e/__init__.py +0 -0
  369. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/e2e/conftest.py +0 -0
  370. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/e2e/test_cli_commands.py +0 -0
  371. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/e2e/test_full_workflow.py +0 -0
  372. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/e2e/test_session_persistence.py +0 -0
  373. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/fixtures/test_atomicity_seed.yml +0 -0
  374. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/__init__.py +0 -0
  375. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/conftest.py +0 -0
  376. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/mcp/__init__.py +0 -0
  377. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/mcp/conftest.py +0 -0
  378. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/mcp/test_client_adapter.py +0 -0
  379. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/mcp/test_client_manager.py +0 -0
  380. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/mcp/test_server_adapter.py +0 -0
  381. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/plugin/test_orchestration.py +0 -0
  382. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/test_codex_cli_passthrough_smoke.py +0 -0
  383. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/test_codex_skill_fallback.py +0 -0
  384. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/test_codex_skill_smoke.py +0 -0
  385. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/integration/test_entry_point.py +0 -0
  386. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/__init__.py +0 -0
  387. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/agents/__init__.py +0 -0
  388. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/agents/test_loader.py +0 -0
  389. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/__init__.py +0 -0
  390. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_ambiguity.py +0 -0
  391. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_brownfield.py +0 -0
  392. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_classifier_context.py +0 -0
  393. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_decide_later_items.py +0 -0
  394. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_explore.py +0 -0
  395. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_interview.py +0 -0
  396. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_pm_document_generator.py +0 -0
  397. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_pm_document_writer.py +0 -0
  398. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_pm_interview.py +0 -0
  399. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_pm_interview_brownfield_db.py +0 -0
  400. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_pm_seed_ac12.py +0 -0
  401. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_pm_seed_save.py +0 -0
  402. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_question_classifier.py +0 -0
  403. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/bigbang/test_seed_generator.py +0 -0
  404. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/__init__.py +0 -0
  405. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/formatters/__init__.py +0 -0
  406. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/formatters/test_console.py +0 -0
  407. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/formatters/test_panels.py +0 -0
  408. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/formatters/test_progress.py +0 -0
  409. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/formatters/test_tables.py +0 -0
  410. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/formatters/test_workflow_display.py +0 -0
  411. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_cancel.py +0 -0
  412. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_config.py +0 -0
  413. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_init_pm_seed_detection.py +0 -0
  414. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_init_runtime.py +0 -0
  415. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_main.py +0 -0
  416. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_mcp_nested_guard.py +0 -0
  417. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_mcp_startup_cleanup.py +0 -0
  418. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_pm_brownfield.py +0 -0
  419. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_pm_missing_litellm.py +0 -0
  420. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_pm_overwrite.py +0 -0
  421. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_pm_select_repos.py +0 -0
  422. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_run_qa.py +0 -0
  423. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_setup.py +0 -0
  424. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/cli/test_uninstall.py +0 -0
  425. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/config/__init__.py +0 -0
  426. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/config/test_loader.py +0 -0
  427. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/config/test_models.py +0 -0
  428. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/__init__.py +0 -0
  429. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_ac_tree.py +0 -0
  430. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_context.py +0 -0
  431. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_errors.py +0 -0
  432. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_git_workflow.py +0 -0
  433. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_lineage.py +0 -0
  434. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_ontology_aspect.py +0 -0
  435. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_ontology_questions.py +0 -0
  436. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_security.py +0 -0
  437. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_seed.py +0 -0
  438. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_types.py +0 -0
  439. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/core/test_worktree.py +0 -0
  440. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evaluation/__init__.py +0 -0
  441. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evaluation/test_consensus.py +0 -0
  442. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evaluation/test_json_utils.py +0 -0
  443. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evaluation/test_languages.py +0 -0
  444. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evaluation/test_mechanical.py +0 -0
  445. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evaluation/test_models.py +0 -0
  446. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evaluation/test_semantic.py +0 -0
  447. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evaluation/test_trigger.py +0 -0
  448. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evaluation/test_verification_artifacts.py +0 -0
  449. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/events/__init__.py +0 -0
  450. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/events/test_base.py +0 -0
  451. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/events/test_decomposition_events.py +0 -0
  452. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/evolution/test_wonder_scope.py +0 -0
  453. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/execution/__init__.py +0 -0
  454. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/execution/test_atomicity.py +0 -0
  455. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/execution/test_decomposition.py +0 -0
  456. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/execution/test_double_diamond.py +0 -0
  457. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/execution/test_subagent_isolation.py +0 -0
  458. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/__init__.py +0 -0
  459. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/client/__init__.py +0 -0
  460. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/client/test_adapter.py +0 -0
  461. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/client/test_manager.py +0 -0
  462. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/conftest.py +0 -0
  463. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/server/__init__.py +0 -0
  464. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/server/test_adapter.py +0 -0
  465. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/server/test_security.py +0 -0
  466. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/test_errors.py +0 -0
  467. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/test_job_manager.py +0 -0
  468. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/test_types.py +0 -0
  469. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/tools/__init__.py +0 -0
  470. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/tools/conftest.py +0 -0
  471. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/tools/test_brownfield_handler.py +0 -0
  472. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/tools/test_definitions.py +0 -0
  473. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/tools/test_pm_handler.py +0 -0
  474. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/tools/test_pm_handler_generate.py +0 -0
  475. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/tools/test_pm_handler_pending_reframe.py +0 -0
  476. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/tools/test_qa_integration.py +0 -0
  477. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/mcp/tools/test_registry.py +0 -0
  478. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/observability/__init__.py +0 -0
  479. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/observability/test_drift.py +0 -0
  480. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/observability/test_logging.py +0 -0
  481. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/observability/test_retrospective.py +0 -0
  482. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/__init__.py +0 -0
  483. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_adapter.py +0 -0
  484. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_codex_cli_runtime.py +0 -0
  485. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_codex_recursion_guard.py +0 -0
  486. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_command_dispatcher.py +0 -0
  487. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_coordinator.py +0 -0
  488. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_dependency_analyzer.py +0 -0
  489. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_events.py +0 -0
  490. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_execution_runtime_scope.py +0 -0
  491. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_execution_strategy.py +0 -0
  492. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_inflight_cancellation.py +0 -0
  493. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_level_context.py +0 -0
  494. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_mcp_config.py +0 -0
  495. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_mcp_tools.py +0 -0
  496. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_parallel_executor.py +0 -0
  497. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_parallel_executor_retry_resume.py +0 -0
  498. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_runner.py +0 -0
  499. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_runner_cancellation.py +0 -0
  500. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_runtime_factory.py +0 -0
  501. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_runtime_message_projection.py +0 -0
  502. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_session.py +0 -0
  503. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/orchestrator/test_workflow_state.py +0 -0
  504. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/persistence/__init__.py +0 -0
  505. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/persistence/test_brownfield_store.py +0 -0
  506. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/persistence/test_checkpoint.py +0 -0
  507. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/persistence/test_event_store.py +0 -0
  508. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/persistence/test_schema.py +0 -0
  509. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/persistence/test_uow.py +0 -0
  510. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/plugin/__init__.py +0 -0
  511. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/plugin/agents/__init__.py +0 -0
  512. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/plugin/agents/test_registry.py +0 -0
  513. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/plugin/orchestration/__init__.py +0 -0
  514. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/plugin/orchestration/test_model_router.py +0 -0
  515. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/plugin/skills/__init__.py +0 -0
  516. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/plugin/skills/test_keywords.py +0 -0
  517. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/plugin/skills/test_registry.py +0 -0
  518. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/pm/__init__.py +0 -0
  519. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/pm/test_renderer.py +0 -0
  520. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/providers/__init__.py +0 -0
  521. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/providers/test_base.py +0 -0
  522. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/providers/test_claude_code_adapter.py +0 -0
  523. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/providers/test_codex_cli_adapter.py +0 -0
  524. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/providers/test_factory.py +0 -0
  525. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/providers/test_litellm_adapter.py +0 -0
  526. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/resilience/__init__.py +0 -0
  527. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/resilience/test_lateral.py +0 -0
  528. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/resilience/test_stagnation.py +0 -0
  529. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/routing/__init__.py +0 -0
  530. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/routing/test_complexity.py +0 -0
  531. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/routing/test_downgrade.py +0 -0
  532. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/routing/test_escalation.py +0 -0
  533. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/routing/test_router.py +0 -0
  534. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/routing/test_tiers.py +0 -0
  535. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/scripts/test_keyword_detector.py +0 -0
  536. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/scripts/test_version_check.py +0 -0
  537. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/secondary/__init__.py +0 -0
  538. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/secondary/test_scheduler.py +0 -0
  539. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/secondary/test_todo_registry.py +0 -0
  540. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_artifact_collector.py +0 -0
  541. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_codex_artifacts.py +0 -0
  542. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_convergence.py +0 -0
  543. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_dashboard.py +0 -0
  544. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_dependencies_configured.py +0 -0
  545. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_evolve_rewind.py +0 -0
  546. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_evolve_step.py +0 -0
  547. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_graceful_shutdown.py +0 -0
  548. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_main_entry_point.py +0 -0
  549. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_module_structure.py +0 -0
  550. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_project_initialization.py +0 -0
  551. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_projector_rewind.py +0 -0
  552. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_ralph_parser.py +0 -0
  553. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_ralph_rewind.py +0 -0
  554. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_regression.py +0 -0
  555. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_tooling_configuration.py +0 -0
  556. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/test_verification.py +0 -0
  557. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/tui/__init__.py +0 -0
  558. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/tui/test_app.py +0 -0
  559. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/tui/test_cancelled_display.py +0 -0
  560. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/tui/test_events.py +0 -0
  561. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/tui/test_lineage_viewer.py +0 -0
  562. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/tui/test_screens.py +0 -0
  563. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/tui/test_session_selector_replay.py +0 -0
  564. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tests/unit/tui/test_widgets.py +0 -0
  565. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/tools/sync_github_project.py +0 -0
  566. {ouroboros_ai-0.26.4.dev1 → ouroboros_ai-0.26.5.dev2}/uv.lock +0 -0
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "ouroboros",
12
12
  "description": "Transform vague ideas into validated seed specifications through Socratic questioning and ontological analysis",
13
- "version": "0.26.3",
13
+ "version": "0.26.4",
14
14
  "author": {
15
15
  "name": "Q00",
16
16
  "email": "jqyu.lee@gmail.com"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ouroboros",
3
- "version": "0.26.3",
3
+ "version": "0.26.4",
4
4
  "description": "Self-improving AI workflow system. Crystallize requirements before execution with Socratic interview, ambiguity scoring, and 3-stage evaluation.",
5
5
  "author": {
6
6
  "name": "Q00",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ouroboros-ai
3
- Version: 0.26.4.dev1
3
+ Version: 0.26.5.dev2
4
4
  Summary: Specification-first workflow engine for AI coding agents. Works with Claude Code and Codex CLI.
5
5
  Author-email: Q00 <jqyu.lee@gmail.com>
6
6
  License-File: LICENSE
@@ -246,7 +246,7 @@ A backup will be created: CLAUDE.md.bak
246
246
  **If "Preview first", show:**
247
247
  ````markdown
248
248
  <!-- ooo:START -->
249
- <!-- ooo:VERSION:0.26.3 -->
249
+ <!-- ooo:VERSION:0.26.4 -->
250
250
  # Ouroboros — Specification-First AI Development
251
251
 
252
252
  > Before telling AI what to build, define what should be built.
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.26.4.dev1'
22
- __version_tuple__ = version_tuple = (0, 26, 4, 'dev1')
21
+ __version__ = version = '0.26.5.dev2'
22
+ __version_tuple__ = version_tuple = (0, 26, 5, 'dev2')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -10,8 +10,6 @@ from pathlib import Path
10
10
  from typing import Annotated
11
11
 
12
12
  import click
13
- from prompt_toolkit import PromptSession
14
- from prompt_toolkit.key_binding import KeyBindings, KeyPressEvent
15
13
  from rich.prompt import Confirm, Prompt
16
14
  import typer
17
15
  import yaml
@@ -26,6 +24,7 @@ from ouroboros.bigbang.interview import (
26
24
  from ouroboros.bigbang.seed_generator import SeedGenerator
27
25
  from ouroboros.cli.formatters import console
28
26
  from ouroboros.cli.formatters.panels import print_error, print_info, print_success, print_warning
27
+ from ouroboros.cli.formatters.prompting import multiline_prompt_async
29
28
  from ouroboros.config import get_clarification_model
30
29
  from ouroboros.observability import LoggingConfig, configure_logging
31
30
  from ouroboros.providers import create_llm_adapter
@@ -104,46 +103,6 @@ def _make_message_callback(debug: bool):
104
103
  return callback
105
104
 
106
105
 
107
- async def _multiline_prompt_async(prompt_text: str) -> str:
108
- """Get multiline input with proper paste handling.
109
-
110
- Behavior:
111
- - Enter: Submit input
112
- - Ctrl+J: Insert newline
113
- - Paste: Multiline text is preserved (via bracketed paste mode)
114
-
115
- Args:
116
- prompt_text: The prompt to display.
117
-
118
- Returns:
119
- The user's input (may contain newlines from paste).
120
-
121
- Raises:
122
- EOFError: If end-of-file is reached (e.g., stdin closed).
123
- KeyboardInterrupt: If user presses Ctrl+C.
124
- """
125
- bindings = KeyBindings()
126
-
127
- @bindings.add("c-j")
128
- def insert_newline(event: KeyPressEvent) -> None:
129
- event.current_buffer.insert_text("\n")
130
-
131
- @bindings.add("c-m")
132
- def submit(event: KeyPressEvent) -> None:
133
- event.current_buffer.validate_and_handle()
134
-
135
- console.print(f"[bold green]{prompt_text}[/] [dim](Enter: submit, Ctrl+J: newline)[/]")
136
-
137
- session: PromptSession[str] = PromptSession(
138
- message="> ",
139
- multiline=True,
140
- prompt_continuation=" ",
141
- key_bindings=bindings,
142
- )
143
-
144
- return await session.prompt_async()
145
-
146
-
147
106
  def _get_adapter(
148
107
  use_orchestrator: bool,
149
108
  backend: str | None = None,
@@ -219,7 +178,7 @@ async def _run_interview_loop(
219
178
  console.print()
220
179
 
221
180
  # Get user response (multiline-safe for paste)
222
- response = await _multiline_prompt_async("Your response")
181
+ response = await multiline_prompt_async("Your response")
223
182
 
224
183
  if not response.strip():
225
184
  print_error("Response cannot be empty. Please try again.")
@@ -791,7 +750,7 @@ def start(
791
750
  )
792
751
  console.print()
793
752
 
794
- context = asyncio.run(_multiline_prompt_async("What would you like to build?"))
753
+ context = asyncio.run(multiline_prompt_async("What would you like to build?"))
795
754
 
796
755
  if not resume and not context:
797
756
  print_error("Initial context is required when not resuming.")
@@ -19,7 +19,10 @@ import typer
19
19
  from ouroboros.bigbang.interview import InterviewRound
20
20
  from ouroboros.cli.formatters import console
21
21
  from ouroboros.cli.formatters.panels import print_error, print_info, print_success, print_warning
22
+ from ouroboros.cli.formatters.prompting import multiline_prompt_async
23
+ from ouroboros.config import get_clarification_model
22
24
  from ouroboros.core.types import Result
25
+ from ouroboros.observability import LoggingConfig, configure_logging
23
26
 
24
27
  app = typer.Typer(
25
28
  name="pm",
@@ -71,13 +74,13 @@ def pm_command(
71
74
  ),
72
75
  ] = None,
73
76
  model: Annotated[
74
- str,
77
+ str | None,
75
78
  typer.Option(
76
79
  "--model",
77
80
  "-m",
78
81
  help="LLM model to use for the PM interview.",
79
82
  ),
80
- ] = "anthropic/claude-sonnet-4-20250514",
83
+ ] = None,
81
84
  debug: Annotated[
82
85
  bool,
83
86
  typer.Option(
@@ -104,6 +107,13 @@ def pm_command(
104
107
  if ctx.invoked_subcommand is not None:
105
108
  return
106
109
 
110
+ if model is None:
111
+ model = get_clarification_model()
112
+
113
+ if debug:
114
+ configure_logging(LoggingConfig(log_level="DEBUG"))
115
+ print_info("Debug mode enabled - showing verbose logs")
116
+
107
117
  console.print("\n[bold cyan]Ouroboros PM Generator[/] - Product Requirements Document\n")
108
118
 
109
119
  if resume:
@@ -388,12 +398,13 @@ async def _run_pm_interview(
388
398
  opening = engine.get_opening_question()
389
399
  console.print(f"\n[bold yellow]?[/] {opening}\n")
390
400
 
391
- user_answer = console.input("[bold green]> [/]")
401
+ user_answer = await multiline_prompt_async("Your response")
392
402
 
393
403
  if not user_answer.strip():
394
404
  print_error("No response provided. Exiting.")
395
405
  raise typer.Exit(code=1)
396
406
 
407
+ print_info("Starting interview...")
397
408
  state_result = await engine.ask_opening_and_start(
398
409
  user_response=user_answer,
399
410
  brownfield_repos=brownfield_repos if brownfield_repos else None,
@@ -413,6 +424,7 @@ async def _run_pm_interview(
413
424
  if state.rounds and state.rounds[-1].user_response is None:
414
425
  question = state.rounds[-1].question
415
426
  else:
427
+ print_info("Generating next question...")
416
428
  q_result = await engine.ask_next_question(state)
417
429
  if q_result.is_err:
418
430
  print_error(f"Question generation failed: {q_result.error}")
@@ -444,7 +456,7 @@ async def _run_pm_interview(
444
456
  break
445
457
  _save_cli_pm_meta(state.interview_id, engine)
446
458
 
447
- user_response = console.input("[bold green]> [/]")
459
+ user_response = await multiline_prompt_async("Your response")
448
460
 
449
461
  # Allow early exit
450
462
  if user_response.strip().lower() in ("done", "exit", "quit", "/done"):
@@ -456,6 +468,8 @@ async def _run_pm_interview(
456
468
  complete_result = await engine.complete_interview(state)
457
469
  if isinstance(complete_result, Result) and complete_result.is_err:
458
470
  print_error(f"Failed to complete interview: {complete_result.error}")
471
+ elif isinstance(complete_result, Result):
472
+ state = complete_result.value
459
473
  save_result = await engine.save_state(state)
460
474
  if isinstance(save_result, Result) and save_result.is_err:
461
475
  print_error(f"Failed to save completed state: {save_result.error}")
@@ -471,6 +485,8 @@ async def _run_pm_interview(
471
485
  if isinstance(record_result, Result) and record_result.is_err:
472
486
  print_error(f"Failed to record response: {record_result.error}")
473
487
  break
488
+ if isinstance(record_result, Result):
489
+ state = record_result.value
474
490
  save_result = await engine.save_state(state)
475
491
  if isinstance(save_result, Result) and save_result.is_err:
476
492
  print_error(f"Failed to save state: {save_result.error}")
@@ -0,0 +1,38 @@
1
+ """Prompt helpers for interactive CLI input."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from prompt_toolkit import PromptSession
6
+ from prompt_toolkit.key_binding import KeyBindings, KeyPressEvent
7
+ from prompt_toolkit.patch_stdout import patch_stdout
8
+
9
+ from ouroboros.cli.formatters import console
10
+
11
+
12
+ async def multiline_prompt_async(prompt_text: str) -> str:
13
+ """Get multiline-safe input while allowing logs above the active prompt."""
14
+ bindings = KeyBindings()
15
+
16
+ @bindings.add("c-j")
17
+ def insert_newline(event: KeyPressEvent) -> None:
18
+ event.current_buffer.insert_text("\n")
19
+
20
+ @bindings.add("c-m")
21
+ def submit(event: KeyPressEvent) -> None:
22
+ event.current_buffer.validate_and_handle()
23
+
24
+ console.print(f"[bold green]{prompt_text}[/] [dim](Enter: submit, Ctrl+J: newline)[/]")
25
+
26
+ session: PromptSession[str] = PromptSession(
27
+ message="> ",
28
+ multiline=True,
29
+ prompt_continuation=" ",
30
+ key_bindings=bindings,
31
+ )
32
+
33
+ # prompt_toolkit proxies both stdout and stderr above the prompt.
34
+ with patch_stdout(raw=True):
35
+ return await session.prompt_async()
36
+
37
+
38
+ __all__ = ["multiline_prompt_async"]
@@ -0,0 +1,45 @@
1
+ """Tests for interactive prompt helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from unittest.mock import AsyncMock, MagicMock, patch
7
+
8
+ import pytest
9
+
10
+ from ouroboros.cli.formatters.prompting import multiline_prompt_async
11
+
12
+
13
+ @pytest.mark.asyncio
14
+ async def test_multiline_prompt_async_patches_stdout_and_stderr() -> None:
15
+ """The shared prompt helper should proxy both stdout and stderr during input."""
16
+ session = MagicMock()
17
+ session.prompt_async = AsyncMock()
18
+
19
+ async def fake_prompt_async() -> str:
20
+ assert sys.stdout is not sys.__stdout__
21
+ assert sys.stderr is not sys.__stderr__
22
+ return "line 1\nline 2"
23
+
24
+ session.prompt_async.side_effect = fake_prompt_async
25
+
26
+ with (
27
+ patch(
28
+ "ouroboros.cli.formatters.prompting.PromptSession", return_value=session
29
+ ) as mock_session,
30
+ patch("ouroboros.cli.formatters.prompting.console.print"),
31
+ ):
32
+ result = await multiline_prompt_async("Prompt here")
33
+
34
+ assert result == "line 1\nline 2"
35
+ session.prompt_async.assert_awaited_once()
36
+
37
+ kwargs = mock_session.call_args.kwargs
38
+ assert kwargs["message"] == "> "
39
+ assert kwargs["multiline"] is True
40
+ assert kwargs["prompt_continuation"] == " "
41
+
42
+ key_bindings = kwargs["key_bindings"]
43
+ bound_keys = {tuple(binding.keys) for binding in key_bindings.bindings}
44
+ assert ("c-j",) in bound_keys
45
+ assert ("c-m",) in bound_keys
@@ -0,0 +1,39 @@
1
+ """Tests for the PM CLI command."""
2
+
3
+ from unittest.mock import patch
4
+
5
+ from typer.testing import CliRunner
6
+
7
+ from ouroboros.cli.main import app
8
+
9
+ runner = CliRunner()
10
+
11
+
12
+ @patch("ouroboros.cli.commands.pm._run_pm_interview")
13
+ @patch("ouroboros.cli.commands.pm.get_clarification_model", return_value="default")
14
+ def test_pm_uses_configured_clarification_model_when_option_omitted(
15
+ mock_get_clarification_model, mock_run_pm_interview
16
+ ) -> None:
17
+ """The bare `pm` command should resolve its model from config."""
18
+ result = runner.invoke(app, ["pm"], input="n\n")
19
+
20
+ assert result.exit_code == 0
21
+ mock_get_clarification_model.assert_called_once_with()
22
+ mock_run_pm_interview.assert_called_once()
23
+ assert mock_run_pm_interview.call_args.kwargs["model"] == "default"
24
+ assert "Model:" in result.output
25
+ assert "default" in result.output
26
+
27
+
28
+ @patch("ouroboros.cli.commands.pm._run_pm_interview")
29
+ @patch("ouroboros.cli.commands.pm.get_clarification_model")
30
+ def test_pm_preserves_explicit_model_override(
31
+ mock_get_clarification_model, mock_run_pm_interview
32
+ ) -> None:
33
+ """An explicit --model value should bypass config lookup."""
34
+ result = runner.invoke(app, ["pm", "--model", "openai/gpt-5.2"], input="n\n")
35
+
36
+ assert result.exit_code == 0
37
+ mock_get_clarification_model.assert_not_called()
38
+ mock_run_pm_interview.assert_called_once()
39
+ assert mock_run_pm_interview.call_args.kwargs["model"] == "openai/gpt-5.2"
@@ -0,0 +1,212 @@
1
+ """Unit tests for interactive PM prompt behavior."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from types import SimpleNamespace
7
+ from unittest.mock import AsyncMock, MagicMock, patch
8
+
9
+ import pytest
10
+ import typer
11
+
12
+ from ouroboros.bigbang.interview import InterviewRound
13
+ from ouroboros.cli.commands.pm import _run_pm_interview, pm_command
14
+ from ouroboros.core.types import Result
15
+
16
+
17
+ def _build_ctx() -> MagicMock:
18
+ """Build a Typer context mock for direct callback testing."""
19
+ ctx = MagicMock()
20
+ ctx.invoked_subcommand = None
21
+ return ctx
22
+
23
+
24
+ def _build_state(*, pending_question: str | None = None) -> SimpleNamespace:
25
+ """Create the minimal interview state shape used by the PM CLI."""
26
+ rounds = []
27
+ if pending_question is not None:
28
+ rounds.append(
29
+ InterviewRound(
30
+ round_number=1,
31
+ question=pending_question,
32
+ user_response=None,
33
+ )
34
+ )
35
+
36
+ return SimpleNamespace(
37
+ is_complete=False,
38
+ rounds=rounds,
39
+ current_round_number=1,
40
+ interview_id="interview_123",
41
+ mark_updated=MagicMock(),
42
+ )
43
+
44
+
45
+ def test_pm_command_exits_cleanly_on_keyboard_interrupt() -> None:
46
+ """The PM command should surface Ctrl+C as a normal CLI exit."""
47
+
48
+ def fake_run(coro: object) -> None:
49
+ coro.close() # type: ignore[union-attr]
50
+ raise KeyboardInterrupt
51
+
52
+ with patch("ouroboros.cli.commands.pm.asyncio.run", side_effect=fake_run):
53
+ with pytest.raises(typer.Exit) as exc_info:
54
+ pm_command(_build_ctx(), model="test-model", debug=False)
55
+
56
+ assert exc_info.value.exit_code == 0
57
+
58
+
59
+ def test_pm_command_enables_debug_logging_when_requested() -> None:
60
+ """The PM debug flag should enable verbose logging for the session."""
61
+
62
+ def fake_run(coro: object) -> None:
63
+ coro.close() # type: ignore[union-attr]
64
+
65
+ with (
66
+ patch("ouroboros.cli.commands.pm.asyncio.run", side_effect=fake_run),
67
+ patch("ouroboros.cli.commands.pm.configure_logging") as mock_configure,
68
+ patch("ouroboros.cli.commands.pm.print_info") as mock_print_info,
69
+ ):
70
+ pm_command(_build_ctx(), model="test-model", debug=True)
71
+
72
+ mock_configure.assert_called_once()
73
+ config = mock_configure.call_args.args[0]
74
+ assert config.log_level == "DEBUG"
75
+ messages = [call.args[0] for call in mock_print_info.call_args_list]
76
+ assert "Debug mode enabled - showing verbose logs" in messages
77
+
78
+
79
+ @pytest.mark.asyncio
80
+ async def test_run_pm_interview_new_session_uses_multiline_prompt_and_shows_progress(
81
+ tmp_path: Path,
82
+ ) -> None:
83
+ """New PM sessions should use the multiline prompt for both answers."""
84
+ initial_state = _build_state()
85
+ recorded_state = _build_state()
86
+ recorded_state.is_complete = True
87
+ engine = MagicMock()
88
+ engine.get_opening_question.return_value = "What do you want to build?"
89
+ engine.ask_opening_and_start = AsyncMock(return_value=Result.ok(initial_state))
90
+ engine.ask_next_question = AsyncMock(return_value=Result.ok("What is the first workflow?"))
91
+ engine.save_state = AsyncMock(return_value=Result.ok(tmp_path / "state.json"))
92
+ engine.record_response = AsyncMock(return_value=Result.ok(recorded_state))
93
+ engine.complete_interview = AsyncMock()
94
+ engine.format_decide_later_summary.return_value = ""
95
+
96
+ with (
97
+ patch.object(Path, "home", return_value=tmp_path),
98
+ patch("ouroboros.providers.litellm_adapter.LiteLLMAdapter", return_value=object()),
99
+ patch("ouroboros.bigbang.pm_interview.PMInterviewEngine.create", return_value=engine),
100
+ patch("ouroboros.cli.commands.pm._check_existing_pm_seeds", return_value=True),
101
+ patch("ouroboros.cli.commands.pm._load_brownfield_from_db", return_value=[]),
102
+ patch("ouroboros.cli.commands.pm._select_repos", return_value=[]),
103
+ patch("ouroboros.cli.commands.pm._save_cli_pm_meta"),
104
+ patch(
105
+ "ouroboros.cli.commands.pm.multiline_prompt_async",
106
+ side_effect=["Initial context", "Actual answer"],
107
+ ) as mock_prompt,
108
+ patch("ouroboros.cli.commands.pm.print_info") as mock_print_info,
109
+ patch("ouroboros.cli.commands.pm.print_success"),
110
+ ):
111
+ await _run_pm_interview(resume_id=None, model="test-model", debug=False)
112
+
113
+ engine.ask_opening_and_start.assert_awaited_once()
114
+ engine.ask_next_question.assert_awaited_once_with(initial_state)
115
+ assert mock_prompt.await_count == 2
116
+ engine.record_response.assert_awaited_once_with(
117
+ initial_state,
118
+ "Actual answer",
119
+ "What is the first workflow?",
120
+ )
121
+ engine.complete_interview.assert_not_called()
122
+ assert engine.save_state.await_args_list[-1].args[0] is recorded_state
123
+
124
+ messages = [call.args[0] for call in mock_print_info.call_args_list]
125
+ assert "Starting interview..." in messages
126
+ assert "Generating next question..." in messages
127
+ assert messages.index("Starting interview...") < messages.index("Generating next question...")
128
+
129
+
130
+ @pytest.mark.asyncio
131
+ async def test_run_pm_interview_resume_with_pending_question_skips_generation_message(
132
+ tmp_path: Path,
133
+ ) -> None:
134
+ """Resume should reuse the saved pending question instead of generating a new one."""
135
+ state = _build_state(pending_question="Saved question?")
136
+ completed_state = _build_state()
137
+ completed_state.is_complete = True
138
+ engine = MagicMock()
139
+ engine.load_state = AsyncMock(return_value=Result.ok(state))
140
+ engine.ask_next_question = AsyncMock()
141
+ engine.save_state = AsyncMock(return_value=Result.ok(tmp_path / "state.json"))
142
+ engine.complete_interview = AsyncMock(return_value=Result.ok(completed_state))
143
+ engine.format_decide_later_summary.return_value = ""
144
+ engine._install_pm_steering = MagicMock()
145
+
146
+ with (
147
+ patch.object(Path, "home", return_value=tmp_path),
148
+ patch("ouroboros.providers.litellm_adapter.LiteLLMAdapter", return_value=object()),
149
+ patch("ouroboros.bigbang.pm_interview.PMInterviewEngine.create", return_value=engine),
150
+ patch("ouroboros.cli.commands.pm._save_cli_pm_meta"),
151
+ patch(
152
+ "ouroboros.cli.commands.pm.multiline_prompt_async", return_value="done"
153
+ ) as mock_prompt,
154
+ patch("ouroboros.cli.commands.pm.print_info") as mock_print_info,
155
+ patch("ouroboros.cli.commands.pm.print_success"),
156
+ ):
157
+ await _run_pm_interview(resume_id="resume_123", model="test-model", debug=False)
158
+
159
+ engine.ask_next_question.assert_not_awaited()
160
+ engine._install_pm_steering.assert_called_once()
161
+ mock_prompt.assert_awaited_once()
162
+ engine.complete_interview.assert_awaited_once_with(state)
163
+ assert engine.save_state.await_args_list[-1].args[0] is completed_state
164
+
165
+ messages = [call.args[0] for call in mock_print_info.call_args_list]
166
+ assert "Generating next question..." not in messages
167
+
168
+
169
+ @pytest.mark.asyncio
170
+ async def test_run_pm_interview_preserves_pending_question_across_interrupt_and_resume(
171
+ tmp_path: Path,
172
+ ) -> None:
173
+ """A saved pending question should be re-displayed after an interrupted session."""
174
+ interrupted_state = _build_state()
175
+ resumed_state = _build_state(pending_question="What is the first workflow?")
176
+ engine = MagicMock()
177
+ engine.get_opening_question.return_value = "What do you want to build?"
178
+ engine.ask_opening_and_start = AsyncMock(return_value=Result.ok(interrupted_state))
179
+ engine.ask_next_question = AsyncMock(return_value=Result.ok("What is the first workflow?"))
180
+ engine.save_state = AsyncMock(return_value=Result.ok(tmp_path / "state.json"))
181
+ engine.load_state = AsyncMock(return_value=Result.ok(resumed_state))
182
+ engine.complete_interview = AsyncMock(
183
+ return_value=Result.ok(SimpleNamespace(**{**resumed_state.__dict__, "is_complete": True}))
184
+ )
185
+ engine.format_decide_later_summary.return_value = ""
186
+ engine._install_pm_steering = MagicMock()
187
+
188
+ with (
189
+ patch.object(Path, "home", return_value=tmp_path),
190
+ patch("ouroboros.providers.litellm_adapter.LiteLLMAdapter", return_value=object()),
191
+ patch("ouroboros.bigbang.pm_interview.PMInterviewEngine.create", return_value=engine),
192
+ patch("ouroboros.cli.commands.pm._check_existing_pm_seeds", return_value=True),
193
+ patch("ouroboros.cli.commands.pm._load_brownfield_from_db", return_value=[]),
194
+ patch("ouroboros.cli.commands.pm._select_repos", return_value=[]),
195
+ patch("ouroboros.cli.commands.pm._save_cli_pm_meta"),
196
+ patch(
197
+ "ouroboros.cli.commands.pm.multiline_prompt_async",
198
+ side_effect=["Initial context", KeyboardInterrupt, "done"],
199
+ ),
200
+ patch("ouroboros.cli.commands.pm.print_success"),
201
+ ):
202
+ with pytest.raises(KeyboardInterrupt):
203
+ await _run_pm_interview(resume_id=None, model="test-model", debug=False)
204
+
205
+ saved_question_state = engine.save_state.await_args_list[0].args[0]
206
+ assert saved_question_state.rounds[-1].question == "What is the first workflow?"
207
+ assert saved_question_state.rounds[-1].user_response is None
208
+
209
+ await _run_pm_interview(resume_id="resume_123", model="test-model", debug=False)
210
+
211
+ engine.ask_next_question.assert_awaited_once_with(interrupted_state)
212
+ engine.load_state.assert_awaited_once_with("resume_123")