rpr-cli 0.3.1__tar.gz → 0.3.3__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.3.1 → rpr_cli-0.3.3}/.github/agents/story.agent.md +1 -1
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/PKG-INFO +14 -3
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/README.md +13 -2
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/code-map.md +0 -13
- rpr_cli-0.3.3/src/rpr/__init__.py +1 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/readonly.py +1 -1
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/chat_service.py +1 -1
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/checks/instructions.py +36 -2
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/checks/packages.py +3 -3
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/checks/workspace.py +3 -3
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/cli.py +2 -1
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/add.py +200 -16
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/domain.py +19 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/init.py +21 -3
- rpr_cli-0.3.3/src/rpr/commands/rename.py +85 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/sync.py +32 -14
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/generators/base.py +26 -4
- rpr_cli-0.3.3/src/rpr/generators/claude.py +57 -0
- rpr_cli-0.3.3/src/rpr/generators/codex.py +46 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/generators/copilot.py +5 -10
- rpr_cli-0.3.3/src/rpr/project_rename.py +521 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/domain/settings.md +153 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/BACKEND_FLOW.md +300 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/README.md +623 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/client/content.ts +47 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/client/httpChatStreamClient.spec.ts +227 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/client/httpChatStreamClient.ts +201 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/client/index.ts +2 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/client/types.ts +74 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.spec.tsx +34 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.tsx +110 -24
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatComposerMentionTokens.tsx +1 -12
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.spec.ts +282 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.ts +1 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/types.ts +2 -1
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/useChatSuggestions.ts +50 -59
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/types.ts +54 -2
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/useChatComposer.ts +85 -5
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.spec.tsx +312 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.ts +527 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperience.spec.tsx +142 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperience.styles.tsx +101 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperience.tsx +166 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceComposer.styles.tsx +101 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceComposer.tsx +176 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceHeader.styles.tsx +29 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceHeader.tsx +45 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/ThreadHistory.styles.tsx +80 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/ThreadHistory.tsx +127 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/chatStorage.spec.ts +98 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/chatStorage.ts +128 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/index.ts +7 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/types.ts +108 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/useChatExperience.spec.tsx +148 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/experience/useChatExperience.ts +473 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/index.ts +1 -1
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/testing/createMockChatStreamClient.ts +153 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/testing/createMockSuggestionProvider.ts +4 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessage.tsx +100 -67
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageActions.tsx +139 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.spec.tsx +25 -25
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.tsx +62 -42
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.spec.tsx +3 -3
- rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.tsx +172 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/README.md +6 -6
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/index.ts +1 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/streaming.ts +2 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/types.ts +56 -2
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.tsx +9 -2
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/api/routes/chat_routes.py +242 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/api/tests/test_chat.py +287 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/models/dtos/chat_dtos.py +450 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/models/dtos/conversation_history_dtos.py +37 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/models/entities/conversation_history.py +122 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/repos/conversation_history.py +349 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/agent_session_codec.py +53 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/chat_service.py +222 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/conversation_history_service.py +192 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/conversation_operations.py +148 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/history_codec.py +146 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/in_memory_history_store.py +94 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/postgres_history_store.py +143 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/protocols/conversation_history_store.py +56 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/protocols/conversation_runtime.py +90 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/services/protocols/llm_provider.py +52 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_chat_dtos.py +110 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_chat_service.py +401 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_history_codec.py +122 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_history_projection.py +19 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_persistence_config.py +24 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_postgres_history_store.py +165 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/__init__.py +15 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/model_catalog.py +106 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/vllm_agent_factory.py +83 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/vllm_agent_factory_protocol.py +17 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/runtimes/__init__.py +3 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/runtimes/agents_sdk.py +210 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/vllm_message_mapping.py +108 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/tests/test_agents_sdk_runtime.py +118 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/tests/test_vllm_model_catalog.py +168 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/py_special_files/vllm_provider/domain/tests/test_vllm_provider.py +85 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/special_files/domain_container.md +115 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/special_files/domain_settings.md +136 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/special_files/encrypted_column.md +119 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/special_files/logging.md +32 -0
- rpr_cli-0.3.3/src/rpr/scaffolds/special_files/test_encrypted_column.md +103 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/templates/registry.py +106 -2
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/ui/theme.py +1 -1
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/README.md +2 -2
- rpr_cli-0.3.3/stories/chat-attachment-upload-gap.md +306 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/01-rpr-init.md +1 -2
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/02-rpr-generate-domain.md +4 -4
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/07-rpr-sync-rules.md +0 -3
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/package-maintenance/default-vite-8-oxc-toolchain.md +1 -5
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/package-maintenance/rpr-update-packages.md +1 -1
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_add.py +75 -8
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_check.py +9 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_generate_domain.py +4 -1
- rpr_cli-0.3.3/tests/test_rename.py +335 -0
- rpr_cli-0.3.3/tests/test_sync.py +240 -0
- rpr_cli-0.3.3/untitled:plan-chatAttachmentUploadGap.prompt.md +52 -0
- rpr_cli-0.3.1/Sample-dot-github/instructions/domain.instructions.md +0 -96
- rpr_cli-0.3.1/Sample-dot-github/instructions/frontend.instructions.md +0 -98
- rpr_cli-0.3.1/Sample-dot-github/instructions/setup-guide.instructions.md +0 -89
- rpr_cli-0.3.1/Sample-dot-github/instructions/tooling-setup.instructions.md +0 -91
- rpr_cli-0.3.1/Sample-dot-github/instructions/tooling.instructions.md +0 -43
- rpr_cli-0.3.1/Sample-dot-github/scaffolds/README.md +0 -7
- rpr_cli-0.3.1/Sample-dot-github/scaffolds/api/main.py +0 -84
- rpr_cli-0.3.1/Sample-dot-github/scaffolds/domain/base-repo.md +0 -48
- rpr_cli-0.3.1/Sample-dot-github/scaffolds/domain/base_entity.md +0 -32
- rpr_cli-0.3.1/Sample-dot-github/scaffolds/frontend/api.service.ts +0 -200
- rpr_cli-0.3.1/Sample-dot-github/scaffolds/frontend/useStateNavigation.ts +0 -142
- rpr_cli-0.3.1/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.tsx +0 -112
- rpr_cli-0.3.1/src/rpr/__init__.py +0 -1
- rpr_cli-0.3.1/src/rpr/generators/claude.py +0 -33
- rpr_cli-0.3.1/src/rpr/scaffolds/domain/settings.md +0 -69
- rpr_cli-0.3.1/src/rpr/scaffolds/instructions/all.instructions.md +0 -49
- rpr_cli-0.3.1/src/rpr/scaffolds/instructions/api.instructions.md +0 -42
- rpr_cli-0.3.1/src/rpr/scaffolds/instructions/rust-engine.instructions.md +0 -41
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/README.md +0 -349
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/client/index.ts +0 -1
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/client/types.ts +0 -45
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.spec.ts +0 -281
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.spec.tsx +0 -104
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.ts +0 -212
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/testing/createMockChatStreamClient.ts +0 -91
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.tsx +0 -93
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.spec.tsx +0 -147
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.tsx +0 -94
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.spec.tsx +0 -277
- rpr_cli-0.3.1/src/rpr/scaffolds/js_special_files/chat/virtual-list/index.ts +0 -1
- rpr_cli-0.3.1/src/rpr/scaffolds/special_files/domain_container.md +0 -74
- rpr_cli-0.3.1/src/rpr/scaffolds/special_files/domain_settings.md +0 -69
- rpr_cli-0.3.1/src/rpr/scaffolds/special_files/encrypted_column.md +0 -98
- rpr_cli-0.3.1/tests/test_sync.py +0 -214
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/.github/workflows/publish-pypi.yml +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/.gitignore +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/CLAUDE.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/GEMINI.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/LICENSE +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/changelogs/mui_v9.txt +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/nx_uv_setup.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/patch_output.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/plan-languageAwareTemplateAdd.prompt.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/pyproject.toml +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/Cargo.lock +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/Cargo.toml +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/pyproject.toml +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/rpr_parser.pyi +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/config/container.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/config/mod.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/config/settings.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/graph.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/lib.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/models/dtos/mod.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/models/entities/mod.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/models/entities/users.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/models/mod.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/parse.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/repos/base.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/repos/mod.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/repos/users.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/resolve.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/src/walker.rs +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/rpr-parser/uv.lock +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/special_files.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/approval.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/bootstrap.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/client.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/control.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/mock.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/runtime.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/session.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/base.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/mutating.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/registry.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/catalog.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/checks.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/cli_adapter.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/completer.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/conversation_service.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/prompt_service.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/selector.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/application/shell.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/checks/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/checks/base.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/chat.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/check.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/api.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/engine.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/storybook.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/ui.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/map.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/refresh.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/settings.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/commands/update.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/context.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/dependencies.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/dependency_manifest_data.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/generators/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/generators/cursor.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/generators/gemini.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/generators/github.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/manifest_refresh.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/architecture.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/chains.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/classifier.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/coverage.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/dependencies.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/extractor.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/graph.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/output.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/responsibility.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/topology.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/map/walker.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/package_updates.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/domain/base_entity.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/domain/base_repo.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/domain/container.md +0 -0
- {rpr_cli-0.3.1/Sample-dot-github → rpr_cli-0.3.3/src/rpr/scaffolds}/instructions/all.instructions.md +0 -0
- {rpr_cli-0.3.1/Sample-dot-github → rpr_cli-0.3.3/src/rpr/scaffolds}/instructions/api.instructions.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/domain.instructions.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/frontend.instructions.md +0 -0
- {rpr_cli-0.3.1/Sample-dot-github → rpr_cli-0.3.3/src/rpr/scaffolds}/instructions/rust-engine.instructions.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/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.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.spec.ts +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.ts +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/index.ts +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatSuggestionsPopover.tsx +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/LocalFileSuggestionAction.tsx +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/index.ts +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.spec.ts +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.ts +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/testing/index.ts +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/contentFormat.ts +0 -0
- {rpr_cli-0.3.1/Sample-dot-github/scaffolds/frontend → rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat}/virtual-list/VirtualComponent.spec.tsx +0 -0
- {rpr_cli-0.3.1/Sample-dot-github/scaffolds/frontend → rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat}/virtual-list/VirtualComponent.tsx +0 -0
- {rpr_cli-0.3.1/Sample-dot-github/scaffolds/frontend → rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat}/virtual-list/VirtualComponentList.spec.tsx +0 -0
- {rpr_cli-0.3.1/Sample-dot-github/scaffolds/frontend → rpr_cli-0.3.3/src/rpr/scaffolds/js_special_files/chat}/virtual-list/index.ts +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/sticky-navigation.spec.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/vitest-browser-config.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/special_files/camel_case_model.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/templates/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/ui/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/ui/console.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/ui/markdown.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/ui/prompt_session.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/ui/renderers.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/src/rpr/workspace.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/00-bootstrap-cli.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/03-rpr-generate-api.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/04-rpr-generate-ui.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/05-rpr-generate-engine.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/06-rpr-generate-storybook.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/08-rpr-add-template.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/09-rpr-check.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/10-rpr-domain-config.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/18-rpr-terminal-ui-foundation.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/19-rpr-markdown-rendering.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/20-rpr-chat-repl.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/21-rpr-agent-tool-loop.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/22-rpr-chat-tui.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/23-rpr-chat-unified-command-shell.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/24-rpr-async-chat-runtime-and-services.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/25-rpr-prompt-service-and-conversation-lifecycle.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/26-rpr-shared-command-catalog.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/27-rpr-slash-command-selection-panel.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/28-rpr-chat-cancellable-and-multiline-input.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/chat/29-rpr-file-context-selection.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/11-rpr-map-command.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/12-rpr-map-file-walker.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/13-rpr-map-rust-engine.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/13a-rpr-map-gitignore.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/14-rpr-map-graph-builder.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/15-rpr-map-analysis-bridge.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/16-rpr-map-layer-classifier.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/17-rpr-map-output.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/17a-rpr-map-directory-topology.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/17b-rpr-map-architecture-assessment.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/17c-rpr-map-representative-chains.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/completed/map/17d-rpr-map-multi-resolution-output.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/map/30-rpr-map-directory-view-and-cycle-detection.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/map/31-rpr-map-coupling-hotspots-and-verdict-reasoning.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/map/32-rpr-map-dependencies-responsibilities-and-test-coverage.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/stories/package-maintenance/typescript-7-frontend-scaffold-compatibility.md +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/__init__.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_architecture.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_architecture_unwrapped.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_catalog.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_chat.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_chat_service.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_completer.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_context.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_generate_api.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_generate_engine.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_generate_storybook.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_generate_ui.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_init.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_chains.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_classifier.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_coverage.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_dependencies.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_extractor.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_graph.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_output.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_responsibility.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_topology.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_map_walker.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_package_updates.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_packaging.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_prompt_session.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_refresh.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_rpr_parser_stub.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_selector.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_settings.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_ui.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/tests/test_update_packages.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/update_output.py +0 -0
- {rpr_cli-0.3.1 → rpr_cli-0.3.3}/uv.lock +0 -0
|
@@ -55,7 +55,7 @@ You must strictly execute the following phases in order. Do not skip to generati
|
|
|
55
55
|
2. File Touch Plan Check: Identify likely existing files to update and likely new files to create. For each file, capture why it belongs in the plan.
|
|
56
56
|
3. Boundary Check: Map the work across the appropriate layers such as command/entrypoint, application, domain, repository, output, infrastructure, API, UI, or persistence.
|
|
57
57
|
4. SOLID and DDD Check: Ensure responsibilities stay separated. Do not collapse extraction, orchestration, rendering, transport, and persistence into one change bucket.
|
|
58
|
-
5. Pattern Alignment Check: Follow the guidance and scaffolds in
|
|
58
|
+
5. Pattern Alignment Check: Follow the bundled RPR guidance and scaffolds in src/rpr/scaffolds. Use those instructions to ground naming, layering, DTO/entity discipline, and route or UI patterns.
|
|
59
59
|
6. Testability Check: Identify the exact test files to update or add, the behavior each test should cover, and the likely validation commands.
|
|
60
60
|
7. Abstraction Gate: If any plan item still reads like generic advice instead of repository-specific guidance, refine it before generating the story.
|
|
61
61
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rpr-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -67,8 +67,17 @@ rpr generate api my-app # Add a FastAPI application
|
|
|
67
67
|
rpr generate ui my-app # Add a React UI library and web app
|
|
68
68
|
rpr generate engine my-app # Add a Rust/PyO3 computation engine
|
|
69
69
|
rpr generate storybook # Add Storybook for UI component development
|
|
70
|
+
rpr rename new-app # Rename the workspace identity and references
|
|
70
71
|
```
|
|
71
72
|
|
|
73
|
+
Run `rpr rename <new-name>` from an initialized workspace root to update RPR
|
|
74
|
+
metadata, package and Nx project names, imports, commands, paths, lockfiles, and
|
|
75
|
+
matching references in user-added text files. The command shows its complete
|
|
76
|
+
change plan before asking for confirmation. Use `--dry-run` to preview without
|
|
77
|
+
writing or `--yes` to skip the prompt. Dependency directories, VCS data, build
|
|
78
|
+
outputs, binary contents, and symlink targets are not changed. The outer workspace
|
|
79
|
+
directory keeps its existing name.
|
|
80
|
+
|
|
72
81
|
`rpr init <project-name>` creates the project directory when it does not exist. If the directory already exists and is not an NX workspace, RPR initializes Git and runs `nx init` inside that directory.
|
|
73
82
|
|
|
74
83
|
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:
|
|
@@ -83,7 +92,7 @@ rpr init todo-list --scaffold api --scaffold web --domain-migrations
|
|
|
83
92
|
Available scaffolds are:
|
|
84
93
|
|
|
85
94
|
- `common`: Alias for `instructions`, `domain`, `api`, `ui`, `web`, and `storybook`; excludes `engine`.
|
|
86
|
-
- `instructions`: AI instruction files for Cursor, Copilot, Claude Code, and
|
|
95
|
+
- `instructions`: AI instruction files for Cursor, Copilot, Claude Code, Gemini, and Codex.
|
|
87
96
|
- `domain`: Python DDD package at `packages/python/domain`.
|
|
88
97
|
- `api`: FastAPI app at `apps/<name>-api`; also scaffolds `domain`.
|
|
89
98
|
- `ui`: React UI library at `packages/node/<name>-ui`.
|
|
@@ -111,7 +120,9 @@ The scaffold version manifest that powers generated dependency specs and the syn
|
|
|
111
120
|
Sync project context to your favorite AI tools and add common code patterns.
|
|
112
121
|
|
|
113
122
|
```bash
|
|
114
|
-
rpr sync rules # Sync AI instructions to
|
|
123
|
+
rpr sync rules # Sync AI instructions to all supported coding agents
|
|
124
|
+
rpr sync rules --target claude # Sync only Claude
|
|
125
|
+
rpr sync rules -t claude -t codex # Sync Claude and Codex
|
|
115
126
|
rpr add template python mapper_util # Add a Python code template to your project
|
|
116
127
|
rpr add template python camel_case_model
|
|
117
128
|
rpr add template node sticky_navigation --include-tests
|
|
@@ -50,8 +50,17 @@ rpr generate api my-app # Add a FastAPI application
|
|
|
50
50
|
rpr generate ui my-app # Add a React UI library and web app
|
|
51
51
|
rpr generate engine my-app # Add a Rust/PyO3 computation engine
|
|
52
52
|
rpr generate storybook # Add Storybook for UI component development
|
|
53
|
+
rpr rename new-app # Rename the workspace identity and references
|
|
53
54
|
```
|
|
54
55
|
|
|
56
|
+
Run `rpr rename <new-name>` from an initialized workspace root to update RPR
|
|
57
|
+
metadata, package and Nx project names, imports, commands, paths, lockfiles, and
|
|
58
|
+
matching references in user-added text files. The command shows its complete
|
|
59
|
+
change plan before asking for confirmation. Use `--dry-run` to preview without
|
|
60
|
+
writing or `--yes` to skip the prompt. Dependency directories, VCS data, build
|
|
61
|
+
outputs, binary contents, and symlink targets are not changed. The outer workspace
|
|
62
|
+
directory keeps its existing name.
|
|
63
|
+
|
|
55
64
|
`rpr init <project-name>` creates the project directory when it does not exist. If the directory already exists and is not an NX workspace, RPR initializes Git and runs `nx init` inside that directory.
|
|
56
65
|
|
|
57
66
|
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:
|
|
@@ -66,7 +75,7 @@ rpr init todo-list --scaffold api --scaffold web --domain-migrations
|
|
|
66
75
|
Available scaffolds are:
|
|
67
76
|
|
|
68
77
|
- `common`: Alias for `instructions`, `domain`, `api`, `ui`, `web`, and `storybook`; excludes `engine`.
|
|
69
|
-
- `instructions`: AI instruction files for Cursor, Copilot, Claude Code, and
|
|
78
|
+
- `instructions`: AI instruction files for Cursor, Copilot, Claude Code, Gemini, and Codex.
|
|
70
79
|
- `domain`: Python DDD package at `packages/python/domain`.
|
|
71
80
|
- `api`: FastAPI app at `apps/<name>-api`; also scaffolds `domain`.
|
|
72
81
|
- `ui`: React UI library at `packages/node/<name>-ui`.
|
|
@@ -94,7 +103,9 @@ The scaffold version manifest that powers generated dependency specs and the syn
|
|
|
94
103
|
Sync project context to your favorite AI tools and add common code patterns.
|
|
95
104
|
|
|
96
105
|
```bash
|
|
97
|
-
rpr sync rules # Sync AI instructions to
|
|
106
|
+
rpr sync rules # Sync AI instructions to all supported coding agents
|
|
107
|
+
rpr sync rules --target claude # Sync only Claude
|
|
108
|
+
rpr sync rules -t claude -t codex # Sync Claude and Codex
|
|
98
109
|
rpr add template python mapper_util # Add a Python code template to your project
|
|
99
110
|
rpr add template python camel_case_model
|
|
100
111
|
rpr add template node sticky_navigation --include-tests
|
|
@@ -19,7 +19,6 @@ Verdict: **unclear**
|
|
|
19
19
|
- No mixed-role hotspots detected
|
|
20
20
|
|
|
21
21
|
### Leaf Areas
|
|
22
|
-
- Sample-dot-github
|
|
23
22
|
- rpr-parser
|
|
24
23
|
- src/rpr
|
|
25
24
|
- tests
|
|
@@ -56,10 +55,6 @@ flowchart TB
|
|
|
56
55
|
## Directory Tree
|
|
57
56
|
|
|
58
57
|
```
|
|
59
|
-
Sample-dot-github/
|
|
60
|
-
scaffolds/
|
|
61
|
-
api/
|
|
62
|
-
frontend/
|
|
63
58
|
rpr-parser/
|
|
64
59
|
src/
|
|
65
60
|
config/
|
|
@@ -91,8 +86,6 @@ Directories: `rpr-parser/src`
|
|
|
91
86
|
## External Dependencies
|
|
92
87
|
|
|
93
88
|
***(root)*** — `re`, `sys`
|
|
94
|
-
**`Sample-dot-github/scaffolds/api`** — `asyncio`, `contextlib`, `fastapi`, `my_app_domain`, `starlette`
|
|
95
|
-
**`Sample-dot-github/scaffolds/frontend`** — `react`
|
|
96
89
|
**`rpr-parser/src`** — `foo`, `ignore`, `log`, `tempfile`, `tokio`, `walker`
|
|
97
90
|
**`rpr-parser/src/config`** — `log`
|
|
98
91
|
**`rpr-parser/src/models/entities`** — `sea_orm`, `uuid`
|
|
@@ -113,10 +106,6 @@ Directories: `rpr-parser/src`
|
|
|
113
106
|
## Module Responsibilities
|
|
114
107
|
|
|
115
108
|
***(root)*** — Tests
|
|
116
|
-
**`Sample-dot-github`** — Entry points
|
|
117
|
-
**`Sample-dot-github/scaffolds`** — Project scaffolds
|
|
118
|
-
**`Sample-dot-github/scaffolds/api`** — API layer
|
|
119
|
-
**`Sample-dot-github/scaffolds/frontend`** — 2 source files
|
|
120
109
|
**`rpr-parser`** — Infrastructure layer
|
|
121
110
|
**`rpr-parser/src`** — Infrastructure layer
|
|
122
111
|
**`rpr-parser/src/config`** — Configuration
|
|
@@ -153,8 +142,6 @@ Directories: `rpr-parser/src`
|
|
|
153
142
|
|
|
154
143
|
### No Test Evidence Detected
|
|
155
144
|
- *(root)*
|
|
156
|
-
- `Sample-dot-github/scaffolds/api`
|
|
157
|
-
- `Sample-dot-github/scaffolds/frontend`
|
|
158
145
|
- `rpr-parser/src`
|
|
159
146
|
- `rpr-parser/src/config`
|
|
160
147
|
- `rpr-parser/src/models`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.3"
|
|
@@ -123,7 +123,7 @@ class SearchTextTool(AgentTool):
|
|
|
123
123
|
path = current_root / file_name
|
|
124
124
|
try:
|
|
125
125
|
content = path.read_text()
|
|
126
|
-
except OSError, UnicodeDecodeError:
|
|
126
|
+
except (OSError, UnicodeDecodeError):
|
|
127
127
|
continue
|
|
128
128
|
|
|
129
129
|
for line_number, line in enumerate(content.splitlines(), start=1):
|
|
@@ -309,7 +309,7 @@ class ChatCommandService:
|
|
|
309
309
|
else:
|
|
310
310
|
_dispatch_agent_turn(normalized)
|
|
311
311
|
|
|
312
|
-
except KeyboardInterrupt, EOFError:
|
|
312
|
+
except (KeyboardInterrupt, EOFError):
|
|
313
313
|
if active_task is not None and not active_task.done():
|
|
314
314
|
active_task.cancel()
|
|
315
315
|
presenter.flush()
|
|
@@ -58,16 +58,50 @@ def check_instructions(
|
|
|
58
58
|
|
|
59
59
|
# Claude instructions
|
|
60
60
|
claude_file = project_dir / "CLAUDE.md"
|
|
61
|
+
claude_rules = project_dir / ".claude" / "rules"
|
|
62
|
+
claude_ok = (
|
|
63
|
+
claude_file.exists()
|
|
64
|
+
and claude_rules.exists()
|
|
65
|
+
and any(claude_rules.glob("*.md"))
|
|
66
|
+
)
|
|
61
67
|
results.append(
|
|
62
68
|
CheckResult(
|
|
63
69
|
group="AI Instructions & Templates",
|
|
64
70
|
area="Claude instructions",
|
|
65
|
-
status=
|
|
66
|
-
path=
|
|
71
|
+
status=claude_ok,
|
|
72
|
+
path=(
|
|
73
|
+
str(claude_file)
|
|
74
|
+
if claude_ok
|
|
75
|
+
else "CLAUDE.md or .claude/rules/*.md missing"
|
|
76
|
+
),
|
|
67
77
|
suggestion="rpr sync rules --target claude",
|
|
68
78
|
)
|
|
69
79
|
)
|
|
70
80
|
|
|
81
|
+
# Gemini instructions
|
|
82
|
+
gemini_file = project_dir / "GEMINI.md"
|
|
83
|
+
results.append(
|
|
84
|
+
CheckResult(
|
|
85
|
+
group="AI Instructions & Templates",
|
|
86
|
+
area="Gemini instructions",
|
|
87
|
+
status=gemini_file.exists(),
|
|
88
|
+
path=str(gemini_file) if gemini_file.exists() else "GEMINI.md missing",
|
|
89
|
+
suggestion="rpr sync rules --target gemini",
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Codex instructions
|
|
94
|
+
codex_file = project_dir / "AGENTS.md"
|
|
95
|
+
results.append(
|
|
96
|
+
CheckResult(
|
|
97
|
+
group="AI Instructions & Templates",
|
|
98
|
+
area="Codex instructions",
|
|
99
|
+
status=codex_file.exists(),
|
|
100
|
+
path=str(codex_file) if codex_file.exists() else "AGENTS.md missing",
|
|
101
|
+
suggestion="rpr sync rules --target codex",
|
|
102
|
+
)
|
|
103
|
+
)
|
|
104
|
+
|
|
71
105
|
# Templates (only if domain package exists for Python, or UI library for JS)
|
|
72
106
|
has_domain = any(project_dir.glob("packages/python/*_domain"))
|
|
73
107
|
has_ui = any(project_dir.glob("packages/node/*-ui"))
|
|
@@ -38,7 +38,7 @@ def check_packages(project_dir: Path, variables: dict[str, str]) -> list[CheckRe
|
|
|
38
38
|
)
|
|
39
39
|
if isinstance(members, list):
|
|
40
40
|
workspace_members = set(members)
|
|
41
|
-
except OSError, tomllib.TOMLDecodeError:
|
|
41
|
+
except (OSError, tomllib.TOMLDecodeError):
|
|
42
42
|
workspace_members = set()
|
|
43
43
|
|
|
44
44
|
# Domain package
|
|
@@ -316,7 +316,7 @@ def _load_json(path: Path) -> dict[str, object] | None:
|
|
|
316
316
|
return None
|
|
317
317
|
try:
|
|
318
318
|
data = json.loads(path.read_text())
|
|
319
|
-
except OSError, json.JSONDecodeError:
|
|
319
|
+
except (OSError, json.JSONDecodeError):
|
|
320
320
|
return None
|
|
321
321
|
return data if isinstance(data, dict) else None
|
|
322
322
|
|
|
@@ -326,7 +326,7 @@ def _load_toml(path: Path) -> dict[str, object] | None:
|
|
|
326
326
|
return None
|
|
327
327
|
try:
|
|
328
328
|
data = tomllib.loads(path.read_text())
|
|
329
|
-
except OSError, tomllib.TOMLDecodeError:
|
|
329
|
+
except (OSError, tomllib.TOMLDecodeError):
|
|
330
330
|
return None
|
|
331
331
|
return data if isinstance(data, dict) else None
|
|
332
332
|
|
|
@@ -20,7 +20,7 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
|
|
|
20
20
|
nx_data = json.loads(nx_json.read_text())
|
|
21
21
|
nx_ok = True
|
|
22
22
|
nx_cloud_disabled = nx_data.get("neverConnectToCloud") is True
|
|
23
|
-
except OSError, json.JSONDecodeError:
|
|
23
|
+
except (OSError, json.JSONDecodeError):
|
|
24
24
|
nx_ok = False
|
|
25
25
|
|
|
26
26
|
results.append(
|
|
@@ -53,7 +53,7 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
|
|
|
53
53
|
pyproject_data = tomllib.loads(pyproject.read_text())
|
|
54
54
|
tool = pyproject_data.get("tool", {})
|
|
55
55
|
uv_ok = "uv" in tool and "workspace" in tool["uv"]
|
|
56
|
-
except OSError, tomllib.TOMLDecodeError:
|
|
56
|
+
except (OSError, tomllib.TOMLDecodeError):
|
|
57
57
|
uv_ok = False
|
|
58
58
|
|
|
59
59
|
results.append(
|
|
@@ -117,7 +117,7 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
|
|
|
117
117
|
"apps/*",
|
|
118
118
|
"packages/node/*",
|
|
119
119
|
}.issubset(set(workspaces))
|
|
120
|
-
except OSError, json.JSONDecodeError:
|
|
120
|
+
except (OSError, json.JSONDecodeError):
|
|
121
121
|
node_workspace_ok = False
|
|
122
122
|
|
|
123
123
|
results.append(
|
|
@@ -17,6 +17,7 @@ from rpr.commands import check as _check_mod # noqa: E402, F401
|
|
|
17
17
|
from rpr.commands import settings as _settings_mod # noqa: E402, F401
|
|
18
18
|
from rpr.commands import map as _map_mod # noqa: E402, F401
|
|
19
19
|
from rpr.commands import chat as _chat_mod # noqa: E402, F401
|
|
20
|
+
from rpr.commands import rename as _rename_mod # noqa: E402, F401
|
|
20
21
|
|
|
21
22
|
generate_app = typer.Typer(
|
|
22
23
|
name="generate",
|
|
@@ -27,7 +28,7 @@ app.add_typer(generate_app, name="generate")
|
|
|
27
28
|
|
|
28
29
|
sync_app = typer.Typer(
|
|
29
30
|
name="sync",
|
|
30
|
-
help="Sync AI instructions to Cursor, Copilot,
|
|
31
|
+
help="Sync AI instructions to Cursor, GitHub Copilot, Claude Code, Gemini, and Codex.",
|
|
31
32
|
no_args_is_help=True,
|
|
32
33
|
)
|
|
33
34
|
app.add_typer(sync_app, name="sync")
|
|
@@ -183,9 +183,11 @@ def template(
|
|
|
183
183
|
output_dir,
|
|
184
184
|
)
|
|
185
185
|
|
|
186
|
+
_auto_wire_python_template(ctx, entry, variables)
|
|
187
|
+
|
|
186
188
|
_print_include_test_notes(entry, include_tests, skipped_config_paths)
|
|
187
189
|
|
|
188
|
-
_maybe_install_dependencies(ctx, ordered_entries, include_tests, install)
|
|
190
|
+
_maybe_install_dependencies(ctx, ordered_entries, include_tests, install, variables)
|
|
189
191
|
|
|
190
192
|
console.print("\n[bold green]Done![/] Template files written:")
|
|
191
193
|
for _, target_path, _ in writable_files:
|
|
@@ -297,6 +299,7 @@ def _apply_raw_transforms(
|
|
|
297
299
|
subdir = template_file.source_subdir
|
|
298
300
|
filename = template_file.source_filename
|
|
299
301
|
name_kebab = variables.get("name_kebab", "")
|
|
302
|
+
name_underscore = variables.get("name_underscore", "")
|
|
300
303
|
|
|
301
304
|
# The chat thread reuses the sibling standalone virtual-list component.
|
|
302
305
|
if subdir.endswith("chat/thread") and filename == "ChatThread.tsx":
|
|
@@ -308,9 +311,15 @@ def _apply_raw_transforms(
|
|
|
308
311
|
|
|
309
312
|
# Documentation references to the originating project should be templated.
|
|
310
313
|
if filename.endswith(".md"):
|
|
314
|
+
code = code.replace("packages/node/testapp-ui", f"packages/node/{name_kebab}-ui")
|
|
315
|
+
code = code.replace("packages/node/testapp-sb", f"packages/node/{name_kebab}-sb")
|
|
316
|
+
code = code.replace("apps/testapp_api", f"apps/{name_underscore}_api")
|
|
317
|
+
code = code.replace("testapp_domain", f"{name_underscore}_domain")
|
|
311
318
|
code = code.replace("packages/huddle-ui", f"packages/node/{name_kebab}-ui")
|
|
312
319
|
code = code.replace("packages/sb/", f"packages/node/{name_kebab}-sb/")
|
|
320
|
+
code = code.replace("@testapp/ui", f"@{name_kebab}/ui")
|
|
313
321
|
code = code.replace("@huddle/ui", f"@{name_kebab}/ui")
|
|
322
|
+
code = code.replace("testapp-ui", f"{name_kebab}-ui")
|
|
314
323
|
code = code.replace("huddle-ui", f"{name_kebab}-ui")
|
|
315
324
|
|
|
316
325
|
return code
|
|
@@ -334,7 +343,7 @@ def _update_root_index(
|
|
|
334
343
|
output_dir: str | None,
|
|
335
344
|
) -> None:
|
|
336
345
|
"""Add component barrel exports to the UI package root index when present."""
|
|
337
|
-
if output_dir:
|
|
346
|
+
if ctx.dry_run or output_dir:
|
|
338
347
|
return
|
|
339
348
|
|
|
340
349
|
component_names: list[str] = []
|
|
@@ -367,34 +376,209 @@ def _update_root_index(
|
|
|
367
376
|
ctx.write_file(index_path, updated)
|
|
368
377
|
|
|
369
378
|
|
|
379
|
+
def _auto_wire_python_template(
|
|
380
|
+
ctx: RunContext, entry: TemplateEntry, variables: dict[str, str]
|
|
381
|
+
) -> None:
|
|
382
|
+
"""Auto-wire container.py and main.py when python_chat or vllm_provider is added."""
|
|
383
|
+
name_underscore = variables.get("name_underscore", "")
|
|
384
|
+
if ctx.dry_run or not name_underscore or entry.lang != "python":
|
|
385
|
+
return
|
|
386
|
+
|
|
387
|
+
# Auto-wire container.py if python_chat or vllm_provider is added
|
|
388
|
+
if entry.id in ("python_chat", "vllm_provider"):
|
|
389
|
+
container_path = (
|
|
390
|
+
ctx.project_dir
|
|
391
|
+
/ "packages"
|
|
392
|
+
/ "python"
|
|
393
|
+
/ f"{name_underscore}_domain"
|
|
394
|
+
/ "src"
|
|
395
|
+
/ f"{name_underscore}_domain"
|
|
396
|
+
/ "config"
|
|
397
|
+
/ "container.py"
|
|
398
|
+
)
|
|
399
|
+
if container_path.exists():
|
|
400
|
+
container_scaffold = (
|
|
401
|
+
Path(__file__).resolve().parent.parent
|
|
402
|
+
/ "scaffolds"
|
|
403
|
+
/ "special_files"
|
|
404
|
+
/ "domain_container.md"
|
|
405
|
+
)
|
|
406
|
+
if container_scaffold.exists():
|
|
407
|
+
from rpr.commands.generate.domain import _extract_first_code_block
|
|
408
|
+
|
|
409
|
+
code = _extract_first_code_block(container_scaffold)
|
|
410
|
+
code = code.replace("your_app_domain", f"{name_underscore}_domain")
|
|
411
|
+
ctx.write_file(container_path, code)
|
|
412
|
+
|
|
413
|
+
# Auto-wire chat_routes into main.py if python_chat is added
|
|
414
|
+
if entry.id in ("python_chat", "vllm_provider"):
|
|
415
|
+
main_path = (
|
|
416
|
+
ctx.project_dir
|
|
417
|
+
/ "apps"
|
|
418
|
+
/ f"{name_underscore}_api"
|
|
419
|
+
/ "src"
|
|
420
|
+
/ f"{name_underscore}_api"
|
|
421
|
+
/ "main.py"
|
|
422
|
+
)
|
|
423
|
+
if main_path.exists():
|
|
424
|
+
content = main_path.read_text()
|
|
425
|
+
if "chat_routes" not in content:
|
|
426
|
+
content = content.replace(
|
|
427
|
+
"from .routes.health import router as health_router",
|
|
428
|
+
"from .routes import chat_routes\nfrom .routes.health import router as health_router",
|
|
429
|
+
)
|
|
430
|
+
content = content.replace(
|
|
431
|
+
"container.wire(modules=[__name__])",
|
|
432
|
+
"container.wire(modules=[__name__, chat_routes])",
|
|
433
|
+
)
|
|
434
|
+
content = content.replace(
|
|
435
|
+
'app.include_router(health_router, prefix="/api/health", tags=["Health"])',
|
|
436
|
+
'app.include_router(health_router, prefix="/api/health", tags=["Health"])\n app.include_router(chat_routes.router, prefix="/api/chat", tags=["Chat"])',
|
|
437
|
+
)
|
|
438
|
+
ctx.write_file(main_path, content)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
@add_app.command("node")
|
|
442
|
+
def node_cmd(
|
|
443
|
+
template_id: Annotated[
|
|
444
|
+
str | None, typer.Argument(help="Template ID to add.")
|
|
445
|
+
] = None,
|
|
446
|
+
list_templates: Annotated[
|
|
447
|
+
bool, typer.Option("--list", "-l", help="List node templates.")
|
|
448
|
+
] = False,
|
|
449
|
+
force: Annotated[
|
|
450
|
+
bool, typer.Option("--force", "-f", help="Overwrite existing files.")
|
|
451
|
+
] = False,
|
|
452
|
+
name: Annotated[
|
|
453
|
+
str | None, typer.Option("--name", "-n", help="App name for variables.")
|
|
454
|
+
] = None,
|
|
455
|
+
source: Annotated[
|
|
456
|
+
str | None, typer.Option("--source", "-s", help="Path to rules source.")
|
|
457
|
+
] = None,
|
|
458
|
+
include_tests: Annotated[
|
|
459
|
+
bool, typer.Option("--include-tests", help="Include unit-test companions.")
|
|
460
|
+
] = False,
|
|
461
|
+
install: Annotated[
|
|
462
|
+
bool | None, typer.Option("--install/--no-install", help="Install deps.")
|
|
463
|
+
] = None,
|
|
464
|
+
output_dir: Annotated[
|
|
465
|
+
str | None, typer.Option("--output-dir", help="Target output dir.")
|
|
466
|
+
] = None,
|
|
467
|
+
dry_run: Annotated[
|
|
468
|
+
bool, typer.Option("--dry-run", help="Preview changes without writing.")
|
|
469
|
+
] = False,
|
|
470
|
+
) -> None:
|
|
471
|
+
"""Add a Node template file (e.g. chat, virtual_list, sticky_navigation)."""
|
|
472
|
+
template(
|
|
473
|
+
"node",
|
|
474
|
+
template_id,
|
|
475
|
+
list_templates=list_templates,
|
|
476
|
+
force=force,
|
|
477
|
+
name=name,
|
|
478
|
+
source=source,
|
|
479
|
+
include_tests=include_tests,
|
|
480
|
+
install=install,
|
|
481
|
+
output_dir=output_dir,
|
|
482
|
+
dry_run=dry_run,
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
@add_app.command("python")
|
|
487
|
+
def python_cmd(
|
|
488
|
+
template_id: Annotated[
|
|
489
|
+
str | None, typer.Argument(help="Template ID to add.")
|
|
490
|
+
] = None,
|
|
491
|
+
list_templates: Annotated[
|
|
492
|
+
bool, typer.Option("--list", "-l", help="List python templates.")
|
|
493
|
+
] = False,
|
|
494
|
+
force: Annotated[
|
|
495
|
+
bool, typer.Option("--force", "-f", help="Overwrite existing files.")
|
|
496
|
+
] = False,
|
|
497
|
+
name: Annotated[
|
|
498
|
+
str | None, typer.Option("--name", "-n", help="App name for variables.")
|
|
499
|
+
] = None,
|
|
500
|
+
source: Annotated[
|
|
501
|
+
str | None, typer.Option("--source", "-s", help="Path to rules source.")
|
|
502
|
+
] = None,
|
|
503
|
+
include_tests: Annotated[
|
|
504
|
+
bool, typer.Option("--include-tests", help="Include unit-test companions.")
|
|
505
|
+
] = False,
|
|
506
|
+
install: Annotated[
|
|
507
|
+
bool | None, typer.Option("--install/--no-install", help="Install deps.")
|
|
508
|
+
] = None,
|
|
509
|
+
output_dir: Annotated[
|
|
510
|
+
str | None, typer.Option("--output-dir", help="Target output dir.")
|
|
511
|
+
] = None,
|
|
512
|
+
dry_run: Annotated[
|
|
513
|
+
bool, typer.Option("--dry-run", help="Preview changes without writing.")
|
|
514
|
+
] = False,
|
|
515
|
+
) -> None:
|
|
516
|
+
"""Add a Python template file (e.g. chat, vllm-provider, encrypted_column)."""
|
|
517
|
+
template(
|
|
518
|
+
"python",
|
|
519
|
+
template_id,
|
|
520
|
+
list_templates=list_templates,
|
|
521
|
+
force=force,
|
|
522
|
+
name=name,
|
|
523
|
+
source=source,
|
|
524
|
+
include_tests=include_tests,
|
|
525
|
+
install=install,
|
|
526
|
+
output_dir=output_dir,
|
|
527
|
+
dry_run=dry_run,
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
|
|
370
531
|
def _maybe_install_dependencies(
|
|
371
532
|
ctx: RunContext,
|
|
372
533
|
ordered_entries: list[tuple[TemplateEntry, bool]],
|
|
373
534
|
include_tests: bool,
|
|
374
535
|
install: bool | None,
|
|
536
|
+
variables: dict[str, str],
|
|
375
537
|
) -> None:
|
|
376
538
|
install_by_default = any(entry.install_by_default for entry, _ in ordered_entries)
|
|
377
539
|
should_install = install_by_default if install is None else install
|
|
378
540
|
if not should_install:
|
|
379
541
|
return
|
|
380
542
|
|
|
381
|
-
|
|
382
|
-
|
|
543
|
+
npm_runtime: list[str] = []
|
|
544
|
+
npm_dev: list[str] = []
|
|
545
|
+
python_domain: list[str] = []
|
|
546
|
+
python_api: list[str] = []
|
|
383
547
|
for entry, _ in ordered_entries:
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
548
|
+
if entry.lang == "node":
|
|
549
|
+
for dep in entry.dependencies:
|
|
550
|
+
if dep not in npm_runtime:
|
|
551
|
+
npm_runtime.append(dep)
|
|
552
|
+
if include_tests:
|
|
553
|
+
for dep in entry.dev_dependencies:
|
|
554
|
+
if dep not in npm_dev:
|
|
555
|
+
npm_dev.append(dep)
|
|
556
|
+
continue
|
|
557
|
+
for dep in entry.python_domain_dependencies:
|
|
558
|
+
if dep not in python_domain:
|
|
559
|
+
python_domain.append(dep)
|
|
560
|
+
for dep in entry.python_api_dependencies:
|
|
561
|
+
if dep not in python_api:
|
|
562
|
+
python_api.append(dep)
|
|
563
|
+
|
|
564
|
+
if npm_runtime:
|
|
393
565
|
console.print("\n[bold]Installing runtime dependencies...[/]")
|
|
394
|
-
ctx.run_command(["npm", "i", *
|
|
395
|
-
if
|
|
566
|
+
ctx.run_command(["npm", "i", *npm_runtime], cwd=ctx.project_dir)
|
|
567
|
+
if npm_dev:
|
|
396
568
|
console.print("\n[bold]Installing dev dependencies...[/]")
|
|
397
|
-
ctx.run_command(["npm", "i", "-D", *
|
|
569
|
+
ctx.run_command(["npm", "i", "-D", *npm_dev], cwd=ctx.project_dir)
|
|
570
|
+
|
|
571
|
+
name = variables.get("name_underscore")
|
|
572
|
+
if not name:
|
|
573
|
+
return
|
|
574
|
+
if python_domain:
|
|
575
|
+
domain_root = ctx.project_dir / "packages" / "python" / f"{name}_domain"
|
|
576
|
+
console.print("\n[bold]Installing Python domain dependencies...[/]")
|
|
577
|
+
ctx.run_uv_command(["uv", "add", *python_domain], cwd=domain_root)
|
|
578
|
+
if python_api:
|
|
579
|
+
api_root = ctx.project_dir / "apps" / f"{name}_api"
|
|
580
|
+
console.print("\n[bold]Installing Python API dependencies...[/]")
|
|
581
|
+
ctx.run_uv_command(["uv", "add", *python_api], cwd=api_root)
|
|
398
582
|
|
|
399
583
|
|
|
400
584
|
def _resolve_target_path(
|
|
@@ -95,7 +95,10 @@ def domain(
|
|
|
95
95
|
# --- scaffold files ----------------------------------------------------
|
|
96
96
|
_write_base_entity(ctx, src_root / "models" / "entities" / "base.py")
|
|
97
97
|
_write_base_repo(ctx, src_root / "repos" / "base.py", pkg_name)
|
|
98
|
+
_write_encrypted_column(ctx, src_root / "utils" / "encrypted_column.py")
|
|
99
|
+
_write_logging(ctx, src_root / "utils" / "logging.py")
|
|
98
100
|
_write_domain_test(ctx, tests_root / "test_package.py", pkg_name)
|
|
101
|
+
_write_encrypted_column_test(ctx, tests_root / "test_encrypted_column.py", pkg_name)
|
|
99
102
|
if migrations:
|
|
100
103
|
_write_alembic_ini(ctx, domain_root / "alembic.ini")
|
|
101
104
|
_write_migration_env(ctx, migrations_root / "env.py", pkg_name)
|
|
@@ -267,6 +270,22 @@ def _write_base_repo(ctx: RunContext, path: Path, pkg_name_underscore: str) -> N
|
|
|
267
270
|
ctx.write_file(path, code)
|
|
268
271
|
|
|
269
272
|
|
|
273
|
+
def _write_encrypted_column(ctx: RunContext, path: Path) -> None:
|
|
274
|
+
code = _extract_first_code_block(_SCAFFOLD_DIR.parent / "special_files" / "encrypted_column.md")
|
|
275
|
+
ctx.write_file(path, code)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _write_logging(ctx: RunContext, path: Path) -> None:
|
|
279
|
+
code = _extract_first_code_block(_SCAFFOLD_DIR.parent / "special_files" / "logging.md")
|
|
280
|
+
ctx.write_file(path, code)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def _write_encrypted_column_test(ctx: RunContext, path: Path, pkg_name_underscore: str) -> None:
|
|
284
|
+
code = _extract_first_code_block(_SCAFFOLD_DIR.parent / "special_files" / "test_encrypted_column.md")
|
|
285
|
+
code = code.replace("{name_underscore}", pkg_name_underscore)
|
|
286
|
+
ctx.write_file(path, code)
|
|
287
|
+
|
|
288
|
+
|
|
270
289
|
def _write_domain_test(ctx: RunContext, path: Path, pkg_name_underscore: str) -> None:
|
|
271
290
|
content = f"""from {pkg_name_underscore}.config.settings import Settings
|
|
272
291
|
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from contextlib import chdir, contextmanager
|
|
4
4
|
import json
|
|
5
|
+
import sys
|
|
5
6
|
import re
|
|
6
7
|
import subprocess
|
|
7
8
|
import tomllib
|
|
@@ -21,8 +22,9 @@ from rpr.dependencies import (
|
|
|
21
22
|
npm_package_name,
|
|
22
23
|
python_package_name,
|
|
23
24
|
)
|
|
24
|
-
from rpr.generators.base import SyncConfig, load_rules
|
|
25
|
+
from rpr.generators.base import SYNC_TARGETS, SyncConfig, load_rules
|
|
25
26
|
from rpr.generators.claude import generate_claude_rules
|
|
27
|
+
from rpr.generators.codex import generate_codex_rules
|
|
26
28
|
from rpr.generators.copilot import generate_copilot_rules
|
|
27
29
|
from rpr.generators.cursor import generate_cursor_rules
|
|
28
30
|
from rpr.generators.gemini import generate_gemini_rules
|
|
@@ -36,13 +38,14 @@ ScaffoldName = Literal[
|
|
|
36
38
|
"instructions", "domain", "api", "ui", "web", "storybook", "engine"
|
|
37
39
|
]
|
|
38
40
|
|
|
39
|
-
_ALL_TARGETS =
|
|
41
|
+
_ALL_TARGETS = list(SYNC_TARGETS)
|
|
40
42
|
_TARGET_GENERATORS = {
|
|
41
43
|
"cursor": generate_cursor_rules,
|
|
42
44
|
"github": generate_github_rules,
|
|
43
45
|
"copilot": generate_copilot_rules,
|
|
44
46
|
"claude": generate_claude_rules,
|
|
45
47
|
"gemini": generate_gemini_rules,
|
|
48
|
+
"codex": generate_codex_rules,
|
|
46
49
|
}
|
|
47
50
|
_NX_BOOTSTRAP_ENV = {"NX_NO_CLOUD": "true"}
|
|
48
51
|
_ROOT_NODE_SCRIPTS = {
|
|
@@ -456,7 +459,7 @@ def _detect_uv_require_version() -> str:
|
|
|
456
459
|
text=True,
|
|
457
460
|
check=True,
|
|
458
461
|
)
|
|
459
|
-
except OSError, subprocess.CalledProcessError:
|
|
462
|
+
except (OSError, subprocess.CalledProcessError):
|
|
460
463
|
return ">=0"
|
|
461
464
|
|
|
462
465
|
match = re.search(r"(\d+\.\d+(?:\.\d+)?)", result.stdout)
|
|
@@ -737,6 +740,16 @@ FERNET_KEY=
|
|
|
737
740
|
|
|
738
741
|
# API
|
|
739
742
|
API_BASE_URL=http://localhost:8000
|
|
743
|
+
|
|
744
|
+
# vLLM
|
|
745
|
+
VLLM_BASE_URL=http://localhost:8000/v1
|
|
746
|
+
VLLM_API_KEY=EMPTY
|
|
747
|
+
VLLM_MODEL_ID=google/gemma-4-12B-it-qat-q4_0-gguf
|
|
748
|
+
# Optional multi-server catalog. Each reasoning-capable profile must match its
|
|
749
|
+
# server's reasoning parser. Omitted providerProperties.mode defaults to online.
|
|
750
|
+
# VLLM_MODEL_CATALOG=[{"id":"gemma","label":"Gemma","modelId":"google/gemma","baseUrl":"http://localhost:8000/v1","reasoningParser":"gemma4","supportsThinking":true}]
|
|
751
|
+
# VLLM_DEFAULT_MODEL_PROFILE_ID=gemma
|
|
752
|
+
VLLM_THINKING_EFFORT=high
|
|
740
753
|
"""
|
|
741
754
|
ctx.write_file(ctx.project_dir / ".env.example", content)
|
|
742
755
|
|
|
@@ -793,6 +806,11 @@ def init(
|
|
|
793
806
|
"--domain-migrations requires a scaffold that generates the domain "
|
|
794
807
|
"package, such as --scaffold domain or --scaffold api."
|
|
795
808
|
)
|
|
809
|
+
if not domain_migrations and "domain" in selected_scaffolds and sys.stdin.isatty():
|
|
810
|
+
domain_migrations = typer.confirm(
|
|
811
|
+
"Include Alembic database migrations for the domain package?",
|
|
812
|
+
default=False,
|
|
813
|
+
)
|
|
796
814
|
variables = _derive_variables(project_name)
|
|
797
815
|
project_dir = Path.cwd() / project_name
|
|
798
816
|
ctx = RunContext(dry_run=dry_run, project_dir=project_dir)
|