rpr-cli 0.3.11__tar.gz → 0.3.12__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 (235) hide show
  1. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/PKG-INFO +1 -1
  2. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/Cargo.lock +1 -1
  3. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/Cargo.toml +1 -1
  4. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/graph.rs +8 -15
  5. rpr_cli-0.3.12/rpr-parser/src/models/dtos/mod.rs +1 -0
  6. rpr_cli-0.3.12/rpr-parser/src/models/mod.rs +2 -0
  7. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/parse.rs +11 -6
  8. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/resolve.rs +8 -1
  9. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/walker.rs +11 -2
  10. rpr_cli-0.3.12/src/rpr/__init__.py +1 -0
  11. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/tools/readonly.py +2 -2
  12. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/chat_service.py +22 -1
  13. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/checks/packages.py +4 -4
  14. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/checks/workspace.py +4 -4
  15. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/add.py +4 -4
  16. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/generate/domain.py +1 -1
  17. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/generate/web.py +1 -1
  18. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/init.py +2 -2
  19. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/rename.py +1 -1
  20. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/version.py +9 -9
  21. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/context.py +2 -2
  22. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/generators/base.py +6 -3
  23. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/graph.py +3 -3
  24. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/package_updates.py +3 -3
  25. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/project_rename.py +21 -7
  26. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/ui/theme.py +3 -2
  27. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/workspace.py +6 -6
  28. rpr_cli-0.3.11/rpr-parser/src/models/dtos/mod.rs +0 -0
  29. rpr_cli-0.3.11/rpr-parser/src/models/mod.rs +0 -2
  30. rpr_cli-0.3.11/src/rpr/__init__.py +0 -1
  31. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/LICENSE +0 -0
  32. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/README.md +0 -0
  33. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/pyproject.toml +0 -0
  34. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/config/container.rs +0 -0
  35. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/config/mod.rs +0 -0
  36. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/config/settings.rs +0 -0
  37. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/lib.rs +1 -1
  38. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/models/entities/mod.rs +0 -0
  39. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/models/entities/users.rs +0 -0
  40. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/rename.rs +0 -0
  41. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/repos/base.rs +0 -0
  42. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/repos/mod.rs +0 -0
  43. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/rpr-parser/src/repos/users.rs +0 -0
  44. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/_native.pyi +0 -0
  45. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/__init__.py +0 -0
  46. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/approval.py +0 -0
  47. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/bootstrap.py +0 -0
  48. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/client.py +0 -0
  49. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/control.py +0 -0
  50. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/mock.py +0 -0
  51. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/runtime.py +0 -0
  52. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/session.py +0 -0
  53. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/tools/__init__.py +0 -0
  54. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/tools/base.py +0 -0
  55. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/tools/mutating.py +0 -0
  56. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/agent/tools/registry.py +0 -0
  57. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/__init__.py +0 -0
  58. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/catalog.py +0 -0
  59. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/checks.py +0 -0
  60. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/cli_adapter.py +0 -0
  61. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/completer.py +0 -0
  62. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/conversation_service.py +0 -0
  63. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/prompt_service.py +0 -0
  64. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/selector.py +0 -0
  65. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/application/shell.py +0 -0
  66. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/checks/__init__.py +0 -0
  67. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/checks/base.py +0 -0
  68. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/checks/instructions.py +0 -0
  69. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/cli.py +0 -0
  70. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/__init__.py +0 -0
  71. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/chat.py +0 -0
  72. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/check.py +0 -0
  73. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/generate/__init__.py +0 -0
  74. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/generate/api.py +0 -0
  75. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/generate/engine.py +0 -0
  76. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/generate/storybook.py +0 -0
  77. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/generate/ui.py +0 -0
  78. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/map.py +0 -0
  79. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/refresh.py +0 -0
  80. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/settings.py +0 -0
  81. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/sync.py +0 -0
  82. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/commands/update.py +0 -0
  83. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/dependencies.py +0 -0
  84. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/dependency_manifest_data.py +0 -0
  85. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/generators/__init__.py +0 -0
  86. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/generators/claude.py +0 -0
  87. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/generators/codex.py +0 -0
  88. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/generators/copilot.py +0 -0
  89. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/generators/cursor.py +0 -0
  90. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/generators/gemini.py +0 -0
  91. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/generators/github.py +0 -0
  92. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/manifest_refresh.py +0 -0
  93. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/__init__.py +0 -0
  94. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/architecture.py +0 -0
  95. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/chains.py +0 -0
  96. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/classifier.py +0 -0
  97. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/coverage.py +0 -0
  98. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/dependencies.py +0 -0
  99. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/extractor.py +0 -0
  100. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/output.py +0 -0
  101. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/responsibility.py +0 -0
  102. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/topology.py +0 -0
  103. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/map/walker.py +0 -0
  104. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/domain/base_entity.md +0 -0
  105. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/domain/base_repo.md +0 -0
  106. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/domain/container.md +0 -0
  107. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/domain/settings.md +0 -0
  108. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/all.instructions.md +0 -0
  109. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/api.instructions.md +0 -0
  110. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/domain.instructions.md +0 -0
  111. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/frontend.instructions.md +0 -0
  112. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/notebook.instructions.md +0 -0
  113. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/rust-engine.instructions.md +0 -0
  114. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +0 -0
  115. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/stories-tracking.instructions.md +0 -0
  116. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +0 -0
  117. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -0
  118. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/BACKEND_FLOW.md +0 -0
  119. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/README.md +0 -0
  120. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/content.ts +0 -0
  121. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/httpChatStreamClient.spec.ts +0 -0
  122. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/httpChatStreamClient.ts +0 -0
  123. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/index.ts +0 -0
  124. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/types.ts +0 -0
  125. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.spec.tsx +0 -0
  126. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.tsx +0 -0
  127. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/__screenshots__/ChatComposer.spec.tsx/ChatComposer-renders-custom-action-buttons-beside-the-attachment-control-1.png +0 -0
  128. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.spec.ts +0 -0
  129. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.ts +0 -0
  130. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/index.ts +0 -0
  131. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatComposerMentionTokens.tsx +0 -0
  132. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatSuggestionsPopover.tsx +0 -0
  133. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/LocalFileSuggestionAction.tsx +0 -0
  134. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/index.ts +0 -0
  135. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.spec.ts +0 -0
  136. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.ts +0 -0
  137. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.spec.ts +0 -0
  138. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.ts +0 -0
  139. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/types.ts +0 -0
  140. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/useChatSuggestions.ts +0 -0
  141. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/types.ts +0 -0
  142. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/useChatComposer.ts +0 -0
  143. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.spec.tsx +0 -0
  144. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.ts +0 -0
  145. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperience.spec.tsx +0 -0
  146. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperience.styles.tsx +0 -0
  147. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperience.tsx +0 -0
  148. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceComposer.styles.tsx +0 -0
  149. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceComposer.tsx +0 -0
  150. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceHeader.styles.tsx +0 -0
  151. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceHeader.tsx +0 -0
  152. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ThreadHistory.styles.tsx +0 -0
  153. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ThreadHistory.tsx +0 -0
  154. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/chatStorage.spec.ts +0 -0
  155. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/chatStorage.ts +0 -0
  156. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/index.ts +0 -0
  157. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/types.ts +0 -0
  158. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/useChatExperience.spec.tsx +0 -0
  159. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/useChatExperience.ts +0 -0
  160. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/index.ts +0 -0
  161. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/testing/createMockChatStreamClient.ts +0 -0
  162. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/testing/createMockSuggestionProvider.ts +0 -0
  163. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/testing/index.ts +0 -0
  164. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessage.tsx +0 -0
  165. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageActions.tsx +0 -0
  166. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.spec.tsx +0 -0
  167. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.tsx +0 -0
  168. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.spec.tsx +0 -0
  169. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.tsx +0 -0
  170. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/README.md +0 -0
  171. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/contentFormat.ts +0 -0
  172. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/index.ts +0 -0
  173. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/streaming.ts +0 -0
  174. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/types.ts +0 -0
  175. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.spec.tsx +0 -0
  176. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.tsx +0 -0
  177. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.spec.tsx +0 -0
  178. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.tsx +0 -0
  179. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/index.ts +0 -0
  180. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
  181. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
  182. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/sticky-navigation.spec.md +0 -0
  183. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/vitest-browser-config.md +0 -0
  184. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/api/routes/chat_routes.py +0 -0
  185. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/api/tests/test_chat.py +0 -0
  186. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/models/dtos/chat_dtos.py +0 -0
  187. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/models/dtos/conversation_history_dtos.py +0 -0
  188. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/models/entities/conversation_history.py +0 -0
  189. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/repos/conversation_history.py +0 -0
  190. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/agent_session_codec.py +0 -0
  191. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/chat_service.py +0 -0
  192. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/conversation_history_service.py +0 -0
  193. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/conversation_operations.py +0 -0
  194. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/history_codec.py +0 -0
  195. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/in_memory_history_store.py +0 -0
  196. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/postgres_history_store.py +0 -0
  197. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/protocols/conversation_history_store.py +0 -0
  198. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/protocols/conversation_runtime.py +0 -0
  199. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/protocols/llm_provider.py +0 -0
  200. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_chat_dtos.py +0 -0
  201. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_chat_service.py +0 -0
  202. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_history_codec.py +0 -0
  203. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_history_projection.py +0 -0
  204. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_persistence_config.py +0 -0
  205. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_postgres_history_store.py +0 -0
  206. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/models/dtos/__init__.py +0 -0
  207. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/models/dtos/vllm_model_dtos.py +0 -0
  208. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/VLLM_SETUP.md +0 -0
  209. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/__init__.py +0 -0
  210. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/model_catalog.py +0 -0
  211. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/vllm_agent_factory.py +0 -0
  212. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/vllm_agent_factory_protocol.py +0 -0
  213. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/vllm_inference_coordinator.py +0 -0
  214. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/runtimes/__init__.py +0 -0
  215. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/runtimes/agents_sdk.py +0 -0
  216. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/runtimes/agents_sdk_message_mapping.py +0 -0
  217. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/tests/test_agents_sdk_runtime.py +0 -0
  218. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/tests/test_vllm_model_catalog.py +0 -0
  219. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/tests/test_vllm_provider.py +0 -0
  220. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/camel_case_model.md +0 -0
  221. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/domain_container.md +0 -0
  222. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/domain_settings.md +0 -0
  223. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
  224. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/encrypted_column.md +0 -0
  225. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/logging.md +0 -0
  226. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
  227. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
  228. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/test_encrypted_column.md +0 -0
  229. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/templates/__init__.py +0 -0
  230. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/templates/registry.py +0 -0
  231. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/ui/__init__.py +0 -0
  232. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/ui/console.py +0 -0
  233. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/ui/markdown.py +0 -0
  234. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/ui/prompt_session.py +0 -0
  235. {rpr_cli-0.3.11 → rpr_cli-0.3.12}/src/rpr/ui/renderers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rpr-cli
3
- Version: 0.3.11
3
+ Version: 0.3.12
4
4
  Requires-Dist: typer>=0.24.1,<0.26
5
5
  Requires-Dist: jinja2>=3.1.5
6
6
  Requires-Dist: pyyaml>=6.0.2
@@ -1981,7 +1981,7 @@ dependencies = [
1981
1981
 
1982
1982
  [[package]]
1983
1983
  name = "rpr-parser"
1984
- version = "0.3.11"
1984
+ version = "0.3.12"
1985
1985
  dependencies = [
1986
1986
  "dirs",
1987
1987
  "dotenvy",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rpr-parser"
3
- version = "0.3.11"
3
+ version = "0.3.12"
4
4
  edition = "2021"
5
5
 
6
6
  [lib]
@@ -127,14 +127,9 @@ fn dfs_iterative<'a>(
127
127
  match color.get(neighbor).copied().unwrap_or(0) {
128
128
  1 => {
129
129
  // Back edge — found a cycle. Trace path back to neighbor.
130
- let cycle_start = path
131
- .iter()
132
- .position(|&n| n == neighbor)
133
- .unwrap_or(0);
134
- let mut cycle: Vec<String> = path[cycle_start..]
135
- .iter()
136
- .map(|s| s.to_string())
137
- .collect();
130
+ let cycle_start = path.iter().position(|&n| n == neighbor).unwrap_or(0);
131
+ let mut cycle: Vec<String> =
132
+ path[cycle_start..].iter().map(|s| s.to_string()).collect();
138
133
  cycle.push(neighbor.to_string()); // close the cycle
139
134
  cycles.push(cycle);
140
135
  }
@@ -163,12 +158,7 @@ mod tests {
163
158
  fn edges(pairs: &[(&str, &[&str])]) -> HashMap<String, Vec<String>> {
164
159
  pairs
165
160
  .iter()
166
- .map(|(k, vs)| {
167
- (
168
- k.to_string(),
169
- vs.iter().map(|s| s.to_string()).collect(),
170
- )
171
- })
161
+ .map(|(k, vs)| (k.to_string(), vs.iter().map(|s| s.to_string()).collect()))
172
162
  .collect()
173
163
  }
174
164
 
@@ -235,7 +225,10 @@ mod tests {
235
225
  // Simulate what build() does for dedup
236
226
  let deps = vec!["B".to_string(), "B".to_string(), "C".to_string()];
237
227
  let mut seen: HashSet<String> = HashSet::new();
238
- let deduped: Vec<String> = deps.into_iter().filter(|d| seen.insert(d.clone())).collect();
228
+ let deduped: Vec<String> = deps
229
+ .into_iter()
230
+ .filter(|d| seen.insert(d.clone()))
231
+ .collect();
239
232
  assert_eq!(deduped.len(), 2);
240
233
  assert!(deduped.contains(&"B".to_string()));
241
234
  assert!(deduped.contains(&"C".to_string()));
@@ -0,0 +1,2 @@
1
+ pub mod dtos;
2
+ pub mod entities;
@@ -166,7 +166,10 @@ fn extract_js_ts_imports(source: &[u8], parser: &mut Parser) -> Vec<String> {
166
166
  let mut cursor = node.walk();
167
167
  for child in node.children(&mut cursor) {
168
168
  if child.kind() == "string" {
169
- let raw = node_text(child, source).trim_matches('"').trim_matches('\'').to_string();
169
+ let raw = node_text(child, source)
170
+ .trim_matches('"')
171
+ .trim_matches('\'')
172
+ .to_string();
170
173
  if !raw.is_empty() {
171
174
  imports.push(raw);
172
175
  }
@@ -257,7 +260,9 @@ fn parse_rust(source: &[u8]) -> Vec<String> {
257
260
  // Only `mod foo;` (without a body block), not `mod foo { ... }`
258
261
  let has_body = {
259
262
  let mut cursor = node.walk();
260
- let result = node.children(&mut cursor).any(|c| c.kind() == "declaration_list");
263
+ let result = node
264
+ .children(&mut cursor)
265
+ .any(|c| c.kind() == "declaration_list");
261
266
  result
262
267
  };
263
268
  if !has_body {
@@ -317,9 +322,7 @@ fn parse_cpp(source: &[u8]) -> Vec<String> {
317
322
  match child.kind() {
318
323
  "string_literal" => {
319
324
  // Quoted include — keep it (strip surrounding quotes)
320
- let raw = node_text(child, source)
321
- .trim_matches('"')
322
- .to_string();
325
+ let raw = node_text(child, source).trim_matches('"').to_string();
323
326
  if !raw.is_empty() {
324
327
  imports.push(raw);
325
328
  }
@@ -475,7 +478,9 @@ mod tests {
475
478
  let f = rs_file();
476
479
  let src = b"use crate::map::walker;";
477
480
  let result = parse_imports(&f, src);
478
- assert!(result.iter().any(|s| s.contains("map") && s.contains("walker")));
481
+ assert!(result
482
+ .iter()
483
+ .any(|s| s.contains("map") && s.contains("walker")));
479
484
  }
480
485
 
481
486
  #[test]
@@ -3,7 +3,14 @@ use std::collections::HashMap;
3
3
  use std::path::{Path, PathBuf};
4
4
 
5
5
  const TS_JS_EXTENSIONS: &[&str] = &["ts", "tsx", "js", "jsx", "mjs", "cjs"];
6
- const INDEX_NAMES: &[&str] = &["index.ts", "index.tsx", "index.js", "index.jsx", "index.mjs", "index.cjs"];
6
+ const INDEX_NAMES: &[&str] = &[
7
+ "index.ts",
8
+ "index.tsx",
9
+ "index.js",
10
+ "index.jsx",
11
+ "index.mjs",
12
+ "index.cjs",
13
+ ];
7
14
 
8
15
  pub fn resolve_imports(
9
16
  file: &SourceFile,
@@ -2,8 +2,17 @@ use ignore::WalkBuilder;
2
2
  use std::path::{Path, PathBuf};
3
3
 
4
4
  const IGNORED_DIRS: &[&str] = &[
5
- ".venv", "venv", ".env", "node_modules", "__pycache__",
6
- "dist", "build", ".nx", "target", ".git", "vendor",
5
+ ".venv",
6
+ "venv",
7
+ ".env",
8
+ "node_modules",
9
+ "__pycache__",
10
+ "dist",
11
+ "build",
12
+ ".nx",
13
+ "target",
14
+ ".git",
15
+ "vendor",
7
16
  ];
8
17
 
9
18
  #[derive(Debug, Clone, PartialEq)]
@@ -0,0 +1 @@
1
+ __version__ = "0.3.12"
@@ -31,7 +31,7 @@ class ReadFileTool(AgentTool):
31
31
  path = resolve_project_path(ctx.project_dir, arguments.get("path"))
32
32
  start_line = int(arguments.get("start_line", 1))
33
33
  end_line = arguments.get("end_line")
34
- content = path.read_text()
34
+ content = path.read_text(encoding="utf-8")
35
35
  lines = content.splitlines()
36
36
  if end_line is None:
37
37
  end_line = len(lines)
@@ -122,7 +122,7 @@ class SearchTextTool(AgentTool):
122
122
  )
123
123
  path = current_root / file_name
124
124
  try:
125
- content = path.read_text()
125
+ content = path.read_text(encoding="utf-8")
126
126
  except (OSError, UnicodeDecodeError):
127
127
  continue
128
128
 
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
+ import sys
4
5
  from collections import deque
5
6
  from contextlib import suppress
6
7
  from dataclasses import dataclass
@@ -9,7 +10,9 @@ from typing import ClassVar
9
10
 
10
11
  from prompt_toolkit import print_formatted_text
11
12
  from prompt_toolkit.application.current import get_app_session
13
+ from prompt_toolkit.data_structures import Size
12
14
  from prompt_toolkit.formatted_text import FormattedText
15
+ from prompt_toolkit.output.vt100 import Vt100_Output
13
16
 
14
17
  from rpr.agent.approval import ApprovalDecision, ApprovalMode
15
18
  from rpr.agent.bootstrap import build_chat_runtime_bundle
@@ -47,6 +50,24 @@ type AgentClientFactory = Callable[[str | None, str | None], AgentClient]
47
50
  type ContextFactory = Callable[[], RunContext]
48
51
 
49
52
 
53
+ def _terminal_output():
54
+ """Return prompt_toolkit's output, falling back to plain stdout.
55
+
56
+ On Windows prompt_toolkit raises when stdout is not a real console (piped
57
+ output, CI, redirected runs). Binding a plain VT100 writer to `sys.stdout`
58
+ keeps `rpr chat` working there; `reset()` clears it with the app session.
59
+ """
60
+ session = get_app_session()
61
+ try:
62
+ return session.output
63
+ except Exception:
64
+ output = Vt100_Output(
65
+ sys.stdout, lambda: Size(rows=24, columns=80), term="dumb"
66
+ )
67
+ session._output = output
68
+ return output
69
+
70
+
50
71
  @dataclass(slots=True)
51
72
  class AssistantStreamRenderer:
52
73
  _accumulated: str = ""
@@ -54,7 +75,7 @@ class AssistantStreamRenderer:
54
75
 
55
76
  def append(self, chunk: str) -> None:
56
77
  self._accumulated += chunk
57
- output = get_app_session().output
78
+ output = _terminal_output()
58
79
  if self._lines_printed > 0:
59
80
  output.cursor_up(self._lines_printed)
60
81
  output.erase_down()
@@ -30,7 +30,7 @@ def check_packages(project_dir: Path, variables: dict[str, str]) -> list[CheckRe
30
30
  workspace_members: set[str] = set()
31
31
  if pyproject.exists():
32
32
  try:
33
- data = tomllib.loads(pyproject.read_text())
33
+ data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
34
34
  members = (
35
35
  data.get("tool", {})
36
36
  .get("uv", {})
@@ -316,7 +316,7 @@ def _load_json(path: Path) -> dict[str, object] | None:
316
316
  if not path.exists():
317
317
  return None
318
318
  try:
319
- data = json.loads(path.read_text())
319
+ data = json.loads(path.read_text(encoding="utf-8"))
320
320
  except (OSError, json.JSONDecodeError):
321
321
  return None
322
322
  return data if isinstance(data, dict) else None
@@ -326,7 +326,7 @@ def _load_toml(path: Path) -> dict[str, object] | None:
326
326
  if not path.exists():
327
327
  return None
328
328
  try:
329
- data = tomllib.loads(path.read_text())
329
+ data = tomllib.loads(path.read_text(encoding="utf-8"))
330
330
  except (OSError, tomllib.TOMLDecodeError):
331
331
  return None
332
332
  return data if isinstance(data, dict) else None
@@ -567,7 +567,7 @@ def _check_domain_migration_scaffold(
567
567
  cwd_ok = isinstance(options, dict) and options.get("cwd") == "."
568
568
  env_ok = False
569
569
  if env_py.exists():
570
- env_content = env_py.read_text()
570
+ env_content = env_py.read_text(encoding="utf-8")
571
571
  env_ok = (
572
572
  f"from {name_underscore}_domain.config.settings import Settings"
573
573
  in env_content
@@ -18,7 +18,7 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
18
18
  nx_cloud_disabled = False
19
19
  if nx_json.exists():
20
20
  try:
21
- nx_data = json.loads(nx_json.read_text())
21
+ nx_data = json.loads(nx_json.read_text(encoding="utf-8"))
22
22
  nx_ok = True
23
23
  nx_cloud_disabled = nx_data.get("neverConnectToCloud") is True
24
24
  except (OSError, json.JSONDecodeError):
@@ -51,7 +51,7 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
51
51
  uv_ok = False
52
52
  if pyproject.exists():
53
53
  try:
54
- pyproject_data = tomllib.loads(pyproject.read_text())
54
+ pyproject_data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
55
55
  tool = pyproject_data.get("tool", {})
56
56
  uv_ok = "uv" in tool and "workspace" in tool["uv"]
57
57
  except (OSError, tomllib.TOMLDecodeError):
@@ -118,7 +118,7 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
118
118
  node_workspace_ok = False
119
119
  if package_json.exists():
120
120
  try:
121
- package_data = json.loads(package_json.read_text())
121
+ package_data = json.loads(package_json.read_text(encoding="utf-8"))
122
122
  workspaces = package_data.get("workspaces", [])
123
123
  node_workspace_ok = isinstance(workspaces, list) and {
124
124
  "apps/*",
@@ -142,7 +142,7 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
142
142
  pre_commit = project_dir / ".pre-commit-config.yaml"
143
143
  pre_commit_ok = False
144
144
  if pre_commit.exists():
145
- content = pre_commit.read_text()
145
+ content = pre_commit.read_text(encoding="utf-8")
146
146
  pre_commit_ok = all(
147
147
  needle in content
148
148
  for needle in (
@@ -277,11 +277,11 @@ def _render_template_file(
277
277
  raise typer.Exit(1)
278
278
 
279
279
  if template_file.raw:
280
- code = source_file.read_text()
280
+ code = source_file.read_text(encoding="utf-8")
281
281
  code = _interpolate_code(code, variables)
282
282
  return _apply_raw_transforms(code, template_file, variables)
283
283
 
284
- markdown = source_file.read_text()
284
+ markdown = source_file.read_text(encoding="utf-8")
285
285
  code_blocks = _extract_code_blocks(markdown, template_file.language)
286
286
 
287
287
  if not code_blocks:
@@ -363,7 +363,7 @@ def _update_root_index(
363
363
  if not index_path.exists():
364
364
  return
365
365
 
366
- existing = index_path.read_text()
366
+ existing = index_path.read_text(encoding="utf-8")
367
367
  additions = [
368
368
  f'export * from "./components/{name}";'
369
369
  for name in sorted(component_names)
@@ -421,7 +421,7 @@ def _auto_wire_python_template(
421
421
  / "main.py"
422
422
  )
423
423
  if main_path.exists():
424
- content = main_path.read_text()
424
+ content = main_path.read_text(encoding="utf-8")
425
425
  if "chat_routes" not in content:
426
426
  content = content.replace(
427
427
  "from .routes.health import router as health_router",
@@ -252,7 +252,7 @@ def _write_container(ctx: RunContext, path: Path, pkg_name_underscore: str) -> N
252
252
 
253
253
  def _extract_first_code_block(md_path: Path) -> str:
254
254
  """Return the content of the first fenced code block in a markdown file."""
255
- text = md_path.read_text()
255
+ text = md_path.read_text(encoding="utf-8")
256
256
  match = re.search(r"```(?:\w*)\n(.*?)```", text, re.DOTALL)
257
257
  if not match:
258
258
  raise ValueError(f"No fenced code block found in {md_path}")
@@ -130,7 +130,7 @@ def next_free_web_port(project_dir: Path) -> int:
130
130
  used: set[int] = set()
131
131
  for pattern in ("apps/*/vite.config.ts", "packages/node/*/vite.config.ts"):
132
132
  for config in project_dir.glob(pattern):
133
- used.update(int(port) for port in _PORT_PATTERN.findall(config.read_text()))
133
+ used.update(int(port) for port in _PORT_PATTERN.findall(config.read_text(encoding="utf-8")))
134
134
 
135
135
  port = _FIRST_WEB_PORT
136
136
  while port in used:
@@ -113,7 +113,7 @@ def _detect_uv_state(project_dir: Path) -> bool:
113
113
  if not pyproject.exists():
114
114
  return False
115
115
  try:
116
- data = tomllib.loads(pyproject.read_text())
116
+ data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
117
117
  except tomllib.TOMLDecodeError:
118
118
  return False
119
119
  tool = data.get("tool", {})
@@ -477,7 +477,7 @@ def _write_root_package_json(ctx: RunContext, project_name: str) -> None:
477
477
  existed = package_path.exists()
478
478
  if existed:
479
479
  try:
480
- package = json.loads(package_path.read_text())
480
+ package = json.loads(package_path.read_text(encoding="utf-8"))
481
481
  except json.JSONDecodeError:
482
482
  package = {}
483
483
  else:
@@ -225,7 +225,7 @@ def _workspace_has_target(root: Path, target: str) -> bool:
225
225
  continue
226
226
  path = Path(current) / filename
227
227
  try:
228
- payload = json.loads(path.read_text())
228
+ payload = json.loads(path.read_text(encoding="utf-8"))
229
229
  except (OSError, UnicodeError, json.JSONDecodeError):
230
230
  continue
231
231
  targets = payload.get("targets")
@@ -32,9 +32,9 @@ def _read_versions(root: Path) -> dict[str, str]:
32
32
  cargo_path = root / "rpr-parser/Cargo.toml"
33
33
  lock_path = root / "rpr-parser/Cargo.lock"
34
34
  try:
35
- init_text = init_path.read_text()
36
- cargo_text = cargo_path.read_text()
37
- lock_text = lock_path.read_text()
35
+ init_text = init_path.read_text(encoding="utf-8")
36
+ cargo_text = cargo_path.read_text(encoding="utf-8")
37
+ lock_text = lock_path.read_text(encoding="utf-8")
38
38
  except OSError as exc:
39
39
  raise VersionError(f"Unable to read release metadata: {exc}") from exc
40
40
 
@@ -88,9 +88,9 @@ def set_version(root: Path, new_version: str) -> tuple[str, str]:
88
88
  init_path = root / "src/rpr/__init__.py"
89
89
  cargo_path = root / "rpr-parser/Cargo.toml"
90
90
  lock_path = root / "rpr-parser/Cargo.lock"
91
- init_text = init_path.read_text()
92
- cargo_text = cargo_path.read_text()
93
- lock_text = lock_path.read_text()
91
+ init_text = init_path.read_text(encoding="utf-8")
92
+ cargo_text = cargo_path.read_text(encoding="utf-8")
93
+ lock_text = lock_path.read_text(encoding="utf-8")
94
94
  updated_init = _replace_once(
95
95
  _PYTHON_VERSION_PATTERN, init_text, new_version, "Python"
96
96
  )
@@ -101,9 +101,9 @@ def set_version(root: Path, new_version: str) -> tuple[str, str]:
101
101
  _LOCK_PACKAGE_VERSION_PATTERN, lock_text, new_version, "Cargo.lock"
102
102
  )
103
103
  if old_version != new_version:
104
- init_path.write_text(updated_init)
105
- cargo_path.write_text(updated_cargo)
106
- lock_path.write_text(updated_lock)
104
+ init_path.write_text(updated_init, encoding="utf-8")
105
+ cargo_path.write_text(updated_cargo, encoding="utf-8")
106
+ lock_path.write_text(updated_lock, encoding="utf-8")
107
107
  return old_version, new_version
108
108
 
109
109
 
@@ -198,7 +198,7 @@ class RunContext:
198
198
  return
199
199
 
200
200
  path.parent.mkdir(parents=True, exist_ok=True)
201
- path.write_text(content)
201
+ path.write_text(content, encoding="utf-8", newline="\n")
202
202
  render_file_preview(path, content, is_dry_run=False, is_update=False)
203
203
  if _should_preview_markdown(path, preview_markdown):
204
204
  _render_markdown_file_preview(
@@ -262,7 +262,7 @@ class RunContext:
262
262
  render_file_preview(path, content, is_dry_run=True, is_update=True)
263
263
  return
264
264
 
265
- path.write_text(content)
265
+ path.write_text(content, encoding="utf-8")
266
266
  render_file_preview(path, content, is_dry_run=False, is_update=True)
267
267
  if _should_preview_markdown(path, preview_markdown):
268
268
  _render_markdown_file_preview(
@@ -34,7 +34,7 @@ def load_rules(source_dir: Path) -> list[Rule]:
34
34
  if ".venv" in md_file.parts:
35
35
  continue
36
36
 
37
- text = md_file.read_text()
37
+ text = md_file.read_text(encoding="utf-8")
38
38
  rule_id = md_file.stem.replace(".instructions", "")
39
39
  frontmatter: dict = {}
40
40
  body = text
@@ -117,7 +117,7 @@ class SyncConfig:
117
117
  if not path.exists():
118
118
  return cls()
119
119
  try:
120
- data = yaml.safe_load(path.read_text()) or {}
120
+ data = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
121
121
  except yaml.YAMLError:
122
122
  data = {}
123
123
  return cls(
@@ -136,7 +136,10 @@ class SyncConfig:
136
136
  "exclude": self.exclude,
137
137
  "variables": self.variables,
138
138
  }
139
- path.write_text(yaml.dump(data, default_flow_style=False, sort_keys=False))
139
+ path.write_text(
140
+ yaml.dump(data, default_flow_style=False, sort_keys=False),
141
+ encoding="utf-8",
142
+ )
140
143
 
141
144
  def filter_rules(self, rules: list[Rule]) -> list[Rule]:
142
145
  if self.include:
@@ -41,7 +41,7 @@ def _resolve_python(
41
41
  dots = len(raw) - len(raw.lstrip("."))
42
42
  remainder = raw.lstrip(".")
43
43
 
44
- base = PurePosixPath(str(importer.rel_path.parent))
44
+ base = PurePosixPath(importer.rel_path.parent.as_posix())
45
45
  for _ in range(dots - 1):
46
46
  base = base.parent
47
47
 
@@ -136,7 +136,7 @@ def _resolve_rust(
136
136
 
137
137
  # mod declaration: bare name, no "::", resolved adjacent to importer.
138
138
  if "::" not in raw:
139
- importer_dir = str(importer.rel_path.parent)
139
+ importer_dir = importer.rel_path.parent.as_posix()
140
140
  prefix = "" if importer_dir == "." else f"{importer_dir}/"
141
141
  for probe in (f"{prefix}{raw}.rs", f"{prefix}{raw}/mod.rs"):
142
142
  if probe in known:
@@ -177,7 +177,7 @@ def _resolve_cpp(
177
177
  header = raw.strip('"')
178
178
 
179
179
  # 1. Resolve relative to the importer's directory.
180
- importer_dir = PurePosixPath(str(importer.rel_path.parent))
180
+ importer_dir = PurePosixPath(importer.rel_path.parent.as_posix())
181
181
  candidate = str((importer_dir / header).as_posix())
182
182
  if candidate.startswith("./"):
183
183
  candidate = candidate[2:]
@@ -169,7 +169,7 @@ def _plan_package_json(
169
169
  include_major: bool,
170
170
  fetch_versions: VersionFetcher,
171
171
  ) -> PackageUpdatePlan:
172
- content = path.read_text()
172
+ content = path.read_text(encoding="utf-8")
173
173
  try:
174
174
  package = json.loads(content)
175
175
  except json.JSONDecodeError as exc:
@@ -264,7 +264,7 @@ def _plan_pyproject_toml(
264
264
  include_major: bool,
265
265
  fetch_versions: VersionFetcher,
266
266
  ) -> PackageUpdatePlan:
267
- content = path.read_text()
267
+ content = path.read_text(encoding="utf-8")
268
268
  try:
269
269
  document = tomlkit.parse(content)
270
270
  except Exception as exc:
@@ -330,7 +330,7 @@ def _plan_requirements_txt(
330
330
  include_major: bool,
331
331
  fetch_versions: VersionFetcher,
332
332
  ) -> PackageUpdatePlan:
333
- lines = path.read_text().splitlines(keepends=True)
333
+ lines = path.read_text(encoding="utf-8").splitlines(keepends=True)
334
334
  updated_lines: list[str] = []
335
335
  changes: list[PackageUpdateChange] = []
336
336
  skipped: list[PackageUpdateSkipped] = []
@@ -68,6 +68,20 @@ def _native_module() -> Any:
68
68
  return native
69
69
 
70
70
 
71
+ def _native_path(value: str) -> Path:
72
+ """Convert a path reported by Rust into a normal `Path`.
73
+
74
+ `Path::canonicalize` returns verbatim paths (`\\\\?\\C:\\...`) on Windows. Python's
75
+ own paths never carry that prefix, so comparisons and `relative_to` would
76
+ fail and the prefix would leak into user-facing output.
77
+ """
78
+ if value.startswith("\\\\?\\UNC\\"):
79
+ value = "\\\\" + value[len("\\\\?\\UNC\\") :]
80
+ elif value.startswith("\\\\?\\"):
81
+ value = value[len("\\\\?\\") :]
82
+ return Path(value)
83
+
84
+
71
85
  def ensure_rename_ignore(project_dir: Path) -> bool:
72
86
  """Create the native rename scope file when it does not exist."""
73
87
  try:
@@ -91,27 +105,27 @@ def build_rename_plan(project_dir: Path, new_name: str) -> RenamePlan:
91
105
  raise ProjectRenameError(str(exc)) from exc
92
106
 
93
107
  return RenamePlan(
94
- project_dir=Path(payload["project_dir"]),
108
+ project_dir=_native_path(payload["project_dir"]),
95
109
  old_name=payload["old_name"],
96
110
  new_name=payload["new_name"],
97
111
  file_edits=tuple(
98
112
  FileEdit(
99
- path=Path(item["path"]),
100
- final_path=Path(item["final_path"]),
113
+ path=_native_path(item["path"]),
114
+ final_path=_native_path(item["final_path"]),
101
115
  replacements=item["replacements"],
102
116
  )
103
117
  for item in payload["file_edits"]
104
118
  ),
105
119
  path_moves=tuple(
106
120
  PathMove(
107
- source=Path(item["source"]),
108
- target=Path(item["target"]),
109
- final_target=Path(item["final_target"]),
121
+ source=_native_path(item["source"]),
122
+ target=_native_path(item["target"]),
123
+ final_target=_native_path(item["final_target"]),
110
124
  )
111
125
  for item in payload["path_moves"]
112
126
  ),
113
127
  skipped_paths=tuple(
114
- SkippedPath(path=Path(item["path"]), reason=item["reason"])
128
+ SkippedPath(path=_native_path(item["path"]), reason=item["reason"])
115
129
  for item in payload["skipped_paths"]
116
130
  ),
117
131
  backend=payload["backend"],
@@ -158,7 +158,7 @@ class SettingsManager:
158
158
  data = self._default_data()
159
159
  if self._config_path.exists():
160
160
  try:
161
- loaded = json.loads(self._config_path.read_text())
161
+ loaded = json.loads(self._config_path.read_text(encoding="utf-8"))
162
162
  except (json.JSONDecodeError, OSError):
163
163
  loaded = {}
164
164
  if isinstance(loaded, dict):
@@ -187,7 +187,8 @@ class SettingsManager:
187
187
  "startup_help": self._startup_help,
188
188
  },
189
189
  indent=2,
190
- )
190
+ ),
191
+ encoding="utf-8",
191
192
  )
192
193
  except OSError:
193
194
  pass
@@ -47,11 +47,11 @@ def add_workspace_member(ctx: RunContext, member: str) -> None:
47
47
  members_str = ", ".join(f'"{m}"' for m in members)
48
48
  new_members_line = f"members = [{members_str}]"
49
49
 
50
- content = pyproject_path.read_text()
50
+ content = pyproject_path.read_text(encoding="utf-8")
51
51
  content = re.sub(
52
52
  r"members\s*=\s*\[.*?\]", new_members_line, content, flags=re.DOTALL
53
53
  )
54
- pyproject_path.write_text(content)
54
+ pyproject_path.write_text(content, encoding="utf-8")
55
55
  console.print(f"[bold green]Updated:[/] Added '{member}' to workspace members")
56
56
 
57
57
 
@@ -83,7 +83,7 @@ def write_package_json(
83
83
 
84
84
  if existed:
85
85
  try:
86
- package = json.loads(path.read_text())
86
+ package = json.loads(path.read_text(encoding="utf-8"))
87
87
  except json.JSONDecodeError:
88
88
  package = {}
89
89
  else:
@@ -123,7 +123,7 @@ def ensure_npm_workspaces(ctx: RunContext, *, package_name: str | None = None) -
123
123
 
124
124
  if existed:
125
125
  try:
126
- package = json.loads(package_path.read_text())
126
+ package = json.loads(package_path.read_text(encoding="utf-8"))
127
127
  except json.JSONDecodeError:
128
128
  package = {}
129
129
  else:
@@ -227,7 +227,7 @@ def append_export(ctx: RunContext, path: Path, line: str) -> None:
227
227
  ctx.write_file(path, f"{line}\n")
228
228
  return
229
229
 
230
- existing = path.read_text().splitlines()
230
+ existing = path.read_text(encoding="utf-8").splitlines()
231
231
  if line in existing:
232
232
  return
233
233
 
@@ -241,7 +241,7 @@ def _declared_root_dependencies(project_dir: Path) -> set[str]:
241
241
  if not package_path.exists():
242
242
  return set()
243
243
  try:
244
- package = json.loads(package_path.read_text())
244
+ package = json.loads(package_path.read_text(encoding="utf-8"))
245
245
  except json.JSONDecodeError:
246
246
  return set()
247
247