rpr-cli 0.1.29__tar.gz → 0.2.0__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 (278) hide show
  1. rpr_cli-0.1.29/README.md → rpr_cli-0.2.0/PKG-INFO +24 -0
  2. rpr_cli-0.1.29/PKG-INFO → rpr_cli-0.2.0/README.md +7 -15
  3. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/pyproject.toml +2 -0
  4. rpr_cli-0.2.0/src/rpr/__init__.py +1 -0
  5. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/catalog.py +61 -0
  6. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/cli.py +8 -0
  7. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/generate/domain.py +6 -1
  8. rpr_cli-0.2.0/src/rpr/commands/update.py +222 -0
  9. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/manifest_refresh.py +50 -0
  10. rpr_cli-0.2.0/src/rpr/package_updates.py +731 -0
  11. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/instructions/domain.instructions.md +1 -1
  12. rpr_cli-0.2.0/src/rpr/scaffolds/special_files/camel_case_model.md +60 -0
  13. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/templates/registry.py +6 -0
  14. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/02-rpr-generate-domain.md +2 -2
  15. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/08-rpr-add-template.md +1 -0
  16. rpr_cli-0.2.0/stories/package-maintenance/rpr-update-packages.md +183 -0
  17. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_add.py +75 -0
  18. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_catalog.py +22 -2
  19. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_generate_domain.py +37 -0
  20. rpr_cli-0.2.0/tests/test_package_updates.py +175 -0
  21. rpr_cli-0.2.0/tests/test_update_packages.py +209 -0
  22. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/uv.lock +16 -3
  23. rpr_cli-0.1.29/src/rpr/__init__.py +0 -1
  24. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/.github/agents/story.agent.md +0 -0
  25. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/.github/workflows/publish-pypi.yml +0 -0
  26. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/.gitignore +0 -0
  27. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/CLAUDE.md +0 -0
  28. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/GEMINI.md +0 -0
  29. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/LICENSE +0 -0
  30. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/instructions/all.instructions.md +0 -0
  31. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/instructions/api.instructions.md +0 -0
  32. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/instructions/domain.instructions.md +0 -0
  33. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/instructions/frontend.instructions.md +0 -0
  34. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/instructions/rust-engine.instructions.md +0 -0
  35. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/instructions/setup-guide.instructions.md +0 -0
  36. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/instructions/tooling-setup.instructions.md +0 -0
  37. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/instructions/tooling.instructions.md +0 -0
  38. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/README.md +0 -0
  39. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/api/main.py +0 -0
  40. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/domain/base-repo.md +0 -0
  41. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/domain/base_entity.md +0 -0
  42. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/frontend/api.service.ts +0 -0
  43. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/frontend/useStateNavigation.ts +0 -0
  44. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponent.spec.tsx +0 -0
  45. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponent.tsx +0 -0
  46. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.spec.tsx +0 -0
  47. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.tsx +0 -0
  48. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/Sample-dot-github/scaffolds/frontend/virtual-list/index.ts +0 -0
  49. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/changelogs/mui_v9.txt +0 -0
  50. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/code-map.md +0 -0
  51. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/nx_uv_setup.md +0 -0
  52. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/patch_output.py +0 -0
  53. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/plan-languageAwareTemplateAdd.prompt.md +0 -0
  54. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/Cargo.lock +0 -0
  55. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/Cargo.toml +0 -0
  56. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/pyproject.toml +0 -0
  57. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/rpr_parser.pyi +0 -0
  58. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/config/container.rs +0 -0
  59. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/config/mod.rs +0 -0
  60. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/config/settings.rs +0 -0
  61. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/graph.rs +0 -0
  62. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/lib.rs +0 -0
  63. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/models/dtos/mod.rs +0 -0
  64. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/models/entities/mod.rs +0 -0
  65. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/models/entities/users.rs +0 -0
  66. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/models/mod.rs +0 -0
  67. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/parse.rs +0 -0
  68. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/repos/base.rs +0 -0
  69. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/repos/mod.rs +0 -0
  70. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/repos/users.rs +0 -0
  71. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/resolve.rs +0 -0
  72. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/src/walker.rs +0 -0
  73. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/rpr-parser/uv.lock +0 -0
  74. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/special_files.md +0 -0
  75. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/__init__.py +0 -0
  76. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/approval.py +0 -0
  77. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/bootstrap.py +0 -0
  78. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/client.py +0 -0
  79. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/control.py +0 -0
  80. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/mock.py +0 -0
  81. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/runtime.py +0 -0
  82. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/session.py +0 -0
  83. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/tools/__init__.py +0 -0
  84. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/tools/base.py +0 -0
  85. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/tools/mutating.py +0 -0
  86. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/tools/readonly.py +0 -0
  87. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/agent/tools/registry.py +0 -0
  88. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/__init__.py +0 -0
  89. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/chat_service.py +0 -0
  90. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/checks.py +0 -0
  91. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/cli_adapter.py +0 -0
  92. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/completer.py +0 -0
  93. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/conversation_service.py +0 -0
  94. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/prompt_service.py +0 -0
  95. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/selector.py +0 -0
  96. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/application/shell.py +0 -0
  97. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/checks/__init__.py +0 -0
  98. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/checks/base.py +0 -0
  99. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/checks/instructions.py +0 -0
  100. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/checks/packages.py +0 -0
  101. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/checks/workspace.py +0 -0
  102. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/__init__.py +0 -0
  103. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/add.py +0 -0
  104. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/chat.py +0 -0
  105. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/check.py +0 -0
  106. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/generate/__init__.py +0 -0
  107. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/generate/api.py +0 -0
  108. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/generate/engine.py +0 -0
  109. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/generate/storybook.py +0 -0
  110. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/generate/ui.py +0 -0
  111. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/init.py +0 -0
  112. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/map.py +0 -0
  113. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/refresh.py +0 -0
  114. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/settings.py +0 -0
  115. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/commands/sync.py +0 -0
  116. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/context.py +0 -0
  117. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/dependencies.py +0 -0
  118. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/dependency_manifest_data.py +0 -0
  119. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/generators/__init__.py +0 -0
  120. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/generators/base.py +0 -0
  121. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/generators/claude.py +0 -0
  122. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/generators/copilot.py +0 -0
  123. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/generators/cursor.py +0 -0
  124. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/generators/gemini.py +0 -0
  125. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/generators/github.py +0 -0
  126. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/__init__.py +0 -0
  127. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/architecture.py +0 -0
  128. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/chains.py +0 -0
  129. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/classifier.py +0 -0
  130. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/coverage.py +0 -0
  131. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/dependencies.py +0 -0
  132. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/extractor.py +0 -0
  133. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/graph.py +0 -0
  134. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/output.py +0 -0
  135. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/responsibility.py +0 -0
  136. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/topology.py +0 -0
  137. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/map/walker.py +0 -0
  138. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/domain/base_entity.md +0 -0
  139. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/domain/base_repo.md +0 -0
  140. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/domain/container.md +0 -0
  141. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/domain/settings.md +0 -0
  142. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/instructions/all.instructions.md +0 -0
  143. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/instructions/api.instructions.md +0 -0
  144. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/instructions/frontend.instructions.md +0 -0
  145. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/instructions/rust-engine.instructions.md +0 -0
  146. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +0 -0
  147. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +0 -0
  148. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -0
  149. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/README.md +0 -0
  150. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/client/index.ts +0 -0
  151. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/client/types.ts +0 -0
  152. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.spec.tsx +0 -0
  153. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.tsx +0 -0
  154. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/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
  155. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.spec.ts +0 -0
  156. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.ts +0 -0
  157. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/index.ts +0 -0
  158. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatComposerMentionTokens.tsx +0 -0
  159. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatSuggestionsPopover.tsx +0 -0
  160. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/LocalFileSuggestionAction.tsx +0 -0
  161. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/index.ts +0 -0
  162. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.spec.ts +0 -0
  163. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.ts +0 -0
  164. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.spec.ts +0 -0
  165. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.ts +0 -0
  166. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/types.ts +0 -0
  167. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/useChatSuggestions.ts +0 -0
  168. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/types.ts +0 -0
  169. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/useChatComposer.ts +0 -0
  170. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.spec.tsx +0 -0
  171. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.ts +0 -0
  172. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/index.ts +0 -0
  173. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/testing/createMockChatStreamClient.ts +0 -0
  174. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/testing/createMockSuggestionProvider.ts +0 -0
  175. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/testing/index.ts +0 -0
  176. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessage.tsx +0 -0
  177. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.spec.tsx +0 -0
  178. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.tsx +0 -0
  179. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.spec.tsx +0 -0
  180. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.tsx +0 -0
  181. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/README.md +0 -0
  182. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/contentFormat.ts +0 -0
  183. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/index.ts +0 -0
  184. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/streaming.ts +0 -0
  185. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/thread/types.ts +0 -0
  186. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.spec.tsx +0 -0
  187. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.tsx +0 -0
  188. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.spec.tsx +0 -0
  189. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.tsx +0 -0
  190. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/chat/virtual-list/index.ts +0 -0
  191. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
  192. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
  193. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/sticky-navigation.spec.md +0 -0
  194. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/js_special_files/vitest-browser-config.md +0 -0
  195. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/special_files/domain_container.md +0 -0
  196. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/special_files/domain_settings.md +0 -0
  197. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
  198. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/special_files/encrypted_column.md +0 -0
  199. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
  200. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
  201. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/templates/__init__.py +0 -0
  202. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/ui/__init__.py +0 -0
  203. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/ui/console.py +0 -0
  204. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/ui/markdown.py +0 -0
  205. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/ui/prompt_session.py +0 -0
  206. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/ui/renderers.py +0 -0
  207. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/ui/theme.py +0 -0
  208. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/src/rpr/workspace.py +0 -0
  209. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/README.md +0 -0
  210. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/00-bootstrap-cli.md +0 -0
  211. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/01-rpr-init.md +0 -0
  212. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/03-rpr-generate-api.md +0 -0
  213. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/04-rpr-generate-ui.md +0 -0
  214. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/05-rpr-generate-engine.md +0 -0
  215. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/06-rpr-generate-storybook.md +0 -0
  216. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/07-rpr-sync-rules.md +0 -0
  217. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/09-rpr-check.md +0 -0
  218. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/10-rpr-domain-config.md +0 -0
  219. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/18-rpr-terminal-ui-foundation.md +0 -0
  220. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/19-rpr-markdown-rendering.md +0 -0
  221. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/20-rpr-chat-repl.md +0 -0
  222. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/21-rpr-agent-tool-loop.md +0 -0
  223. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/22-rpr-chat-tui.md +0 -0
  224. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/23-rpr-chat-unified-command-shell.md +0 -0
  225. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/24-rpr-async-chat-runtime-and-services.md +0 -0
  226. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/25-rpr-prompt-service-and-conversation-lifecycle.md +0 -0
  227. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/26-rpr-shared-command-catalog.md +0 -0
  228. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/27-rpr-slash-command-selection-panel.md +0 -0
  229. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/28-rpr-chat-cancellable-and-multiline-input.md +0 -0
  230. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/chat/29-rpr-file-context-selection.md +0 -0
  231. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/11-rpr-map-command.md +0 -0
  232. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/12-rpr-map-file-walker.md +0 -0
  233. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/13-rpr-map-rust-engine.md +0 -0
  234. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/13a-rpr-map-gitignore.md +0 -0
  235. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/14-rpr-map-graph-builder.md +0 -0
  236. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/15-rpr-map-analysis-bridge.md +0 -0
  237. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/16-rpr-map-layer-classifier.md +0 -0
  238. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/17-rpr-map-output.md +0 -0
  239. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/17a-rpr-map-directory-topology.md +0 -0
  240. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/17b-rpr-map-architecture-assessment.md +0 -0
  241. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/17c-rpr-map-representative-chains.md +0 -0
  242. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/completed/map/17d-rpr-map-multi-resolution-output.md +0 -0
  243. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/map/30-rpr-map-directory-view-and-cycle-detection.md +0 -0
  244. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/map/31-rpr-map-coupling-hotspots-and-verdict-reasoning.md +0 -0
  245. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/stories/map/32-rpr-map-dependencies-responsibilities-and-test-coverage.md +0 -0
  246. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/__init__.py +0 -0
  247. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_architecture.py +0 -0
  248. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_architecture_unwrapped.py +0 -0
  249. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_chat.py +0 -0
  250. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_chat_service.py +0 -0
  251. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_check.py +0 -0
  252. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_completer.py +0 -0
  253. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_context.py +0 -0
  254. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_generate_api.py +0 -0
  255. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_generate_engine.py +0 -0
  256. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_generate_storybook.py +0 -0
  257. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_generate_ui.py +0 -0
  258. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_init.py +0 -0
  259. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map.py +0 -0
  260. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_chains.py +0 -0
  261. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_classifier.py +0 -0
  262. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_coverage.py +0 -0
  263. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_dependencies.py +0 -0
  264. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_extractor.py +0 -0
  265. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_graph.py +0 -0
  266. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_output.py +0 -0
  267. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_responsibility.py +0 -0
  268. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_topology.py +0 -0
  269. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_map_walker.py +0 -0
  270. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_packaging.py +0 -0
  271. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_prompt_session.py +0 -0
  272. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_refresh.py +0 -0
  273. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_rpr_parser_stub.py +0 -0
  274. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_selector.py +0 -0
  275. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_settings.py +0 -0
  276. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_sync.py +0 -0
  277. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/tests/test_ui.py +0 -0
  278. {rpr_cli-0.1.29 → rpr_cli-0.2.0}/update_output.py +0 -0
@@ -1,3 +1,20 @@
1
+ Metadata-Version: 2.4
2
+ Name: rpr-cli
3
+ Version: 0.2.0
4
+ Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.14
8
+ Requires-Dist: jinja2>=3.1.5
9
+ Requires-Dist: packaging>=26.2
10
+ Requires-Dist: pathspec>=1.0.4
11
+ Requires-Dist: prompt-toolkit>=3.0.52
12
+ Requires-Dist: pyyaml>=6.0.2
13
+ Requires-Dist: rich>=14.3.3
14
+ Requires-Dist: tomlkit>=0.15.0
15
+ Requires-Dist: typer>=0.24.1
16
+ Description-Content-Type: text/markdown
17
+
1
18
  # RPR CLI
2
19
 
3
20
  React Python Rust monorepo scaffolding orchestrator.
@@ -85,6 +102,8 @@ RPR keeps dependencies close to the package that uses them.
85
102
 
86
103
  Python dependency changes are made with `uv` so they are tracked in `pyproject.toml`. Node dependency changes are made through npm workspace package metadata and root `npm install`.
87
104
 
105
+ Update project-owned package manifests from upstream registries with `rpr update node` or `rpr update python`. Node updates target `package.json`; Python updates target `pyproject.toml` by default and fall back to `requirements.txt` when no `pyproject.toml` exists. Use `--file` to update a nested manifest, `--dry-run` to preview without changing files or running installers, and `--include-major` to opt into major-version updates.
106
+
88
107
  The scaffold version manifest that powers generated dependency specs and the synced AI tech-stack overview lives in `src/rpr/dependency_manifest_data.py`. Refresh it from upstream registries with `rpr refresh manifest` when you want the repo-owned defaults to move forward.
89
108
 
90
109
  ### 🧠 AI Instructions & Code Templates
@@ -94,6 +113,7 @@ Sync project context to your favorite AI tools and add common code patterns.
94
113
  ```bash
95
114
  rpr sync rules # Sync AI instructions to Cursor, Copilot, Claude Code, and Gemini
96
115
  rpr add template python mapper_util # Add a Python code template to your project
116
+ rpr add template python camel_case_model
97
117
  rpr add template node sticky_navigation --include-tests
98
118
  rpr add template node -l # List available Node/TSX templates
99
119
  rpr add template --list # List all available code templates
@@ -132,6 +152,8 @@ Keep your project healthy and explore its structure.
132
152
 
133
153
  ```bash
134
154
  rpr refresh manifest # Refresh the scaffold dependency manifest from npm, PyPI, and crates.io
155
+ rpr update node # Update package.json dependencies and run npm install
156
+ rpr update python # Update pyproject.toml or requirements.txt and sync Python dependencies
135
157
  rpr check # Inspect project health and report setup status
136
158
  rpr map # Generate a structured code map of your project
137
159
  rpr settings # Inspect persisted shell settings
@@ -148,6 +170,8 @@ Persisted settings currently include:
148
170
 
149
171
  `rpr refresh manifest` is a repo-maintenance command. It rewrites `src/rpr/dependency_manifest_data.py`, which feeds scaffold dependency versions in `rpr generate ...` and the versioned overview text produced by `rpr sync rules`. Use `--dry-run` to preview the manifest rewrite without writing the file.
150
172
 
173
+ `rpr update node` and `rpr update python` are project-maintenance commands. They update the selected package manifest, print applied and held-back dependency changes, and run the matching installer only when live changes are written. Without `--include-major`, RPR chooses the latest stable version inside the current major version and reports higher-major candidates as held back. Python updates cover `[project].dependencies`, `[dependency-groups].*`, and `requirements.txt`; build backend packages in `[build-system].requires` are left unchanged unless a future explicit build-system update option is added.
174
+
151
175
  ### ⚙️ Common Flags
152
176
 
153
177
  Most commands support these global flags:
@@ -1,18 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: rpr-cli
3
- Version: 0.1.29
4
- Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
5
- License-Expression: MIT
6
- License-File: LICENSE
7
- Requires-Python: >=3.14
8
- Requires-Dist: jinja2>=3.1.5
9
- Requires-Dist: pathspec>=1.0.4
10
- Requires-Dist: prompt-toolkit>=3.0.52
11
- Requires-Dist: pyyaml>=6.0.2
12
- Requires-Dist: rich>=14.3.3
13
- Requires-Dist: typer>=0.24.1
14
- Description-Content-Type: text/markdown
15
-
16
1
  # RPR CLI
17
2
 
18
3
  React Python Rust monorepo scaffolding orchestrator.
@@ -100,6 +85,8 @@ RPR keeps dependencies close to the package that uses them.
100
85
 
101
86
  Python dependency changes are made with `uv` so they are tracked in `pyproject.toml`. Node dependency changes are made through npm workspace package metadata and root `npm install`.
102
87
 
88
+ Update project-owned package manifests from upstream registries with `rpr update node` or `rpr update python`. Node updates target `package.json`; Python updates target `pyproject.toml` by default and fall back to `requirements.txt` when no `pyproject.toml` exists. Use `--file` to update a nested manifest, `--dry-run` to preview without changing files or running installers, and `--include-major` to opt into major-version updates.
89
+
103
90
  The scaffold version manifest that powers generated dependency specs and the synced AI tech-stack overview lives in `src/rpr/dependency_manifest_data.py`. Refresh it from upstream registries with `rpr refresh manifest` when you want the repo-owned defaults to move forward.
104
91
 
105
92
  ### 🧠 AI Instructions & Code Templates
@@ -109,6 +96,7 @@ Sync project context to your favorite AI tools and add common code patterns.
109
96
  ```bash
110
97
  rpr sync rules # Sync AI instructions to Cursor, Copilot, Claude Code, and Gemini
111
98
  rpr add template python mapper_util # Add a Python code template to your project
99
+ rpr add template python camel_case_model
112
100
  rpr add template node sticky_navigation --include-tests
113
101
  rpr add template node -l # List available Node/TSX templates
114
102
  rpr add template --list # List all available code templates
@@ -147,6 +135,8 @@ Keep your project healthy and explore its structure.
147
135
 
148
136
  ```bash
149
137
  rpr refresh manifest # Refresh the scaffold dependency manifest from npm, PyPI, and crates.io
138
+ rpr update node # Update package.json dependencies and run npm install
139
+ rpr update python # Update pyproject.toml or requirements.txt and sync Python dependencies
150
140
  rpr check # Inspect project health and report setup status
151
141
  rpr map # Generate a structured code map of your project
152
142
  rpr settings # Inspect persisted shell settings
@@ -163,6 +153,8 @@ Persisted settings currently include:
163
153
 
164
154
  `rpr refresh manifest` is a repo-maintenance command. It rewrites `src/rpr/dependency_manifest_data.py`, which feeds scaffold dependency versions in `rpr generate ...` and the versioned overview text produced by `rpr sync rules`. Use `--dry-run` to preview the manifest rewrite without writing the file.
165
155
 
156
+ `rpr update node` and `rpr update python` are project-maintenance commands. They update the selected package manifest, print applied and held-back dependency changes, and run the matching installer only when live changes are written. Without `--include-major`, RPR chooses the latest stable version inside the current major version and reports higher-major candidates as held back. Python updates cover `[project].dependencies`, `[dependency-groups].*`, and `requirements.txt`; build backend packages in `[build-system].requires` are left unchanged unless a future explicit build-system update option is added.
157
+
166
158
  ### ⚙️ Common Flags
167
159
 
168
160
  Most commands support these global flags:
@@ -12,6 +12,8 @@ dependencies = [
12
12
  "rich>=14.3.3",
13
13
  "pathspec>=1.0.4",
14
14
  "prompt-toolkit>=3.0.52",
15
+ "tomlkit>=0.15.0",
16
+ "packaging>=26.2",
15
17
  ]
16
18
 
17
19
  [project.scripts]
@@ -0,0 +1 @@
1
+ __version__ = "0.2.0"
@@ -241,6 +241,67 @@ COMMAND_CATALOG: tuple[CommandDefinition, ...] = (
241
241
  ),
242
242
  ),
243
243
  ),
244
+ CommandDefinition(
245
+ name="update",
246
+ description="Update project package manifests from upstream registries.",
247
+ action_id="update.dispatch",
248
+ children=(
249
+ CommandDefinition(
250
+ name="node",
251
+ description="Update a package.json manifest and run npm install.",
252
+ action_id="update.node",
253
+ options=(
254
+ CommandOption(
255
+ "--file",
256
+ "Package manifest to update.",
257
+ kind="value",
258
+ value_name="PATH",
259
+ ),
260
+ CommandOption(
261
+ "--include-major",
262
+ "Apply available updates across major versions.",
263
+ kind="flag",
264
+ ),
265
+ CommandOption(
266
+ "--timeout",
267
+ "Per-request registry timeout in seconds.",
268
+ kind="value",
269
+ value_name="SECONDS",
270
+ ),
271
+ CommandOption(
272
+ "--dry-run", "Preview changes without writing.", kind="flag"
273
+ ),
274
+ ),
275
+ ),
276
+ CommandDefinition(
277
+ name="python",
278
+ description="Update a Python manifest and run the matching sync command.",
279
+ action_id="update.python",
280
+ options=(
281
+ CommandOption(
282
+ "--file",
283
+ "Package manifest to update.",
284
+ kind="value",
285
+ value_name="PATH",
286
+ ),
287
+ CommandOption(
288
+ "--include-major",
289
+ "Apply available updates across major versions.",
290
+ kind="flag",
291
+ ),
292
+ CommandOption(
293
+ "--timeout",
294
+ "Per-request registry timeout in seconds.",
295
+ kind="value",
296
+ value_name="SECONDS",
297
+ ),
298
+ CommandOption(
299
+ "--dry-run", "Preview changes without writing.", kind="flag"
300
+ ),
301
+ ),
302
+ ),
303
+ ),
304
+ ),
244
305
  CommandDefinition(
245
306
  name="add",
246
307
  description="Write a registered template into the current project.",
@@ -39,6 +39,13 @@ refresh_app = typer.Typer(
39
39
  )
40
40
  app.add_typer(refresh_app, name="refresh")
41
41
 
42
+ update_app = typer.Typer(
43
+ name="update",
44
+ help="Update project package manifests from upstream registries.",
45
+ no_args_is_help=True,
46
+ )
47
+ app.add_typer(update_app, name="update")
48
+
42
49
  add_app = typer.Typer(
43
50
  name="add",
44
51
  help="Add code templates to the current project.",
@@ -54,6 +61,7 @@ from rpr.commands.generate import engine as _engine_mod # noqa: E402, F401
54
61
  from rpr.commands.generate import storybook as _storybook_mod # noqa: E402, F401
55
62
  from rpr.commands import sync as _sync_mod # noqa: E402, F401
56
63
  from rpr.commands import refresh as _refresh_mod # noqa: E402, F401
64
+ from rpr.commands import update as _update_mod # noqa: E402, F401
57
65
  from rpr.commands import add as _add_mod # noqa: E402, F401
58
66
 
59
67
 
@@ -17,7 +17,12 @@ console = Console()
17
17
 
18
18
  _SCAFFOLD_DIR = Path(__file__).parent.parent.parent / "scaffolds" / "domain"
19
19
 
20
- _UTILITY_TEMPLATES = ["mapper_util", "dto_util", "partial_update"]
20
+ _UTILITY_TEMPLATES = [
21
+ "mapper_util",
22
+ "dto_util",
23
+ "camel_case_model",
24
+ "partial_update",
25
+ ]
21
26
 
22
27
 
23
28
  @generate_app.command()
@@ -0,0 +1,222 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import Annotated
5
+
6
+ import typer
7
+ from rich.console import Console
8
+
9
+ from rpr.cli import update_app
10
+ from rpr.context import RunContext
11
+ from rpr.package_updates import (
12
+ PackageFileKind,
13
+ PackageUpdateError,
14
+ PackageUpdatePlan,
15
+ plan_package_updates,
16
+ )
17
+ from rpr.ui.renderers import render_table
18
+
19
+ console = Console()
20
+
21
+
22
+ @update_app.command("node")
23
+ def node(
24
+ file: Annotated[
25
+ str | None,
26
+ typer.Option("--file", help="Package manifest to update."),
27
+ ] = None,
28
+ include_major: Annotated[
29
+ bool,
30
+ typer.Option(
31
+ "--include-major", help="Apply available updates across major versions."
32
+ ),
33
+ ] = False,
34
+ dry_run: Annotated[
35
+ bool, typer.Option("--dry-run", help="Preview changes without writing.")
36
+ ] = False,
37
+ timeout: Annotated[
38
+ float,
39
+ typer.Option(
40
+ "--timeout",
41
+ min=1.0,
42
+ help="Per-request timeout in seconds when talking to registries.",
43
+ ),
44
+ ] = 10.0,
45
+ ) -> None:
46
+ """Update a package.json manifest and run npm install."""
47
+ ctx = RunContext(dry_run=dry_run, project_dir=Path.cwd())
48
+ manifest_path = _resolve_manifest_path(file, default=ctx.project_dir / "package.json")
49
+ plan = _build_plan(
50
+ manifest_path,
51
+ "node",
52
+ include_major=include_major,
53
+ dry_run=dry_run,
54
+ timeout=timeout,
55
+ )
56
+ _apply_plan(ctx, plan)
57
+
58
+
59
+ @update_app.command("python")
60
+ def python(
61
+ file: Annotated[
62
+ str | None,
63
+ typer.Option("--file", help="Package manifest to update."),
64
+ ] = None,
65
+ include_major: Annotated[
66
+ bool,
67
+ typer.Option(
68
+ "--include-major", help="Apply available updates across major versions."
69
+ ),
70
+ ] = False,
71
+ dry_run: Annotated[
72
+ bool, typer.Option("--dry-run", help="Preview changes without writing.")
73
+ ] = False,
74
+ timeout: Annotated[
75
+ float,
76
+ typer.Option(
77
+ "--timeout",
78
+ min=1.0,
79
+ help="Per-request timeout in seconds when talking to registries.",
80
+ ),
81
+ ] = 10.0,
82
+ ) -> None:
83
+ """Update a Python manifest and run the matching sync command."""
84
+ ctx = RunContext(dry_run=dry_run, project_dir=Path.cwd())
85
+ manifest_path = _resolve_manifest_path(
86
+ file,
87
+ default=_default_python_manifest(ctx.project_dir),
88
+ )
89
+ plan = _build_plan(
90
+ manifest_path,
91
+ "python",
92
+ include_major=include_major,
93
+ dry_run=dry_run,
94
+ timeout=timeout,
95
+ )
96
+ _apply_plan(ctx, plan)
97
+
98
+
99
+ def _resolve_manifest_path(file: str | None, *, default: Path) -> Path:
100
+ if file is None:
101
+ return default
102
+ path = Path(file).expanduser()
103
+ if path.is_absolute():
104
+ return path
105
+ return Path.cwd() / path
106
+
107
+
108
+ def _default_python_manifest(project_dir: Path) -> Path:
109
+ pyproject = project_dir / "pyproject.toml"
110
+ if pyproject.exists():
111
+ return pyproject
112
+ return project_dir / "requirements.txt"
113
+
114
+
115
+ def _build_plan(
116
+ manifest_path: Path,
117
+ target: str,
118
+ *,
119
+ include_major: bool,
120
+ dry_run: bool,
121
+ timeout: float,
122
+ ) -> PackageUpdatePlan:
123
+ try:
124
+ plan = plan_package_updates(
125
+ manifest_path,
126
+ target, # type: ignore[arg-type]
127
+ include_major=include_major,
128
+ timeout=timeout,
129
+ )
130
+ except PackageUpdateError as exc:
131
+ console.print(f"[bold red]Error:[/] {exc}")
132
+ raise typer.Exit(1) from exc
133
+
134
+ _render_plan(plan, dry_run=dry_run)
135
+ return plan
136
+
137
+
138
+ def _render_plan(plan: PackageUpdatePlan, *, dry_run: bool) -> None:
139
+ if not plan.changes:
140
+ if plan.supported_section_count == 0:
141
+ console.print(
142
+ f"[bold green]Done![/] No supported dependency sections in {plan.path}."
143
+ )
144
+ else:
145
+ console.print(f"[bold green]Done![/] {plan.path} is already up to date.")
146
+ _render_skipped(plan)
147
+ if dry_run:
148
+ console.print(
149
+ "\n[bold yellow]Dry run complete.[/] No manifest or installer command was changed."
150
+ )
151
+ return
152
+
153
+ action = "Planned" if dry_run else "Applying"
154
+ console.print(f"\n[bold]{action} package updates[/] ({len(plan.changes)} updates)\n")
155
+ render_table(
156
+ "Package updates",
157
+ ["Path", "Section", "Package", "Old", "New", "Major"],
158
+ [
159
+ [
160
+ str(change.path),
161
+ change.section,
162
+ change.package,
163
+ change.old_specifier,
164
+ change.new_specifier,
165
+ "yes" if change.is_major else "no",
166
+ ]
167
+ for change in plan.changes
168
+ ],
169
+ )
170
+ _render_skipped(plan)
171
+ if dry_run:
172
+ console.print(
173
+ "\n[bold yellow]Dry run complete.[/] No manifest or installer command was changed."
174
+ )
175
+
176
+
177
+ def _render_skipped(plan: PackageUpdatePlan) -> None:
178
+ if not plan.skipped:
179
+ return
180
+ rows = []
181
+ for skipped in plan.skipped:
182
+ reason = skipped.reason
183
+ if skipped.latest_version:
184
+ reason = f"{reason} (latest: {skipped.latest_version})"
185
+ rows.append(
186
+ [
187
+ str(skipped.path),
188
+ skipped.section,
189
+ skipped.package,
190
+ skipped.specifier,
191
+ reason,
192
+ ]
193
+ )
194
+ render_table(
195
+ "Skipped package updates",
196
+ ["Path", "Section", "Package", "Specifier", "Reason"],
197
+ rows,
198
+ )
199
+
200
+
201
+ def _apply_plan(ctx: RunContext, plan: PackageUpdatePlan) -> None:
202
+ if not plan.has_changes:
203
+ return
204
+ if ctx.dry_run:
205
+ return
206
+
207
+ ctx.update_file(plan.path, plan.updated_content)
208
+ _run_installer(ctx, plan.file_kind, plan.path)
209
+ console.print(f"\n[bold green]Done![/] Updated package manifest at {plan.path}")
210
+
211
+
212
+ def _run_installer(ctx: RunContext, file_kind: PackageFileKind, manifest_path: Path) -> None:
213
+ if file_kind == "package-json":
214
+ ctx.run_command(["npm", "install"], cwd=ctx.project_dir)
215
+ return
216
+ if file_kind == "pyproject-toml":
217
+ ctx.run_uv_command(["uv", "sync", "--all-packages"], cwd=ctx.project_dir)
218
+ return
219
+ ctx.run_command(
220
+ ["python", "-m", "pip", "install", "-r", str(manifest_path)],
221
+ cwd=ctx.project_dir,
222
+ )
@@ -8,6 +8,8 @@ from typing import Literal
8
8
  from urllib.parse import quote
9
9
  from urllib.request import Request, urlopen
10
10
 
11
+ from packaging.version import InvalidVersion, Version
12
+
11
13
  RegistryName = Literal["npm", "pypi", "cratesio"]
12
14
  RefreshStrategy = Literal[
13
15
  "caret", "minimum", "exact", "major-range", "latest", "pinned-major"
@@ -64,6 +66,54 @@ def fetch_latest_version(
64
66
  ) from exc
65
67
 
66
68
 
69
+ def fetch_available_versions(
70
+ registry: RegistryName, package: str, *, timeout: float = 10.0
71
+ ) -> list[str]:
72
+ if registry == "npm":
73
+ url = f"https://registry.npmjs.org/{quote(package, safe='')}"
74
+ elif registry == "pypi":
75
+ url = f"https://pypi.org/pypi/{quote(package, safe='')}/json"
76
+ else:
77
+ raise ManifestRefreshError(
78
+ f"Available-version lookup is not supported for {registry} packages"
79
+ )
80
+
81
+ request = Request(url, headers={"User-Agent": _USER_AGENT})
82
+ try:
83
+ with urlopen(request, timeout=timeout) as response:
84
+ payload = json.load(response)
85
+ except Exception as exc: # pragma: no cover - exercised through command tests
86
+ raise ManifestRefreshError(
87
+ f"Failed to fetch {registry} metadata for {package}: {exc}"
88
+ ) from exc
89
+
90
+ try:
91
+ raw_versions = (
92
+ payload["versions"].keys() if registry == "npm" else payload["releases"].keys()
93
+ )
94
+ except Exception as exc: # pragma: no cover - exercised through command tests
95
+ raise ManifestRefreshError(
96
+ f"Registry response for {package} did not include available versions"
97
+ ) from exc
98
+
99
+ versions: list[tuple[Version, str]] = []
100
+ for raw_version in raw_versions:
101
+ try:
102
+ parsed = Version(str(raw_version))
103
+ except InvalidVersion:
104
+ continue
105
+ if parsed.is_prerelease or parsed.is_devrelease:
106
+ continue
107
+ versions.append((parsed, str(raw_version)))
108
+
109
+ if not versions:
110
+ raise ManifestRefreshError(
111
+ f"Registry response for {package} did not include stable versions"
112
+ )
113
+
114
+ return [raw_version for _, raw_version in sorted(versions, reverse=True)]
115
+
116
+
67
117
  def refresh_dependency_manifest(
68
118
  manifest: Manifest,
69
119
  *,