rpr-cli 0.1.26__tar.gz → 0.1.28__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 (273) hide show
  1. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/PKG-INFO +3 -2
  2. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/README.md +2 -1
  3. rpr_cli-0.1.28/src/rpr/__init__.py +1 -0
  4. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/instructions.py +1 -0
  5. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/add.py +156 -14
  6. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/ui.py +10 -2
  7. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/init.py +12 -5
  8. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/README.md +349 -0
  9. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/client/index.ts +1 -0
  10. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/client/types.ts +45 -0
  11. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.spec.tsx +329 -0
  12. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.tsx +358 -0
  13. rpr_cli-0.1.28/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
  14. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.spec.ts +60 -0
  15. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.ts +128 -0
  16. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/index.ts +6 -0
  17. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatComposerMentionTokens.tsx +139 -0
  18. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatSuggestionsPopover.tsx +125 -0
  19. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/LocalFileSuggestionAction.tsx +100 -0
  20. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/index.ts +7 -0
  21. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.spec.ts +281 -0
  22. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.ts +1003 -0
  23. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.spec.ts +56 -0
  24. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.ts +58 -0
  25. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/types.ts +123 -0
  26. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/useChatSuggestions.ts +339 -0
  27. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/types.ts +114 -0
  28. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/useChatComposer.ts +169 -0
  29. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.spec.tsx +104 -0
  30. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.ts +212 -0
  31. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/index.ts +5 -0
  32. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/testing/createMockChatStreamClient.ts +91 -0
  33. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/testing/createMockSuggestionProvider.ts +99 -0
  34. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/testing/index.ts +2 -0
  35. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessage.tsx +235 -0
  36. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.spec.tsx +163 -0
  37. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.tsx +670 -0
  38. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.spec.tsx +365 -0
  39. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.tsx +93 -0
  40. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/README.md +111 -0
  41. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/contentFormat.ts +30 -0
  42. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/index.ts +6 -0
  43. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/streaming.ts +174 -0
  44. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/types.ts +135 -0
  45. rpr_cli-0.1.26/src/rpr/scaffolds/js_special_files/virtual-component.spec.md → rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.spec.tsx +39 -60
  46. rpr_cli-0.1.26/src/rpr/scaffolds/js_special_files/virtual-component.md → rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.tsx +12 -28
  47. rpr_cli-0.1.26/src/rpr/scaffolds/js_special_files/virtual-component-list.spec.md → rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.spec.tsx +58 -85
  48. rpr_cli-0.1.26/src/rpr/scaffolds/js_special_files/virtual-component-list.md → rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.tsx +32 -63
  49. rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/virtual-list/index.ts +1 -0
  50. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/templates/registry.py +123 -51
  51. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_add.py +201 -3
  52. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_check.py +4 -0
  53. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_init.py +152 -0
  54. rpr_cli-0.1.26/src/rpr/__init__.py +0 -1
  55. rpr_cli-0.1.26/src/rpr/scaffolds/js_special_files/virtual-list-index.md +0 -9
  56. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/.github/agents/story.agent.md +0 -0
  57. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/.github/workflows/publish-pypi.yml +0 -0
  58. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/.gitignore +0 -0
  59. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/CLAUDE.md +0 -0
  60. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/GEMINI.md +0 -0
  61. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/LICENSE +0 -0
  62. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/all.instructions.md +0 -0
  63. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/api.instructions.md +0 -0
  64. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/domain.instructions.md +0 -0
  65. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/frontend.instructions.md +0 -0
  66. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/rust-engine.instructions.md +0 -0
  67. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/setup-guide.instructions.md +0 -0
  68. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/tooling-setup.instructions.md +0 -0
  69. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/tooling.instructions.md +0 -0
  70. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/README.md +0 -0
  71. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/api/main.py +0 -0
  72. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/domain/base-repo.md +0 -0
  73. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/domain/base_entity.md +0 -0
  74. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/api.service.ts +0 -0
  75. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/useStateNavigation.ts +0 -0
  76. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponent.spec.tsx +0 -0
  77. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponent.tsx +0 -0
  78. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.spec.tsx +0 -0
  79. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.tsx +0 -0
  80. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/index.ts +0 -0
  81. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/changelogs/mui_v9.txt +0 -0
  82. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/code-map.md +0 -0
  83. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/nx_uv_setup.md +0 -0
  84. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/patch_output.py +0 -0
  85. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/plan-languageAwareTemplateAdd.prompt.md +0 -0
  86. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/pyproject.toml +0 -0
  87. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/Cargo.lock +0 -0
  88. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/Cargo.toml +0 -0
  89. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/pyproject.toml +0 -0
  90. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/rpr_parser.pyi +0 -0
  91. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/config/container.rs +0 -0
  92. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/config/mod.rs +0 -0
  93. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/config/settings.rs +0 -0
  94. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/graph.rs +0 -0
  95. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/lib.rs +0 -0
  96. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/models/dtos/mod.rs +0 -0
  97. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/models/entities/mod.rs +0 -0
  98. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/models/entities/users.rs +0 -0
  99. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/models/mod.rs +0 -0
  100. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/parse.rs +0 -0
  101. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/repos/base.rs +0 -0
  102. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/repos/mod.rs +0 -0
  103. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/repos/users.rs +0 -0
  104. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/resolve.rs +0 -0
  105. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/walker.rs +0 -0
  106. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/uv.lock +0 -0
  107. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/special_files.md +0 -0
  108. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/__init__.py +0 -0
  109. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/approval.py +0 -0
  110. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/bootstrap.py +0 -0
  111. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/client.py +0 -0
  112. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/control.py +0 -0
  113. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/mock.py +0 -0
  114. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/runtime.py +0 -0
  115. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/session.py +0 -0
  116. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/__init__.py +0 -0
  117. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/base.py +0 -0
  118. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/mutating.py +0 -0
  119. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/readonly.py +0 -0
  120. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/registry.py +0 -0
  121. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/__init__.py +0 -0
  122. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/catalog.py +0 -0
  123. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/chat_service.py +0 -0
  124. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/checks.py +0 -0
  125. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/cli_adapter.py +0 -0
  126. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/completer.py +0 -0
  127. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/conversation_service.py +0 -0
  128. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/prompt_service.py +0 -0
  129. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/selector.py +0 -0
  130. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/shell.py +0 -0
  131. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/__init__.py +0 -0
  132. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/base.py +0 -0
  133. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/packages.py +0 -0
  134. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/workspace.py +0 -0
  135. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/cli.py +0 -0
  136. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/__init__.py +0 -0
  137. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/chat.py +0 -0
  138. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/check.py +0 -0
  139. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/__init__.py +0 -0
  140. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/api.py +0 -0
  141. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/domain.py +0 -0
  142. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/engine.py +0 -0
  143. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/storybook.py +0 -0
  144. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/map.py +0 -0
  145. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/refresh.py +0 -0
  146. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/settings.py +0 -0
  147. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/sync.py +0 -0
  148. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/context.py +0 -0
  149. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/dependencies.py +0 -0
  150. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/dependency_manifest_data.py +0 -0
  151. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/__init__.py +0 -0
  152. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/base.py +0 -0
  153. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/claude.py +0 -0
  154. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/copilot.py +0 -0
  155. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/cursor.py +0 -0
  156. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/gemini.py +0 -0
  157. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/github.py +0 -0
  158. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/manifest_refresh.py +0 -0
  159. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/__init__.py +0 -0
  160. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/architecture.py +0 -0
  161. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/chains.py +0 -0
  162. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/classifier.py +0 -0
  163. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/coverage.py +0 -0
  164. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/dependencies.py +0 -0
  165. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/extractor.py +0 -0
  166. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/graph.py +0 -0
  167. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/output.py +0 -0
  168. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/responsibility.py +0 -0
  169. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/topology.py +0 -0
  170. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/walker.py +0 -0
  171. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/domain/base_entity.md +0 -0
  172. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/domain/base_repo.md +0 -0
  173. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/domain/container.md +0 -0
  174. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/domain/settings.md +0 -0
  175. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/all.instructions.md +0 -0
  176. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/api.instructions.md +0 -0
  177. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/domain.instructions.md +0 -0
  178. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/frontend.instructions.md +0 -0
  179. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/rust-engine.instructions.md +0 -0
  180. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +0 -0
  181. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +0 -0
  182. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -0
  183. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
  184. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
  185. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/js_special_files/sticky-navigation.spec.md +0 -0
  186. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/js_special_files/vitest-browser-config.md +0 -0
  187. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/domain_container.md +0 -0
  188. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/domain_settings.md +0 -0
  189. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
  190. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/encrypted_column.md +0 -0
  191. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
  192. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
  193. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/templates/__init__.py +0 -0
  194. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/__init__.py +0 -0
  195. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/console.py +0 -0
  196. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/markdown.py +0 -0
  197. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/prompt_session.py +0 -0
  198. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/renderers.py +0 -0
  199. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/theme.py +0 -0
  200. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/workspace.py +0 -0
  201. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/README.md +0 -0
  202. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/00-bootstrap-cli.md +0 -0
  203. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/01-rpr-init.md +0 -0
  204. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/02-rpr-generate-domain.md +0 -0
  205. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/03-rpr-generate-api.md +0 -0
  206. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/04-rpr-generate-ui.md +0 -0
  207. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/05-rpr-generate-engine.md +0 -0
  208. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/06-rpr-generate-storybook.md +0 -0
  209. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/07-rpr-sync-rules.md +0 -0
  210. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/08-rpr-add-template.md +0 -0
  211. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/09-rpr-check.md +0 -0
  212. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/10-rpr-domain-config.md +0 -0
  213. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/18-rpr-terminal-ui-foundation.md +0 -0
  214. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/19-rpr-markdown-rendering.md +0 -0
  215. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/20-rpr-chat-repl.md +0 -0
  216. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/21-rpr-agent-tool-loop.md +0 -0
  217. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/22-rpr-chat-tui.md +0 -0
  218. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/23-rpr-chat-unified-command-shell.md +0 -0
  219. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/24-rpr-async-chat-runtime-and-services.md +0 -0
  220. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/25-rpr-prompt-service-and-conversation-lifecycle.md +0 -0
  221. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/26-rpr-shared-command-catalog.md +0 -0
  222. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/27-rpr-slash-command-selection-panel.md +0 -0
  223. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/28-rpr-chat-cancellable-and-multiline-input.md +0 -0
  224. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/29-rpr-file-context-selection.md +0 -0
  225. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/11-rpr-map-command.md +0 -0
  226. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/12-rpr-map-file-walker.md +0 -0
  227. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/13-rpr-map-rust-engine.md +0 -0
  228. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/13a-rpr-map-gitignore.md +0 -0
  229. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/14-rpr-map-graph-builder.md +0 -0
  230. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/15-rpr-map-analysis-bridge.md +0 -0
  231. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/16-rpr-map-layer-classifier.md +0 -0
  232. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17-rpr-map-output.md +0 -0
  233. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17a-rpr-map-directory-topology.md +0 -0
  234. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17b-rpr-map-architecture-assessment.md +0 -0
  235. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17c-rpr-map-representative-chains.md +0 -0
  236. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17d-rpr-map-multi-resolution-output.md +0 -0
  237. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/map/30-rpr-map-directory-view-and-cycle-detection.md +0 -0
  238. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/map/31-rpr-map-coupling-hotspots-and-verdict-reasoning.md +0 -0
  239. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/map/32-rpr-map-dependencies-responsibilities-and-test-coverage.md +0 -0
  240. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/__init__.py +0 -0
  241. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_architecture.py +0 -0
  242. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_architecture_unwrapped.py +0 -0
  243. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_catalog.py +0 -0
  244. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_chat.py +0 -0
  245. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_chat_service.py +0 -0
  246. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_completer.py +0 -0
  247. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_context.py +0 -0
  248. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_api.py +0 -0
  249. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_domain.py +0 -0
  250. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_engine.py +0 -0
  251. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_storybook.py +0 -0
  252. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_ui.py +0 -0
  253. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map.py +0 -0
  254. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_chains.py +0 -0
  255. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_classifier.py +0 -0
  256. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_coverage.py +0 -0
  257. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_dependencies.py +0 -0
  258. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_extractor.py +0 -0
  259. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_graph.py +0 -0
  260. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_output.py +0 -0
  261. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_responsibility.py +0 -0
  262. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_topology.py +0 -0
  263. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_walker.py +0 -0
  264. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_packaging.py +0 -0
  265. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_prompt_session.py +0 -0
  266. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_refresh.py +0 -0
  267. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_rpr_parser_stub.py +0 -0
  268. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_selector.py +0 -0
  269. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_settings.py +0 -0
  270. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_sync.py +0 -0
  271. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_ui.py +0 -0
  272. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/update_output.py +0 -0
  273. {rpr_cli-0.1.26 → rpr_cli-0.1.28}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rpr-cli
3
- Version: 0.1.26
3
+ Version: 0.1.28
4
4
  Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -72,14 +72,15 @@ rpr generate storybook # Add Storybook for UI component development
72
72
  By default, `rpr init` scaffolds the root workspace and AI instructions only. To create project components during initialization, repeat `--scaffold` or pass a comma-separated list:
73
73
 
74
74
  ```bash
75
+ rpr init todo-list --scaffold common
75
76
  rpr init todo-list --scaffold domain
76
77
  rpr init todo-list --scaffold api --domain-migrations
77
78
  rpr init todo-list --scaffold api --scaffold web --domain-migrations
78
- rpr init todo-list --scaffold instructions, domain, api, ui, web, storybook
79
79
  ```
80
80
 
81
81
  Available scaffolds are:
82
82
 
83
+ - `common`: Alias for `instructions`, `domain`, `api`, `ui`, `web`, and `storybook`; excludes `engine`.
83
84
  - `instructions`: AI instruction files for Cursor, Copilot, Claude Code, and Gemini.
84
85
  - `domain`: Python DDD package at `packages/python/domain`.
85
86
  - `api`: FastAPI app at `apps/<name>-api`; also scaffolds `domain`.
@@ -57,14 +57,15 @@ rpr generate storybook # Add Storybook for UI component development
57
57
  By default, `rpr init` scaffolds the root workspace and AI instructions only. To create project components during initialization, repeat `--scaffold` or pass a comma-separated list:
58
58
 
59
59
  ```bash
60
+ rpr init todo-list --scaffold common
60
61
  rpr init todo-list --scaffold domain
61
62
  rpr init todo-list --scaffold api --domain-migrations
62
63
  rpr init todo-list --scaffold api --scaffold web --domain-migrations
63
- rpr init todo-list --scaffold instructions, domain, api, ui, web, storybook
64
64
  ```
65
65
 
66
66
  Available scaffolds are:
67
67
 
68
+ - `common`: Alias for `instructions`, `domain`, `api`, `ui`, `web`, and `storybook`; excludes `engine`.
68
69
  - `instructions`: AI instruction files for Cursor, Copilot, Claude Code, and Gemini.
69
70
  - `domain`: Python DDD package at `packages/python/domain`.
70
71
  - `api`: FastAPI app at `apps/<name>-api`; also scaffolds `domain`.
@@ -0,0 +1 @@
1
+ __version__ = "0.1.28"
@@ -82,6 +82,7 @@ def check_instructions(
82
82
  ("fetch_service", "has_ui"),
83
83
  ("sticky_navigation", "has_ui"),
84
84
  ("virtual_list", "has_ui"),
85
+ ("chat", "has_ui"),
85
86
  ]
86
87
 
87
88
  for tid, prereq in template_ids:
@@ -62,6 +62,13 @@ def template(
62
62
  "--include-tests", help="Include unit-test companions when available."
63
63
  ),
64
64
  ] = False,
65
+ install: Annotated[
66
+ bool | None,
67
+ typer.Option(
68
+ "--install/--no-install",
69
+ help="Install npm dependencies after writing files (default depends on template).",
70
+ ),
71
+ ] = None,
65
72
  output_dir: Annotated[
66
73
  str | None,
67
74
  typer.Option(
@@ -115,24 +122,43 @@ def template(
115
122
  )
116
123
  raise typer.Exit(1)
117
124
 
118
- selected_files = list(entry.files)
119
- if include_tests:
120
- selected_files.extend(entry.test_files)
121
- selected_files.extend(entry.config_files)
122
-
123
- rendered_files = []
124
- for template_file in selected_files:
125
- source_file = source_dir / template_file.source_subdir / template_file.source_filename
126
- code = _render_template_file(source_file, template_file, variables)
127
- target_path = _resolve_target_path(ctx, template_file, variables, output_dir)
128
- rendered_files.append((template_file, target_path, code))
125
+ ordered_entries: list[tuple[TemplateEntry, bool]] = []
126
+ for required_id in entry.requires:
127
+ required_entry = TEMPLATES.get(required_id)
128
+ if required_entry is not None:
129
+ ordered_entries.append((required_entry, True))
130
+ ordered_entries.append((entry, False))
131
+
132
+ seen_targets: set[Path] = set()
133
+ rendered_files: list[tuple[TemplateFile, Path, str, bool]] = []
134
+ for current_entry, reuse_mode in ordered_entries:
135
+ files_for_entry = list(current_entry.files)
136
+ if include_tests:
137
+ files_for_entry.extend(current_entry.test_files)
138
+ files_for_entry.extend(current_entry.config_files)
139
+ for template_file in files_for_entry:
140
+ target_path = _resolve_target_path(
141
+ ctx, template_file, variables, output_dir
142
+ )
143
+ if target_path in seen_targets:
144
+ continue
145
+ seen_targets.add(target_path)
146
+ source_file = (
147
+ source_dir / template_file.source_subdir / template_file.source_filename
148
+ )
149
+ code = _render_template_file(source_file, template_file, variables)
150
+ rendered_files.append((template_file, target_path, code, reuse_mode))
129
151
 
130
152
  skipped_config_paths: list[Path] = []
153
+ reused_paths: list[Path] = []
131
154
  writable_files = []
132
- for template_file, target_path, code in rendered_files:
155
+ for template_file, target_path, code, reuse_mode in rendered_files:
133
156
  if dry_run or not target_path.exists() or force:
134
157
  writable_files.append((template_file, target_path, code))
135
158
  continue
159
+ if reuse_mode:
160
+ reused_paths.append(target_path)
161
+ continue
136
162
  if template_file.role == "config":
137
163
  console.print(
138
164
  f"[bold yellow]Warning:[/] Config already exists, leaving it unchanged: {target_path}"
@@ -150,11 +176,24 @@ def template(
150
176
  for _, target_path, code in writable_files:
151
177
  ctx.write_file(target_path, code)
152
178
 
179
+ _update_root_index(
180
+ ctx,
181
+ [target_path for _, target_path, _ in writable_files],
182
+ variables,
183
+ output_dir,
184
+ )
185
+
153
186
  _print_include_test_notes(entry, include_tests, skipped_config_paths)
154
187
 
188
+ _maybe_install_dependencies(ctx, ordered_entries, include_tests, install)
189
+
155
190
  console.print("\n[bold green]Done![/] Template files written:")
156
191
  for _, target_path, _ in writable_files:
157
192
  console.print(f" {target_path}")
193
+ if reused_paths:
194
+ console.print("\n[bold]Reused existing files:[/]")
195
+ for target_path in reused_paths:
196
+ console.print(f" {target_path}")
158
197
  if skipped_config_paths:
159
198
  console.print("\n[bold yellow]Skipped existing config files:[/]")
160
199
  for target_path in skipped_config_paths:
@@ -167,7 +206,9 @@ def _resolve_template_args(
167
206
  if lang_or_template_id in KNOWN_TEMPLATE_LANGS:
168
207
  return lang_or_template_id, template_id
169
208
  if template_id is not None:
170
- console.print(f"[bold red]Error:[/] Unknown template language: {lang_or_template_id}")
209
+ console.print(
210
+ f"[bold red]Error:[/] Unknown template language: {lang_or_template_id}"
211
+ )
171
212
  console.print("Supported languages: node, python")
172
213
  raise typer.Exit(1)
173
214
  return None, lang_or_template_id
@@ -233,6 +274,11 @@ def _render_template_file(
233
274
  console.print(f"[bold red]Error:[/] Source file not found: {source_file}")
234
275
  raise typer.Exit(1)
235
276
 
277
+ if template_file.raw:
278
+ code = source_file.read_text()
279
+ code = _interpolate_code(code, variables)
280
+ return _apply_raw_transforms(code, template_file, variables)
281
+
236
282
  markdown = source_file.read_text()
237
283
  code_blocks = _extract_code_blocks(markdown, template_file.language)
238
284
 
@@ -244,6 +290,32 @@ def _render_template_file(
244
290
  return _interpolate_code(code, variables)
245
291
 
246
292
 
293
+ def _apply_raw_transforms(
294
+ code: str, template_file: TemplateFile, variables: dict[str, str]
295
+ ) -> str:
296
+ """Rewrite project-specific paths/imports in raw chat scaffold files."""
297
+ subdir = template_file.source_subdir
298
+ filename = template_file.source_filename
299
+ name_kebab = variables.get("name_kebab", "")
300
+
301
+ # The chat thread reuses the sibling standalone virtual-list component.
302
+ if subdir.endswith("chat/thread") and filename == "ChatThread.tsx":
303
+ code = code.replace("from '../virtual-list'", "from '../../virtual-list'")
304
+
305
+ # The chat barrel must not re-export the reused virtual-list package.
306
+ if subdir.endswith("js_special_files/chat") and filename == "index.ts":
307
+ code = code.replace("export * from './virtual-list';\n", "")
308
+
309
+ # Documentation references to the originating project should be templated.
310
+ if filename.endswith(".md"):
311
+ code = code.replace("packages/huddle-ui", f"packages/node/{name_kebab}-ui")
312
+ code = code.replace("packages/sb/", f"packages/node/{name_kebab}-sb/")
313
+ code = code.replace("@huddle/ui", f"@{name_kebab}/ui")
314
+ code = code.replace("huddle-ui", f"{name_kebab}-ui")
315
+
316
+ return code
317
+
318
+
247
319
  def _interpolate_code(code: str, variables: dict[str, str]) -> str:
248
320
  code = interpolate(code, variables)
249
321
  name_val = variables.get("name", "")
@@ -255,6 +327,76 @@ def _interpolate_code(code: str, variables: dict[str, str]) -> str:
255
327
  return code
256
328
 
257
329
 
330
+ def _update_root_index(
331
+ ctx: RunContext,
332
+ written_targets: list[Path],
333
+ variables: dict[str, str],
334
+ output_dir: str | None,
335
+ ) -> None:
336
+ """Add component barrel exports to the UI package root index when present."""
337
+ if output_dir:
338
+ return
339
+
340
+ component_names: list[str] = []
341
+ for target in written_targets:
342
+ parts = target.parts
343
+ if "components" in parts:
344
+ index = parts.index("components")
345
+ if index + 1 < len(parts):
346
+ name = parts[index + 1]
347
+ if name not in component_names:
348
+ component_names.append(name)
349
+ if not component_names:
350
+ return
351
+
352
+ index_rel = interpolate("packages/node/{name_kebab}-ui/src/index.ts", variables)
353
+ index_path = ctx.project_dir / index_rel
354
+ if not index_path.exists():
355
+ return
356
+
357
+ existing = index_path.read_text()
358
+ additions = [
359
+ f'export * from "./components/{name}";'
360
+ for name in sorted(component_names)
361
+ if f'"./components/{name}"' not in existing
362
+ ]
363
+ if not additions:
364
+ return
365
+
366
+ updated = existing.rstrip("\n") + "\n" + "\n".join(additions) + "\n"
367
+ ctx.write_file(index_path, updated)
368
+
369
+
370
+ def _maybe_install_dependencies(
371
+ ctx: RunContext,
372
+ ordered_entries: list[tuple[TemplateEntry, bool]],
373
+ include_tests: bool,
374
+ install: bool | None,
375
+ ) -> None:
376
+ install_by_default = any(entry.install_by_default for entry, _ in ordered_entries)
377
+ should_install = install_by_default if install is None else install
378
+ if not should_install:
379
+ return
380
+
381
+ runtime: list[str] = []
382
+ dev: list[str] = []
383
+ for entry, _ in ordered_entries:
384
+ for dep in entry.dependencies:
385
+ if dep not in runtime:
386
+ runtime.append(dep)
387
+ if include_tests:
388
+ for dep in entry.dev_dependencies:
389
+ if dep not in dev:
390
+ dev.append(dep)
391
+
392
+ if runtime:
393
+ console.print("\n[bold]Installing runtime dependencies...[/]")
394
+ ctx.run_command(["npm", "i", *runtime], cwd=ctx.project_dir)
395
+ if dev:
396
+ console.print("\n[bold]Installing dev dependencies...[/]")
397
+ ctx.run_command(["npm", "i", "-D", *dev], cwd=ctx.project_dir)
398
+
399
+
258
400
  def _resolve_target_path(
259
401
  ctx: RunContext,
260
402
  template_file: TemplateFile,
@@ -295,4 +437,4 @@ def _find_source_dir(config: SyncConfig) -> Path | None:
295
437
  if common.exists():
296
438
  return common
297
439
 
298
- return None
440
+ return None
@@ -102,9 +102,17 @@ def ui(
102
102
  if include_library:
103
103
  console.print(" Optional templates: rpr add template node fetch_service")
104
104
  console.print(" rpr add template node sticky_navigation")
105
- console.print(" rpr add template node sticky_navigation --include-tests")
105
+ console.print(
106
+ " rpr add template node sticky_navigation --include-tests"
107
+ )
106
108
  console.print(" rpr add template node virtual_list")
107
- console.print(" rpr add template node virtual_list --include-tests")
109
+ console.print(
110
+ " rpr add template node virtual_list --include-tests"
111
+ )
112
+ console.print(" rpr add template node chat")
113
+ console.print(
114
+ " rpr add template node chat --include-tests"
115
+ )
108
116
 
109
117
 
110
118
  def _scaffold_ui_library(ctx: RunContext, ui_pkg_name: str) -> None:
@@ -71,6 +71,10 @@ _SCAFFOLD_DEPENDENCIES: dict[ScaffoldName, tuple[ScaffoldName, ...]] = {
71
71
  "storybook": ("ui",),
72
72
  "engine": (),
73
73
  }
74
+ _SCAFFOLD_ALIASES: dict[str, tuple[ScaffoldName, ...]] = {
75
+ "common": ("instructions", "domain", "api", "ui", "web", "storybook"),
76
+ }
77
+ _ALLOWED_SCAFFOLD_VALUES = [*_SCAFFOLD_DEPENDENCIES, *_SCAFFOLD_ALIASES]
74
78
 
75
79
 
76
80
  # ---------------------------------------------------------------------------
@@ -118,12 +122,14 @@ def _derive_variables(project_name: str) -> dict[str, str]:
118
122
  }
119
123
 
120
124
 
121
- def _normalize_scaffold_name(value: str) -> ScaffoldName:
125
+ def _expand_scaffold_value(value: str) -> tuple[ScaffoldName, ...]:
122
126
  normalized = value.strip().lower()
127
+ if normalized in _SCAFFOLD_ALIASES:
128
+ return _SCAFFOLD_ALIASES[normalized]
123
129
  if normalized not in _SCAFFOLD_DEPENDENCIES:
124
- allowed = ", ".join(_SCAFFOLD_DEPENDENCIES)
130
+ allowed = ", ".join(_ALLOWED_SCAFFOLD_VALUES)
125
131
  raise typer.BadParameter(f"Unknown scaffold '{value}'. Choose from: {allowed}.")
126
- return normalized # type: ignore[return-value]
132
+ return (normalized,) # type: ignore[return-value]
127
133
 
128
134
 
129
135
  def _parse_scaffold_values(
@@ -141,7 +147,7 @@ def _parse_scaffold_values(
141
147
  for value in raw_value.split(","):
142
148
  value = value.strip()
143
149
  if value:
144
- scaffolds.append(_normalize_scaffold_name(value))
150
+ scaffolds.extend(_expand_scaffold_value(value))
145
151
  return scaffolds
146
152
 
147
153
 
@@ -717,7 +723,8 @@ def init(
717
723
  help=(
718
724
  "Repeat or pass a comma-separated list to scaffold additional "
719
725
  "components: instructions, domain, api, ui, web, storybook, "
720
- "engine. Defaults to instructions only."
726
+ "engine, or common. common expands to instructions, domain, "
727
+ "api, ui, web, and storybook. Defaults to instructions only."
721
728
  ),
722
729
  ),
723
730
  ] = None,