rpr-cli 0.1.6__tar.gz → 0.1.9__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 (221) hide show
  1. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/PKG-INFO +1 -1
  2. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/instructions/frontend.instructions.md +2 -1
  3. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/instructions/setup-guide.instructions.md +4 -0
  4. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/nx_uv_setup.md +36 -41
  5. rpr_cli-0.1.9/src/rpr/__init__.py +1 -0
  6. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/checks/workspace.py +1 -1
  7. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/generate/api.py +9 -0
  8. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/generate/domain.py +9 -0
  9. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/generate/storybook.py +8 -4
  10. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/generate/ui.py +6 -3
  11. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/init.py +16 -3
  12. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/dependencies.py +28 -2
  13. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/instructions/frontend.instructions.md +2 -1
  14. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +4 -0
  15. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/workspace.py +28 -3
  16. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_check.py +2 -2
  17. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_generate_api.py +2 -0
  18. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_generate_domain.py +2 -0
  19. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_generate_storybook.py +4 -3
  20. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_generate_ui.py +100 -8
  21. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_init.py +4 -2
  22. rpr_cli-0.1.6/src/rpr/__init__.py +0 -1
  23. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/.github/agents/story.agent.md +0 -0
  24. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/.github/workflows/publish-pypi.yml +0 -0
  25. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/.gitignore +0 -0
  26. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/CLAUDE.md +0 -0
  27. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/GEMINI.md +0 -0
  28. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/LICENSE +0 -0
  29. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/README.md +0 -0
  30. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/instructions/all.instructions.md +0 -0
  31. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/instructions/api.instructions.md +0 -0
  32. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/instructions/domain.instructions.md +0 -0
  33. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/instructions/rust-engine.instructions.md +0 -0
  34. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/instructions/tooling-setup.instructions.md +0 -0
  35. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/instructions/tooling.instructions.md +0 -0
  36. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/scaffolds/README.md +0 -0
  37. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/scaffolds/api/main.py +0 -0
  38. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/scaffolds/domain/base-repo.md +0 -0
  39. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/scaffolds/domain/base_entity.md +0 -0
  40. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/scaffolds/frontend/api.service.ts +0 -0
  41. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/Sample-dot-github/scaffolds/frontend/useStateNavigation.ts +0 -0
  42. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/changelogs/mui_v9.txt +0 -0
  43. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/code-map.md +0 -0
  44. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/patch_output.py +0 -0
  45. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/pyproject.toml +0 -0
  46. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/Cargo.lock +0 -0
  47. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/Cargo.toml +0 -0
  48. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/pyproject.toml +0 -0
  49. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/rpr_parser.pyi +0 -0
  50. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/config/container.rs +0 -0
  51. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/config/mod.rs +0 -0
  52. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/config/settings.rs +0 -0
  53. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/graph.rs +0 -0
  54. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/lib.rs +0 -0
  55. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/models/dtos/mod.rs +0 -0
  56. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/models/entities/mod.rs +0 -0
  57. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/models/entities/users.rs +0 -0
  58. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/models/mod.rs +0 -0
  59. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/parse.rs +0 -0
  60. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/repos/base.rs +0 -0
  61. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/repos/mod.rs +0 -0
  62. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/repos/users.rs +0 -0
  63. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/resolve.rs +0 -0
  64. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/src/walker.rs +0 -0
  65. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/rpr-parser/uv.lock +0 -0
  66. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/special_files.md +0 -0
  67. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/__init__.py +0 -0
  68. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/approval.py +0 -0
  69. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/bootstrap.py +0 -0
  70. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/client.py +0 -0
  71. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/control.py +0 -0
  72. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/mock.py +0 -0
  73. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/runtime.py +0 -0
  74. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/session.py +0 -0
  75. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/tools/__init__.py +0 -0
  76. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/tools/base.py +0 -0
  77. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/tools/mutating.py +0 -0
  78. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/tools/readonly.py +0 -0
  79. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/agent/tools/registry.py +0 -0
  80. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/__init__.py +0 -0
  81. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/catalog.py +0 -0
  82. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/chat_service.py +0 -0
  83. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/checks.py +0 -0
  84. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/cli_adapter.py +0 -0
  85. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/completer.py +0 -0
  86. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/conversation_service.py +0 -0
  87. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/prompt_service.py +0 -0
  88. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/selector.py +0 -0
  89. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/application/shell.py +0 -0
  90. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/checks/__init__.py +0 -0
  91. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/checks/base.py +0 -0
  92. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/checks/instructions.py +0 -0
  93. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/checks/packages.py +0 -0
  94. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/cli.py +0 -0
  95. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/__init__.py +0 -0
  96. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/add.py +0 -0
  97. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/chat.py +0 -0
  98. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/check.py +0 -0
  99. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/generate/__init__.py +0 -0
  100. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/generate/engine.py +0 -0
  101. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/map.py +0 -0
  102. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/refresh.py +0 -0
  103. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/settings.py +0 -0
  104. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/commands/sync.py +0 -0
  105. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/context.py +0 -0
  106. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/dependency_manifest_data.py +0 -0
  107. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/generators/__init__.py +0 -0
  108. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/generators/base.py +0 -0
  109. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/generators/claude.py +0 -0
  110. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/generators/copilot.py +0 -0
  111. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/generators/cursor.py +0 -0
  112. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/generators/gemini.py +0 -0
  113. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/manifest_refresh.py +0 -0
  114. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/__init__.py +0 -0
  115. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/architecture.py +0 -0
  116. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/chains.py +0 -0
  117. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/classifier.py +0 -0
  118. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/coverage.py +0 -0
  119. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/dependencies.py +0 -0
  120. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/extractor.py +0 -0
  121. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/graph.py +0 -0
  122. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/output.py +0 -0
  123. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/responsibility.py +0 -0
  124. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/topology.py +0 -0
  125. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/map/walker.py +0 -0
  126. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/domain/base_entity.md +0 -0
  127. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/domain/base_repo.md +0 -0
  128. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/domain/container.md +0 -0
  129. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/domain/settings.md +0 -0
  130. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/instructions/all.instructions.md +0 -0
  131. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/instructions/api.instructions.md +0 -0
  132. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/instructions/domain.instructions.md +0 -0
  133. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/instructions/rust-engine.instructions.md +0 -0
  134. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +0 -0
  135. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -0
  136. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
  137. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
  138. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/special_files/domain_container.md +0 -0
  139. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/special_files/domain_settings.md +0 -0
  140. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
  141. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/special_files/encrypted_column.md +0 -0
  142. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
  143. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
  144. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/templates/__init__.py +0 -0
  145. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/templates/registry.py +0 -0
  146. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/ui/__init__.py +0 -0
  147. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/ui/console.py +0 -0
  148. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/ui/markdown.py +0 -0
  149. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/ui/prompt_session.py +0 -0
  150. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/ui/renderers.py +0 -0
  151. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/src/rpr/ui/theme.py +0 -0
  152. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/README.md +0 -0
  153. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/00-bootstrap-cli.md +0 -0
  154. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/01-rpr-init.md +0 -0
  155. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/02-rpr-generate-domain.md +0 -0
  156. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/03-rpr-generate-api.md +0 -0
  157. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/04-rpr-generate-ui.md +0 -0
  158. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/05-rpr-generate-engine.md +0 -0
  159. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/06-rpr-generate-storybook.md +0 -0
  160. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/07-rpr-sync-rules.md +0 -0
  161. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/08-rpr-add-template.md +0 -0
  162. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/09-rpr-check.md +0 -0
  163. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/10-rpr-domain-config.md +0 -0
  164. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/18-rpr-terminal-ui-foundation.md +0 -0
  165. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/19-rpr-markdown-rendering.md +0 -0
  166. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/20-rpr-chat-repl.md +0 -0
  167. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/21-rpr-agent-tool-loop.md +0 -0
  168. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/22-rpr-chat-tui.md +0 -0
  169. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/23-rpr-chat-unified-command-shell.md +0 -0
  170. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/24-rpr-async-chat-runtime-and-services.md +0 -0
  171. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/25-rpr-prompt-service-and-conversation-lifecycle.md +0 -0
  172. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/26-rpr-shared-command-catalog.md +0 -0
  173. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/27-rpr-slash-command-selection-panel.md +0 -0
  174. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/28-rpr-chat-cancellable-and-multiline-input.md +0 -0
  175. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/chat/29-rpr-file-context-selection.md +0 -0
  176. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/11-rpr-map-command.md +0 -0
  177. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/12-rpr-map-file-walker.md +0 -0
  178. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/13-rpr-map-rust-engine.md +0 -0
  179. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/13a-rpr-map-gitignore.md +0 -0
  180. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/14-rpr-map-graph-builder.md +0 -0
  181. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/15-rpr-map-analysis-bridge.md +0 -0
  182. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/16-rpr-map-layer-classifier.md +0 -0
  183. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/17-rpr-map-output.md +0 -0
  184. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/17a-rpr-map-directory-topology.md +0 -0
  185. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/17b-rpr-map-architecture-assessment.md +0 -0
  186. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/17c-rpr-map-representative-chains.md +0 -0
  187. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/completed/map/17d-rpr-map-multi-resolution-output.md +0 -0
  188. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/map/30-rpr-map-directory-view-and-cycle-detection.md +0 -0
  189. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/map/31-rpr-map-coupling-hotspots-and-verdict-reasoning.md +0 -0
  190. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/stories/map/32-rpr-map-dependencies-responsibilities-and-test-coverage.md +0 -0
  191. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/__init__.py +0 -0
  192. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_add.py +0 -0
  193. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_architecture.py +0 -0
  194. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_architecture_unwrapped.py +0 -0
  195. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_catalog.py +0 -0
  196. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_chat.py +0 -0
  197. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_chat_service.py +0 -0
  198. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_completer.py +0 -0
  199. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_context.py +0 -0
  200. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_generate_engine.py +0 -0
  201. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map.py +0 -0
  202. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_chains.py +0 -0
  203. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_classifier.py +0 -0
  204. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_coverage.py +0 -0
  205. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_dependencies.py +0 -0
  206. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_extractor.py +0 -0
  207. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_graph.py +0 -0
  208. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_output.py +0 -0
  209. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_responsibility.py +0 -0
  210. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_topology.py +0 -0
  211. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_map_walker.py +0 -0
  212. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_packaging.py +0 -0
  213. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_prompt_session.py +0 -0
  214. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_refresh.py +0 -0
  215. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_rpr_parser_stub.py +0 -0
  216. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_selector.py +0 -0
  217. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_settings.py +0 -0
  218. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_sync.py +0 -0
  219. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/tests/test_ui.py +0 -0
  220. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/update_output.py +0 -0
  221. {rpr_cli-0.1.6 → rpr_cli-0.1.9}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rpr-cli
3
- Version: 0.1.6
3
+ Version: 0.1.9
4
4
  Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -11,6 +11,7 @@ Use React for UI composition, TanStack Query for server-state workflows, TanStac
11
11
 
12
12
  - Use functional components.
13
13
  - Extract reusable behavior into hooks instead of duplicating component logic.
14
+ - Import the generated shared UI package through the app-scoped package name `@{name}/ui`, such as `@testapp/ui`, not `@repo/{name}-ui`.
14
15
  - Prefer a shared base API service at `src/services/base/api.service.ts` when the UI package needs centralized fetch behavior.
15
16
  - Prefer a shared `useStateNavigation` hook at `src/hooks/useStateNavigation.ts` when UI state should persist in the URL.
16
17
  - Reuse existing components, hooks, and service patterns before introducing a new abstraction.
@@ -84,7 +85,7 @@ export const SomeContainer = styled(Box)`
84
85
 
85
86
  - Type every API payload and mutation input.
86
87
  - Prefer `type` aliases for DTO-shaped data, `interface` for extendable service contracts, and classes only when the UI genuinely needs behavior.
87
- - For components with children, prefer `React.PropsWithChildren<T>` over manually re-declaring a `children` field.
88
+ - For components with children, prefer `React.PropsWithChildren<T>` over manually redeclaring a `children` field.
88
89
 
89
90
  ## Components
90
91
 
@@ -45,6 +45,9 @@ Use this guidance when validating or changing the monorepo setup against the RPR
45
45
  - Generate React app and library projects in a way that preserves the expected Nx command surface.
46
46
  - The web app should expose at least `serve`, `build`, `lint`, `test`, and `typecheck` when those capabilities exist in the generated project.
47
47
  - The UI library should expose at least `build`, `lint`, `test`, and `typecheck`.
48
+ - Use app-scoped Node package names: `packages/node/{name}-ui` publishes as `@{name}/ui`, `apps/{name}-web` publishes as `@{name}/web`, and Storybook publishes as `@{name}/sb`.
49
+ - Import the shared UI package through `@{name}/ui`, for example `import { AppThemeProvider } from "@testapp/ui"` for a `TestApp` workspace.
50
+ - Link local Node workspace packages with relative `file:` dependency specs instead of `workspace:*`, because npm must be able to install the generated workspace without unsupported protocol errors.
48
51
  - Keep Storybook as a dedicated host project at `packages/node/sb`; do not silently repurpose the UI library as the Storybook project.
49
52
 
50
53
  ## Python Expectations
@@ -81,6 +84,7 @@ npx nx run domain:migrate -- downgrade -1
81
84
  - Project roots and import package names follow the kebab-case and snake_case rules.
82
85
  - Python projects have both `src/` and `tests/`.
83
86
  - The domain import package remains `src/{name_underscore}_domain`.
87
+ - Node imports use app-scoped package names such as `@{name}/ui`, not stale `@repo/*` aliases.
84
88
  - Storybook remains hosted in `packages/node/sb`.
85
89
  - Workspace members and workspace dependency sources are complete.
86
90
  - Generated instructions, checks, and scaffolds refer to the current contract rather than stale paths.
@@ -1,8 +1,8 @@
1
1
  # NX + UV Monorepo Setup Guide
2
2
 
3
- This guide explains how to setup a monorepo that cobines NX ( for Node / Typescript ) and UV (for Python).
3
+ This guide explains how to set up a monorepo that combines NX (for Node / TypeScript) and UV (for Python).
4
4
 
5
- ## Rprerequisites
5
+ ## Prerequisites
6
6
 
7
7
  Install the following:
8
8
 
@@ -10,30 +10,30 @@ Install the following:
10
10
  - **npm**: comes with Node.js
11
11
  - **UV**: install from [uv.io](https://uv.io/)
12
12
  - **Python**: latest version from [python.org](https://www.python.org/)
13
- - **GIT**: latest version from [git-scm.com](https://git-scm.com/)
14
- - **Rust**: latest version from [rust-lang.org](https://www.rust-lang.org/)(optional, for Rust-based engines)
13
+ - **Git**: latest version from [git-scm.com](https://git-scm.com/)
14
+ - **Rust**: latest version from [rust-lang.org](https://www.rust-lang.org/) (optional, for Rust-based engines)
15
15
 
16
16
  ## Initial Setup
17
17
 
18
18
  ### Step 1: Create NX Workspace
19
19
 
20
20
  ```shell
21
- npx create-nx-workspace@latest my-monorepo --template=nrwl/empty-template
21
+ npx create-nx-workspace@latest my-monorepo --preset=apps --nxCloud=never --interactive=false
22
22
  cd my-monorepo
23
23
  ```
24
24
 
25
25
  If you already have an existing directory, you can initialize NX in it:
26
26
 
27
27
  ```shell
28
- npx create-nx-workspace@latest . --template=nrwl/empty-template
28
+ npx nx init --interactive=false --nxCloud=false
29
29
  ```
30
30
 
31
31
  ### Step 2: Initialize UV
32
32
 
33
- Create a root `pyproject.toml`file for UV workspace management
33
+ Create a root `pyproject.toml` file for UV workspace management
34
34
 
35
35
  ```shell
36
- uv init --no-project
36
+ uv init --no-readme --no-pin-python --python {python_version}
37
37
  ```
38
38
 
39
39
  Edit the generated `pyproject.toml` to include the following configuration:
@@ -140,7 +140,7 @@ npx nx g @nx/storybook:configuration {sb-name} --uiFramework=@storybook/react-vi
140
140
 
141
141
  ## Adding Python Projects
142
142
 
143
- Python project require manual setup since NX doesn't have build int Python plugins.
143
+ Python projects require manual setup since NX doesn't have built-in Python plugins.
144
144
 
145
145
  ### Step 1: Create Directory Structure
146
146
 
@@ -170,7 +170,7 @@ requires-python = ">={python_version}"
170
170
  dependencies = []
171
171
 
172
172
  [tool.uv]
173
- require-version=">={uv_version}" # use the latest you have installed
173
+ required-version = ">={uv_version}" # use the latest you have installed
174
174
 
175
175
  [tool.uv.workspace]
176
176
  members = [
@@ -190,8 +190,8 @@ dev = [
190
190
  ]
191
191
  [tool.ruff]
192
192
  line-length = 88
193
- target-version="py314" # Update to match your target Python version
194
- exclude = [**/migrations/**]
193
+ target-version = "py314" # Update to match your target Python version
194
+ exclude = ["**/migrations/**"]
195
195
 
196
196
  [tool.ruff.lint]
197
197
  select = [
@@ -207,17 +207,17 @@ ignore = [
207
207
  "C901" # Complexity, can be handled by refactoring when needed, but not a hard rule
208
208
  ]
209
209
 
210
- [tool.ruff.lint.pre-file-ignores]
211
- "__init"__.py" = [
210
+ [tool.ruff.lint.per-file-ignores]
211
+ "__init__.py" = [
212
212
  "F401", # Allow unused imports in __init__.py for package exports
213
213
  ]
214
- "tests/"=["F841"]
214
+ "tests/**/*.py" = ["F841"]
215
215
 
216
216
  [tool.ruff.format]
217
- quote-style="double"
218
- indent-style="space"
219
- skip-magic-trailing-comma=false
220
- line-ending="lf"
217
+ quote-style = "double"
218
+ indent-style = "space"
219
+ skip-magic-trailing-comma = false
220
+ line-ending = "lf"
221
221
 
222
222
  [tool.pytest.ini_options]
223
223
  pythonpath = [
@@ -230,7 +230,7 @@ testpaths = [
230
230
  ]
231
231
  ```
232
232
 
233
- **For a fast api application (`apps/{my-python-app}/pyproject.toml`)**
233
+ **For a FastAPI application (`apps/{my-python-app}/pyproject.toml`)**
234
234
 
235
235
  ```toml
236
236
  [project]
@@ -245,13 +245,8 @@ dependencies = [
245
245
  # Add other workspace dependencies here e.g. "{my-python-lib}" must be defined in tool.uv.sources
246
246
  ]
247
247
 
248
- [tool.uv.workspace]
249
- members = [
250
- "apps/{my-python-app}"
251
- ]
252
-
253
248
  [tool.uv.sources]
254
- {my-python-lib} = { workspace = true }
249
+ "{my-python-lib}" = { workspace = true }
255
250
 
256
251
  [project.optional-dependencies]
257
252
  dev = [
@@ -263,11 +258,11 @@ dev = [
263
258
  ]
264
259
 
265
260
  [build-system]
266
- requires=["hatchling"]
267
- build-backend="hatchling.build"
261
+ requires = ["hatchling"]
262
+ build-backend = "hatchling.build"
268
263
 
269
- [tool.hatch.build.targets.wheel.force-include]
270
- "src"="{my_python_app}"
264
+ [tool.hatch.build.targets.wheel]
265
+ packages = ["src/{my_python_app}"]
271
266
 
272
267
  [tool.coverage.run]
273
268
  source = ["src"]
@@ -279,8 +274,8 @@ omit = [
279
274
  "*/.venv/*"
280
275
  ]
281
276
 
282
- [tool.coverage.report]
283
- output="coverage.xml"
277
+ [tool.coverage.xml]
278
+ output = "coverage.xml"
284
279
 
285
280
  [tool.coverage.report]
286
281
  exclude_lines = [
@@ -313,10 +308,10 @@ dependencies = []
313
308
  # another-lib = { workspace = true }
314
309
 
315
310
  [build-system]
316
- requires=["hatchling"]
317
- build-backend="hatchling.build"
311
+ requires = ["hatchling"]
312
+ build-backend = "hatchling.build"
318
313
 
319
- [tool.hatch.build.targets.wheel.force-include]
314
+ [tool.hatch.build.targets.wheel]
320
315
  packages = ["src/{my_python_lib}"]
321
316
 
322
317
  # if you have files that are not code like json or yaml you can include them in the wheel with:
@@ -497,7 +492,7 @@ Alembic autogeneration relies on model discovery, make sure the new entity modul
497
492
 
498
493
  ## Adding other languages (e.g. Rust)
499
494
 
500
- The same pattern can be applied to other languages. Here how you would setup a Rust project:
495
+ The same pattern can be applied to other languages. Here is how you would set up a Rust project:
501
496
 
502
497
  ### Step 1: Create Directory Structure
503
498
 
@@ -646,7 +641,7 @@ Example:
646
641
  - Use `.env.example` to document required environment variables without exposing sensitive information
647
642
  - Never commit `.env` files to version control
648
643
  - For python use `python-dotenv` or `pydantic-settings` to load environment variables in your application
649
- - For Node.js ise `dotenv` or Vite's built-in environment variable support
644
+ - For Node.js use `dotenv` or Vite's built-in environment variable support
650
645
 
651
646
  ### 6. Testing
652
647
 
@@ -710,7 +705,7 @@ repos:
710
705
 
711
706
  - id: prettier
712
707
  name: Prettier format
713
- entry: npx prettier --write --loglevel=warn
708
+ entry: npx prettier --write --log-level=warn
714
709
  language: system
715
710
  types_or: [javascript, jsx, ts, tsx, json, css, scss, html, markdown]
716
711
  exclude: \.ipynb$ # Exclude Jupyter notebooks from Prettier formatting
@@ -726,7 +721,7 @@ repos:
726
721
 
727
722
  ### 9. CI / CD Considerations
728
723
 
729
- - Use NX's aggected commands to only test/build changed projects
724
+ - Use NX's affected commands to only test/build changed projects
730
725
  - Cache build between CI runs
731
726
  - Example GitHub Actions:
732
727
 
@@ -815,7 +810,7 @@ uvx ruff format . # Format Python code with Ruff
815
810
  **Problem:**
816
811
 
817
812
  1. The package is not listed in the root `pyproject.toml` under `[tool.uv.workspace].members`
818
- 2. You have not ran `uv sync --all-packages` after adding the package to the workspace configuration
813
+ 2. You have not run `uv sync --all-packages` after adding the package to the workspace configuration
819
814
  3. The workspace dependency was not declared with `{ workspace = true }` in the `[tool.uv.sources]` section of the dependent package's `pyproject.toml`
820
815
 
821
816
  ### Issue: NX can't find Python projects
@@ -838,7 +833,7 @@ uvx ruff format . # Format Python code with Ruff
838
833
 
839
834
  This setup gives you the best of both worlds:
840
835
 
841
- - **NX** for Node.js/Typescript projects with excellent tooling and generators
836
+ - **NX** for Node.js/TypeScript projects with excellent tooling and generators
842
837
  - **UV** for Python projects with modern dependency management and workspace support
843
838
  - A unified monorepo structure that allows you to manage both ecosystems in one place.
844
839
  - Extensible to other languages like Rust with manual setup.
@@ -0,0 +1 @@
1
+ __version__ = "0.1.9"
@@ -73,7 +73,7 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
73
73
  pytest_config = False
74
74
  dev_dependencies_ok = False
75
75
  if tool:
76
- uv_require_version = "require-version" in tool.get("uv", {})
76
+ uv_require_version = "required-version" in tool.get("uv", {})
77
77
  pytest_config = "pytest" in tool and "ini_options" in tool["pytest"]
78
78
 
79
79
  dependency_groups = pyproject_data.get("dependency-groups", {}) if pyproject_data else {}
@@ -42,6 +42,7 @@ def api(
42
42
  ctx.ensure_dir(tests_root)
43
43
 
44
44
  _write_api_pyproject(ctx, api_root, name, app_name, app_name_underscore)
45
+ _write_api_readme(ctx, api_root, name)
45
46
  _write_api_project_json(ctx, api_root, app_name, app_name_underscore)
46
47
  _write_main(ctx, src_root / "main.py", name, domain_underscore)
47
48
  _write_init_file(ctx, src_root / "__init__.py")
@@ -98,6 +99,14 @@ testpaths = ["tests"]
98
99
  ctx.write_file(api_root / "pyproject.toml", content)
99
100
 
100
101
 
102
+ def _write_api_readme(ctx: RunContext, api_root: Path, name: str) -> None:
103
+ content = f"""# {name} API
104
+
105
+ FastAPI application generated by RPR.
106
+ """
107
+ ctx.write_file(api_root / "README.md", content)
108
+
109
+
101
110
  def _write_api_project_json(
102
111
  ctx: RunContext, api_root: Path, app_name: str, app_name_underscore: str
103
112
  ) -> None:
@@ -60,6 +60,7 @@ def domain(
60
60
 
61
61
  # --- project metadata --------------------------------------------------
62
62
  _write_domain_pyproject(ctx, domain_root, name, pkg_name_underscore)
63
+ _write_domain_readme(ctx, domain_root, name)
63
64
  _write_project_json(ctx, domain_root, include_migrations=migrations)
64
65
 
65
66
  # --- __init__.py files -------------------------------------------------
@@ -142,6 +143,14 @@ testpaths = ["tests"]
142
143
  ctx.write_file(domain_root / "pyproject.toml", content)
143
144
 
144
145
 
146
+ def _write_domain_readme(ctx: RunContext, domain_root: Path, name: str) -> None:
147
+ content = f"""# {name} Domain
148
+
149
+ Domain layer package generated by RPR.
150
+ """
151
+ ctx.write_file(domain_root / "README.md", content)
152
+
153
+
145
154
  def _write_project_json(
146
155
  ctx: RunContext, domain_root: Path, *, include_migrations: bool
147
156
  ) -> None:
@@ -12,7 +12,9 @@ from rpr.context import RunContext
12
12
  from rpr.dependencies import (
13
13
  ROOT_STORYBOOK_DEV_DEPENDENCIES,
14
14
  STORYBOOK_DEV_DEPENDENCIES,
15
+ storybook_host_package_name,
15
16
  storybook_package_dependencies,
17
+ ui_package_name,
16
18
  )
17
19
  from rpr.workspace import ensure_npm_workspaces, write_package_json
18
20
 
@@ -185,7 +187,7 @@ def _write_sb_package_json(ctx: RunContext, sb_root: Path, ui_pkg: str) -> None:
185
187
  ctx,
186
188
  sb_root / "package.json",
187
189
  defaults={
188
- "name": "@repo/sb",
190
+ "name": storybook_host_package_name(ui_pkg),
189
191
  "version": "0.1.0",
190
192
  "private": True,
191
193
  "type": "module",
@@ -306,7 +308,8 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
306
308
 
307
309
 
308
310
  def _write_sb_app(ctx: RunContext, src_root: Path, ui_pkg: str) -> None:
309
- content = f"""import {{ uiPackageName }} from "@repo/{ui_pkg}";
311
+ ui_import_name = ui_package_name(ui_pkg)
312
+ content = f"""import {{ uiPackageName }} from "{ui_import_name}";
310
313
 
311
314
  export const storybookHostTitle = "Storybook Host";
312
315
 
@@ -368,7 +371,8 @@ export default config;
368
371
 
369
372
 
370
373
  def _write_sb_preview(ctx: RunContext, path: Path, ui_pkg: str) -> None:
371
- content = """import { appTheme } from "@repo/__UI_PKG__";
374
+ ui_import_name = ui_package_name(ui_pkg)
375
+ content = """import { appTheme } from "__UI_IMPORT__";
372
376
  import { CssBaseline, ThemeProvider } from "@mui/material";
373
377
  import type { Preview } from "@storybook/react";
374
378
  import { Fragment, createElement } from "react";
@@ -398,7 +402,7 @@ const preview: Preview = {
398
402
  };
399
403
 
400
404
  export default preview;
401
- """.replace("__UI_PKG__", ui_pkg)
405
+ """.replace("__UI_IMPORT__", ui_import_name)
402
406
  ctx.write_file(path, content)
403
407
 
404
408
 
@@ -13,7 +13,9 @@ from rpr.dependencies import (
13
13
  UI_LIBRARY_DEPENDENCIES,
14
14
  UI_LIBRARY_DEV_DEPENDENCIES,
15
15
  WEB_APP_DEV_DEPENDENCIES,
16
+ ui_package_name,
16
17
  web_app_dependencies,
18
+ web_package_name,
17
19
  )
18
20
  from rpr.workspace import ensure_npm_workspaces, write_package_json
19
21
 
@@ -140,7 +142,7 @@ def _write_ui_package_json(ctx: RunContext, lib_root: Path, ui_pkg_name: str) ->
140
142
  ctx,
141
143
  lib_root / "package.json",
142
144
  defaults={
143
- "name": f"@repo/{ui_pkg_name}",
145
+ "name": ui_package_name(ui_pkg_name),
144
146
  "version": "0.1.0",
145
147
  "private": True,
146
148
  "main": "src/index.ts",
@@ -259,7 +261,7 @@ def _write_app_package_json(
259
261
  ctx,
260
262
  app_root / "package.json",
261
263
  defaults={
262
- "name": f"@repo/{app_name}",
264
+ "name": web_package_name(app_name),
263
265
  "version": "0.1.0",
264
266
  "private": True,
265
267
  "type": "module",
@@ -370,7 +372,8 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
370
372
 
371
373
  def _write_app_tsx(ctx: RunContext, src: Path, app_name: str, ui_pkg_name: str) -> None:
372
374
  title = app_name.replace("-", " ").title()
373
- content = f"""import {{ AppThemeProvider, uiPackageName }} from "@repo/{ui_pkg_name}";
375
+ ui_import_name = ui_package_name(ui_pkg_name)
376
+ content = f"""import {{ AppThemeProvider, uiPackageName }} from "{ui_import_name}";
374
377
 
375
378
  export const appTitle = "{title}";
376
379
 
@@ -13,7 +13,7 @@ from rich.console import Console
13
13
 
14
14
  from rpr.cli import app
15
15
  from rpr.context import RunContext
16
- from rpr.dependencies import ROOT_NODE_DEV_DEPENDENCIES
16
+ from rpr.dependencies import ROOT_NODE_DEV_DEPENDENCIES, npm_package_name
17
17
  from rpr.generators.base import SyncConfig, load_rules
18
18
  from rpr.generators.claude import generate_claude_rules
19
19
  from rpr.generators.copilot import generate_copilot_rules
@@ -355,7 +355,7 @@ requires-python = ">={python_version}"
355
355
  dependencies = []
356
356
 
357
357
  [tool.uv]
358
- require-version = "{uv_require_version}"
358
+ required-version = "{uv_require_version}"
359
359
 
360
360
  [tool.uv.workspace]
361
361
  members = []
@@ -398,6 +398,18 @@ testpaths = []
398
398
  ctx.update_file(ctx.project_dir / "pyproject.toml", content)
399
399
 
400
400
 
401
+ def _write_root_readme(ctx: RunContext, project_name: str) -> None:
402
+ path = ctx.project_dir / "README.md"
403
+ if path.exists():
404
+ return
405
+
406
+ content = f"""# {project_name}
407
+
408
+ RPR NX + UV monorepo.
409
+ """
410
+ ctx.write_file(path, content)
411
+
412
+
401
413
  def _detect_uv_require_version() -> str:
402
414
  try:
403
415
  result = subprocess.run(
@@ -426,7 +438,7 @@ def _write_root_package_json(ctx: RunContext, project_name: str) -> None:
426
438
  else:
427
439
  package = {}
428
440
 
429
- package.setdefault("name", project_name)
441
+ package["name"] = npm_package_name(project_name)
430
442
  package["private"] = True
431
443
 
432
444
  workspaces = package.get("workspaces", [])
@@ -813,6 +825,7 @@ def init(
813
825
  # ------------------------------------------------------------------
814
826
  _write_nx_json(ctx)
815
827
  _write_root_pyproject(ctx, project_name, python_version)
828
+ _write_root_readme(ctx, project_name)
816
829
  _write_root_package_json(ctx, project_name)
817
830
  _write_tsconfig_base(ctx)
818
831
  _write_root_eslint_config(ctx)
@@ -67,9 +67,35 @@ PYO3_VERSION = MANIFEST["engine"]["pyo3"]["specifier"]
67
67
  MATURIN_SPEC = MANIFEST["engine"]["maturin"]["specifier"]
68
68
 
69
69
 
70
+ def npm_package_name(package_name: str) -> str:
71
+ normalized = package_name.replace("_", "-").lower()
72
+ normalized = re.sub(r"[^a-z0-9._-]+", "-", normalized).strip(".-")
73
+ return normalized or "package"
74
+
75
+
76
+ def scoped_package_name(scope_name: str, package_name: str) -> str:
77
+ return f"@{npm_package_name(scope_name)}/{npm_package_name(package_name)}"
78
+
79
+
80
+ def _strip_suffix(package_name: str, suffix: str) -> str:
81
+ return package_name[: -len(suffix)] if package_name.endswith(suffix) else package_name
82
+
83
+
84
+ def ui_package_name(ui_pkg_name: str) -> str:
85
+ return scoped_package_name(_strip_suffix(ui_pkg_name, "-ui"), "ui")
86
+
87
+
88
+ def web_package_name(app_name: str) -> str:
89
+ return scoped_package_name(_strip_suffix(app_name, "-web"), "web")
90
+
91
+
92
+ def storybook_host_package_name(ui_pkg_name: str) -> str:
93
+ return scoped_package_name(_strip_suffix(ui_pkg_name, "-ui"), "sb")
94
+
95
+
70
96
  def web_app_dependencies(ui_pkg_name: str) -> dict[str, str]:
71
97
  return {
72
- f"@repo/{ui_pkg_name}": "workspace:*",
98
+ ui_package_name(ui_pkg_name): f"file:../../packages/node/{ui_pkg_name}",
73
99
  "react": UI_LIBRARY_DEPENDENCIES["react"],
74
100
  "react-dom": UI_LIBRARY_DEPENDENCIES["react-dom"],
75
101
  }
@@ -77,7 +103,7 @@ def web_app_dependencies(ui_pkg_name: str) -> dict[str, str]:
77
103
 
78
104
  def storybook_package_dependencies(ui_pkg_name: str) -> dict[str, str]:
79
105
  return {
80
- f"@repo/{ui_pkg_name}": "workspace:*",
106
+ ui_package_name(ui_pkg_name): f"file:../{ui_pkg_name}",
81
107
  **STORYBOOK_DEPENDENCIES,
82
108
  }
83
109
 
@@ -11,6 +11,7 @@ Use React for UI composition, TanStack Query for server-state workflows, TanStac
11
11
 
12
12
  - Use functional components.
13
13
  - Extract reusable behavior into hooks instead of duplicating component logic.
14
+ - Import the generated shared UI package through the app-scoped package name `@{name}/ui`, such as `@testapp/ui`, not `@repo/{name}-ui`.
14
15
  - Prefer a shared base API service at `src/services/base/api.service.ts` when the UI package needs centralized fetch behavior.
15
16
  - Prefer a shared `useStateNavigation` hook at `src/hooks/useStateNavigation.ts` when UI state should persist in the URL.
16
17
  - Reuse existing components, hooks, and service patterns before introducing a new abstraction.
@@ -96,7 +97,7 @@ export const SomeContainer = styled(Box)`
96
97
 
97
98
  - Type every API payload and mutation input.
98
99
  - Prefer `type` aliases for DTO-shaped data, `interface` for extendable service contracts, and classes only when the UI genuinely needs behavior.
99
- - For components with children, prefer `React.PropsWithChildren<T>` over manually re-declaring a `children` field.
100
+ - For components with children, prefer `React.PropsWithChildren<T>` over manually redeclaring a `children` field.
100
101
 
101
102
  ## Components
102
103
 
@@ -45,6 +45,9 @@ Use this guidance when validating or changing the monorepo setup against the RPR
45
45
  - Generate React app and library projects in a way that preserves the expected Nx command surface.
46
46
  - The web app should expose at least `serve`, `build`, `lint`, `test`, and `typecheck` when those capabilities exist in the generated project.
47
47
  - The UI library should expose at least `build`, `lint`, `test`, and `typecheck`.
48
+ - Use app-scoped Node package names: `packages/node/{name}-ui` publishes as `@{name}/ui`, `apps/{name}-web` publishes as `@{name}/web`, and Storybook publishes as `@{name}/sb`.
49
+ - Import the shared UI package through `@{name}/ui`, for example `import { AppThemeProvider } from "@testapp/ui"` for a `TestApp` workspace.
50
+ - Link local Node workspace packages with relative `file:` dependency specs instead of `workspace:*`, because npm must be able to install the generated workspace without unsupported protocol errors.
48
51
  - Keep Storybook as a dedicated host project at `packages/node/sb`; do not silently repurpose the UI library as the Storybook project.
49
52
 
50
53
  ## Python Expectations
@@ -81,6 +84,7 @@ npx nx run domain:migrate -- downgrade -1
81
84
  - Project roots and import package names follow the kebab-case and snake_case rules.
82
85
  - Python projects have both `src/` and `tests/`.
83
86
  - The domain import package remains `src/{name_underscore}_domain`.
87
+ - Node imports use app-scoped package names such as `@{name}/ui`, not stale `@repo/*` aliases.
84
88
  - Storybook remains hosted in `packages/node/sb`.
85
89
  - Workspace members and workspace dependency sources are complete.
86
90
  - Generated instructions, checks, and scaffolds refer to the current contract rather than stale paths.
@@ -12,6 +12,12 @@ console = Console()
12
12
  DEFAULT_NPM_WORKSPACES = ["apps/*", "packages/node/*"]
13
13
 
14
14
 
15
+ def _npm_package_name(package_name: str) -> str:
16
+ normalized = package_name.replace("_", "-").lower()
17
+ normalized = re.sub(r"[^a-z0-9._-]+", "-", normalized).strip(".-")
18
+ return normalized or "package"
19
+
20
+
15
21
  def add_workspace_member(ctx: RunContext, member: str) -> None:
16
22
  """Add a UV workspace member to the root pyproject.toml."""
17
23
  pyproject_path = ctx.project_dir / "pyproject.toml"
@@ -76,7 +82,10 @@ def write_package_json(
76
82
  package = {}
77
83
 
78
84
  for key, value in (defaults or {}).items():
79
- package.setdefault(key, value)
85
+ if key == "name":
86
+ package[key] = value
87
+ else:
88
+ package.setdefault(key, value)
80
89
 
81
90
  for field_name, additions in (
82
91
  ("dependencies", dependencies or {}),
@@ -87,7 +96,23 @@ def write_package_json(
87
96
  field = {}
88
97
  package[field_name] = field
89
98
  for dep_name, version in additions.items():
90
- field.setdefault(dep_name, version)
99
+ if version.startswith("file:"):
100
+ for existing_name, existing_value in list(field.items()):
101
+ if (
102
+ existing_name != dep_name
103
+ and isinstance(existing_value, str)
104
+ and existing_value.startswith("workspace:")
105
+ ):
106
+ field.pop(existing_name)
107
+ existing_version = field.get(dep_name)
108
+ if existing_version is None:
109
+ field[dep_name] = version
110
+ elif (
111
+ isinstance(existing_version, str)
112
+ and existing_version.startswith("workspace:")
113
+ and version.startswith("file:")
114
+ ):
115
+ field[dep_name] = version
91
116
 
92
117
  content = json.dumps(package, indent=2) + "\n"
93
118
  if existed:
@@ -111,7 +136,7 @@ def ensure_npm_workspaces(ctx: RunContext, *, package_name: str | None = None) -
111
136
  package = {}
112
137
 
113
138
  if package_name:
114
- package.setdefault("name", package_name)
139
+ package["name"] = _npm_package_name(package_name)
115
140
  package["private"] = True
116
141
 
117
142
  workspaces = package.get("workspaces", [])
@@ -39,7 +39,7 @@ requires-python = ">=3.12"
39
39
  dependencies = []
40
40
 
41
41
  [tool.uv]
42
- require-version = ">=0.8.0"
42
+ required-version = ">=0.8.0"
43
43
 
44
44
  [tool.uv.workspace]
45
45
  members = ["packages/python/domain", "apps/my-app-api"]
@@ -205,7 +205,7 @@ def _create_packages(base: Path) -> None:
205
205
  json.dumps(
206
206
  {
207
207
  "dependencies": {
208
- "@repo/my-app-ui": web_app_dependencies("my-app-ui")["@repo/my-app-ui"],
208
+ "@my-app/ui": web_app_dependencies("my-app-ui")["@my-app/ui"],
209
209
  **STORYBOOK_DEPENDENCIES,
210
210
  },
211
211
  "devDependencies": STORYBOOK_DEV_DEPENDENCIES,
@@ -59,6 +59,7 @@ def test_generate_api_scaffolds_src_layout_tests_and_build_target(monkeypatch):
59
59
  assert (src_root / "__init__.py").exists()
60
60
  assert (src_root / "routes" / "__init__.py").exists()
61
61
  assert (tests_root / "test_health.py").exists()
62
+ assert (api_root / "README.md").read_text().startswith("# my-app API")
62
63
 
63
64
  pyproject = (api_root / "pyproject.toml").read_text()
64
65
  project = json.loads((api_root / "project.json").read_text())
@@ -67,6 +68,7 @@ def test_generate_api_scaffolds_src_layout_tests_and_build_target(monkeypatch):
67
68
  root_pyproject = Path("pyproject.toml").read_text()
68
69
 
69
70
  assert 'packages = ["src/my_app_api"]' in pyproject
71
+ assert 'readme = "README.md"' in pyproject
70
72
  assert '[tool.pytest.ini_options]' in pyproject
71
73
  assert 'testpaths = ["tests"]' in pyproject
72
74
  assert project["name"] == "my-app-api"
@@ -68,6 +68,7 @@ def test_generate_domain_scaffolds_config_and_metadata(monkeypatch):
68
68
  assert (src_root / "entities" / "base.py").exists()
69
69
  assert (src_root / "repos" / "base.py").exists()
70
70
  assert (domain_root / "tests" / "test_package.py").exists()
71
+ assert (domain_root / "README.md").read_text().startswith("# my-app Domain")
71
72
 
72
73
  for package_dir in [
73
74
  "",
@@ -125,6 +126,7 @@ def test_generate_domain_scaffolds_config_and_metadata(monkeypatch):
125
126
  )
126
127
  assert "migrate" not in project["targets"]
127
128
  assert '[tool.pytest.ini_options]' in (domain_root / "pyproject.toml").read_text()
129
+ assert 'readme = "README.md"' in (domain_root / "pyproject.toml").read_text()
128
130
  assert 'members = ["packages/python/domain"]' in root_pyproject
129
131
 
130
132
  assert recorded_calls[0][0] == ["uv", "sync"]