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.
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/PKG-INFO +3 -2
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/README.md +2 -1
- rpr_cli-0.1.28/src/rpr/__init__.py +1 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/instructions.py +1 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/add.py +156 -14
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/ui.py +10 -2
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/init.py +12 -5
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/README.md +349 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/client/index.ts +1 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/client/types.ts +45 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.spec.tsx +329 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.tsx +358 -0
- 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
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.spec.ts +60 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.ts +128 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/index.ts +6 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatComposerMentionTokens.tsx +139 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatSuggestionsPopover.tsx +125 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/LocalFileSuggestionAction.tsx +100 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/index.ts +7 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.spec.ts +281 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.ts +1003 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.spec.ts +56 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.ts +58 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/types.ts +123 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/useChatSuggestions.ts +339 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/types.ts +114 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/useChatComposer.ts +169 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.spec.tsx +104 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.ts +212 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/index.ts +5 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/testing/createMockChatStreamClient.ts +91 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/testing/createMockSuggestionProvider.ts +99 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/testing/index.ts +2 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessage.tsx +235 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.spec.tsx +163 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.tsx +670 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.spec.tsx +365 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.tsx +93 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/README.md +111 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/contentFormat.ts +30 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/index.ts +6 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/streaming.ts +174 -0
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/thread/types.ts +135 -0
- 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
- 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
- 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
- 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
- rpr_cli-0.1.28/src/rpr/scaffolds/js_special_files/chat/virtual-list/index.ts +1 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/templates/registry.py +123 -51
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_add.py +201 -3
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_check.py +4 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_init.py +152 -0
- rpr_cli-0.1.26/src/rpr/__init__.py +0 -1
- rpr_cli-0.1.26/src/rpr/scaffolds/js_special_files/virtual-list-index.md +0 -9
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/.github/agents/story.agent.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/.github/workflows/publish-pypi.yml +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/.gitignore +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/CLAUDE.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/GEMINI.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/LICENSE +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/all.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/api.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/domain.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/frontend.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/rust-engine.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/setup-guide.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/tooling-setup.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/instructions/tooling.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/README.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/api/main.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/domain/base-repo.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/domain/base_entity.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/api.service.ts +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/useStateNavigation.ts +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponent.spec.tsx +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponent.tsx +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.spec.tsx +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.tsx +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/Sample-dot-github/scaffolds/frontend/virtual-list/index.ts +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/changelogs/mui_v9.txt +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/code-map.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/nx_uv_setup.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/patch_output.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/plan-languageAwareTemplateAdd.prompt.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/pyproject.toml +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/Cargo.lock +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/Cargo.toml +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/pyproject.toml +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/rpr_parser.pyi +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/config/container.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/config/mod.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/config/settings.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/graph.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/lib.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/models/dtos/mod.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/models/entities/mod.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/models/entities/users.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/models/mod.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/parse.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/repos/base.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/repos/mod.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/repos/users.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/resolve.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/src/walker.rs +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/rpr-parser/uv.lock +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/special_files.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/approval.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/bootstrap.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/client.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/control.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/mock.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/runtime.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/session.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/base.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/mutating.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/readonly.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/agent/tools/registry.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/catalog.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/chat_service.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/checks.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/cli_adapter.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/completer.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/conversation_service.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/prompt_service.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/selector.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/application/shell.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/base.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/packages.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/checks/workspace.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/cli.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/chat.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/check.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/api.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/domain.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/engine.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/generate/storybook.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/map.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/refresh.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/settings.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/commands/sync.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/context.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/dependencies.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/dependency_manifest_data.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/base.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/claude.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/copilot.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/cursor.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/gemini.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/generators/github.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/manifest_refresh.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/architecture.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/chains.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/classifier.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/coverage.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/dependencies.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/extractor.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/graph.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/output.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/responsibility.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/topology.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/map/walker.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/domain/base_entity.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/domain/base_repo.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/domain/container.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/domain/settings.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/all.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/api.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/domain.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/frontend.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/rust-engine.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/js_special_files/sticky-navigation.spec.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/js_special_files/vitest-browser-config.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/domain_container.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/domain_settings.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/encrypted_column.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/templates/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/console.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/markdown.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/prompt_session.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/renderers.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/ui/theme.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/src/rpr/workspace.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/README.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/00-bootstrap-cli.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/01-rpr-init.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/02-rpr-generate-domain.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/03-rpr-generate-api.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/04-rpr-generate-ui.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/05-rpr-generate-engine.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/06-rpr-generate-storybook.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/07-rpr-sync-rules.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/08-rpr-add-template.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/09-rpr-check.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/10-rpr-domain-config.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/18-rpr-terminal-ui-foundation.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/19-rpr-markdown-rendering.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/20-rpr-chat-repl.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/21-rpr-agent-tool-loop.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/22-rpr-chat-tui.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/23-rpr-chat-unified-command-shell.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/24-rpr-async-chat-runtime-and-services.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/25-rpr-prompt-service-and-conversation-lifecycle.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/26-rpr-shared-command-catalog.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/27-rpr-slash-command-selection-panel.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/28-rpr-chat-cancellable-and-multiline-input.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/chat/29-rpr-file-context-selection.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/11-rpr-map-command.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/12-rpr-map-file-walker.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/13-rpr-map-rust-engine.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/13a-rpr-map-gitignore.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/14-rpr-map-graph-builder.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/15-rpr-map-analysis-bridge.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/16-rpr-map-layer-classifier.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17-rpr-map-output.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17a-rpr-map-directory-topology.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17b-rpr-map-architecture-assessment.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17c-rpr-map-representative-chains.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/completed/map/17d-rpr-map-multi-resolution-output.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/map/30-rpr-map-directory-view-and-cycle-detection.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/map/31-rpr-map-coupling-hotspots-and-verdict-reasoning.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/stories/map/32-rpr-map-dependencies-responsibilities-and-test-coverage.md +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/__init__.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_architecture.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_architecture_unwrapped.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_catalog.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_chat.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_chat_service.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_completer.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_context.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_api.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_domain.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_engine.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_storybook.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_generate_ui.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_chains.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_classifier.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_coverage.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_dependencies.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_extractor.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_graph.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_output.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_responsibility.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_topology.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_map_walker.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_packaging.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_prompt_session.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_refresh.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_rpr_parser_stub.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_selector.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_settings.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_sync.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/tests/test_ui.py +0 -0
- {rpr_cli-0.1.26 → rpr_cli-0.1.28}/update_output.py +0 -0
- {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.
|
|
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"
|
|
@@ -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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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.
|
|
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.
|
|
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,
|