rpr-cli 0.2.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.2.1 → rpr_cli-0.3.3}/.github/agents/story.agent.md +1 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/PKG-INFO +14 -3
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/README.md +13 -2
- {rpr_cli-0.2.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.2.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/readonly.py +1 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/chat_service.py +1 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/checks/instructions.py +36 -2
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/checks/packages.py +44 -7
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/checks/workspace.py +9 -3
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/cli.py +2 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/add.py +200 -16
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/api.py +24 -4
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/domain.py +47 -3
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/engine.py +8 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/storybook.py +82 -108
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/ui.py +90 -82
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/init.py +161 -98
- rpr_cli-0.3.3/src/rpr/commands/rename.py +85 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/sync.py +32 -14
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/context.py +14 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/dependencies.py +4 -3
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/dependency_manifest_data.py +27 -32
- {rpr_cli-0.2.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.2.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.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/all.instructions.md +1 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/rust-engine.instructions.md +2 -1
- rpr_cli-0.3.3/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +91 -0
- {rpr_cli-0.2.1/Sample-dot-github → rpr_cli-0.3.3/src/rpr/scaffolds}/instructions/tooling.instructions.md +9 -8
- 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.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.spec.tsx +34 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.tsx +110 -24
- {rpr_cli-0.2.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.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.ts +1 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/types.ts +2 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/useChatSuggestions.ts +50 -59
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/types.ts +54 -2
- {rpr_cli-0.2.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.2.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.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/testing/createMockSuggestionProvider.ts +4 -0
- {rpr_cli-0.2.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.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.spec.tsx +25 -25
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.tsx +62 -42
- {rpr_cli-0.2.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.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/README.md +6 -6
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/index.ts +1 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/streaming.ts +2 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/types.ts +56 -2
- {rpr_cli-0.2.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.2.1 → rpr_cli-0.3.3}/src/rpr/templates/registry.py +106 -2
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/ui/theme.py +1 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/workspace.py +14 -1
- {rpr_cli-0.2.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.2.1 → rpr_cli-0.3.3}/stories/completed/01-rpr-init.md +1 -2
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/02-rpr-generate-domain.md +4 -4
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/07-rpr-sync-rules.md +0 -3
- rpr_cli-0.3.3/stories/package-maintenance/default-vite-8-oxc-toolchain.md +142 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/package-maintenance/rpr-update-packages.md +1 -1
- rpr_cli-0.3.3/stories/package-maintenance/typescript-7-frontend-scaffold-compatibility.md +123 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_add.py +75 -8
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_check.py +21 -11
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_context.py +30 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_generate_api.py +8 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_generate_domain.py +39 -6
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_generate_engine.py +2 -1
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_generate_storybook.py +23 -45
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_generate_ui.py +45 -16
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_init.py +120 -26
- 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.2.1/Sample-dot-github/instructions/all.instructions.md +0 -49
- rpr_cli-0.2.1/Sample-dot-github/instructions/domain.instructions.md +0 -96
- rpr_cli-0.2.1/Sample-dot-github/instructions/frontend.instructions.md +0 -98
- rpr_cli-0.2.1/Sample-dot-github/instructions/rust-engine.instructions.md +0 -40
- rpr_cli-0.2.1/Sample-dot-github/instructions/setup-guide.instructions.md +0 -89
- rpr_cli-0.2.1/Sample-dot-github/instructions/tooling-setup.instructions.md +0 -97
- rpr_cli-0.2.1/Sample-dot-github/scaffolds/README.md +0 -7
- rpr_cli-0.2.1/Sample-dot-github/scaffolds/api/main.py +0 -84
- rpr_cli-0.2.1/Sample-dot-github/scaffolds/domain/base-repo.md +0 -48
- rpr_cli-0.2.1/Sample-dot-github/scaffolds/domain/base_entity.md +0 -32
- rpr_cli-0.2.1/Sample-dot-github/scaffolds/frontend/api.service.ts +0 -200
- rpr_cli-0.2.1/Sample-dot-github/scaffolds/frontend/useStateNavigation.ts +0 -142
- rpr_cli-0.2.1/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.tsx +0 -112
- rpr_cli-0.2.1/src/rpr/__init__.py +0 -1
- rpr_cli-0.2.1/src/rpr/generators/claude.py +0 -33
- rpr_cli-0.2.1/src/rpr/scaffolds/domain/settings.md +0 -57
- rpr_cli-0.2.1/src/rpr/scaffolds/instructions/api.instructions.md +0 -42
- rpr_cli-0.2.1/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +0 -97
- rpr_cli-0.2.1/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -42
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/README.md +0 -349
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/client/index.ts +0 -1
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/client/types.ts +0 -45
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.spec.ts +0 -281
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.spec.tsx +0 -104
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.ts +0 -212
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/testing/createMockChatStreamClient.ts +0 -91
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.tsx +0 -93
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.spec.tsx +0 -147
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.tsx +0 -94
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.spec.tsx +0 -277
- rpr_cli-0.2.1/src/rpr/scaffolds/js_special_files/chat/virtual-list/index.ts +0 -1
- rpr_cli-0.2.1/src/rpr/scaffolds/special_files/domain_container.md +0 -74
- rpr_cli-0.2.1/src/rpr/scaffolds/special_files/domain_settings.md +0 -57
- rpr_cli-0.2.1/src/rpr/scaffolds/special_files/encrypted_column.md +0 -98
- rpr_cli-0.2.1/tests/test_sync.py +0 -202
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/.github/workflows/publish-pypi.yml +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/.gitignore +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/CLAUDE.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/GEMINI.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/LICENSE +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/changelogs/mui_v9.txt +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/nx_uv_setup.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/patch_output.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/plan-languageAwareTemplateAdd.prompt.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/pyproject.toml +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/Cargo.lock +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/Cargo.toml +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/pyproject.toml +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/rpr_parser.pyi +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/config/container.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/config/mod.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/config/settings.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/graph.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/lib.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/models/dtos/mod.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/models/entities/mod.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/models/entities/users.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/models/mod.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/parse.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/repos/base.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/repos/mod.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/repos/users.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/resolve.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/src/walker.rs +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/rpr-parser/uv.lock +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/special_files.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/approval.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/bootstrap.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/client.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/control.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/mock.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/runtime.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/session.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/base.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/mutating.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/agent/tools/registry.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/catalog.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/checks.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/cli_adapter.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/completer.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/conversation_service.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/prompt_service.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/selector.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/application/shell.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/checks/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/checks/base.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/chat.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/check.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/generate/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/map.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/refresh.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/settings.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/commands/update.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/generators/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/generators/cursor.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/generators/gemini.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/generators/github.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/manifest_refresh.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/architecture.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/chains.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/classifier.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/coverage.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/dependencies.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/extractor.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/graph.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/output.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/responsibility.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/topology.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/map/walker.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/package_updates.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/domain/base_entity.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/domain/base_repo.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/domain/container.md +0 -0
- {rpr_cli-0.2.1/Sample-dot-github → rpr_cli-0.3.3/src/rpr/scaffolds}/instructions/api.instructions.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/domain.instructions.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/frontend.instructions.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +0 -0
- {rpr_cli-0.2.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.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.spec.ts +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.ts +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/index.ts +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatSuggestionsPopover.tsx +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/LocalFileSuggestionAction.tsx +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/index.ts +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.spec.ts +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.ts +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/testing/index.ts +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/chat/thread/contentFormat.ts +0 -0
- {rpr_cli-0.2.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.2.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.2.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.2.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.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/sticky-navigation.spec.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/js_special_files/vitest-browser-config.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/special_files/camel_case_model.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/templates/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/ui/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/ui/console.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/ui/markdown.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/ui/prompt_session.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/src/rpr/ui/renderers.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/00-bootstrap-cli.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/03-rpr-generate-api.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/04-rpr-generate-ui.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/05-rpr-generate-engine.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/06-rpr-generate-storybook.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/08-rpr-add-template.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/09-rpr-check.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/10-rpr-domain-config.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/18-rpr-terminal-ui-foundation.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/19-rpr-markdown-rendering.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/20-rpr-chat-repl.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/21-rpr-agent-tool-loop.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/22-rpr-chat-tui.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/23-rpr-chat-unified-command-shell.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/24-rpr-async-chat-runtime-and-services.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/25-rpr-prompt-service-and-conversation-lifecycle.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/26-rpr-shared-command-catalog.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/27-rpr-slash-command-selection-panel.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/28-rpr-chat-cancellable-and-multiline-input.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/chat/29-rpr-file-context-selection.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/11-rpr-map-command.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/12-rpr-map-file-walker.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/13-rpr-map-rust-engine.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/13a-rpr-map-gitignore.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/14-rpr-map-graph-builder.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/15-rpr-map-analysis-bridge.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/16-rpr-map-layer-classifier.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/17-rpr-map-output.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/17a-rpr-map-directory-topology.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/17b-rpr-map-architecture-assessment.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/17c-rpr-map-representative-chains.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/completed/map/17d-rpr-map-multi-resolution-output.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/map/30-rpr-map-directory-view-and-cycle-detection.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/map/31-rpr-map-coupling-hotspots-and-verdict-reasoning.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/stories/map/32-rpr-map-dependencies-responsibilities-and-test-coverage.md +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/__init__.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_architecture.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_architecture_unwrapped.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_catalog.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_chat.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_chat_service.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_completer.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_chains.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_classifier.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_coverage.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_dependencies.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_extractor.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_graph.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_output.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_responsibility.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_topology.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_map_walker.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_package_updates.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_packaging.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_prompt_session.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_refresh.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_rpr_parser_stub.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_selector.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_settings.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_ui.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/tests/test_update_packages.py +0 -0
- {rpr_cli-0.2.1 → rpr_cli-0.3.3}/update_output.py +0 -0
- {rpr_cli-0.2.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
|
+
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
|
|
@@ -67,7 +67,7 @@ def check_packages(project_dir: Path, variables: dict[str, str]) -> list[CheckRe
|
|
|
67
67
|
_check_project_targets(
|
|
68
68
|
area="Domain targets",
|
|
69
69
|
project_json=domain_dir / "project.json",
|
|
70
|
-
required_targets={"build", "test", "lint"},
|
|
70
|
+
required_targets={"build", "test", "lint", "format", "format:check"},
|
|
71
71
|
suggestion=f"rpr generate domain {name}",
|
|
72
72
|
)
|
|
73
73
|
)
|
|
@@ -130,7 +130,14 @@ def check_packages(project_dir: Path, variables: dict[str, str]) -> list[CheckRe
|
|
|
130
130
|
_check_project_targets(
|
|
131
131
|
area="API targets",
|
|
132
132
|
project_json=api_dir / "project.json",
|
|
133
|
-
required_targets={
|
|
133
|
+
required_targets={
|
|
134
|
+
"serve",
|
|
135
|
+
"build",
|
|
136
|
+
"test",
|
|
137
|
+
"lint",
|
|
138
|
+
"format",
|
|
139
|
+
"format:check",
|
|
140
|
+
},
|
|
134
141
|
suggestion=f"rpr generate api {name}",
|
|
135
142
|
)
|
|
136
143
|
)
|
|
@@ -173,7 +180,14 @@ def check_packages(project_dir: Path, variables: dict[str, str]) -> list[CheckRe
|
|
|
173
180
|
_check_project_targets(
|
|
174
181
|
area="UI targets",
|
|
175
182
|
project_json=ui_dir / "project.json",
|
|
176
|
-
required_targets={
|
|
183
|
+
required_targets={
|
|
184
|
+
"build",
|
|
185
|
+
"lint",
|
|
186
|
+
"format",
|
|
187
|
+
"format:check",
|
|
188
|
+
"test",
|
|
189
|
+
"typecheck",
|
|
190
|
+
},
|
|
177
191
|
suggestion=f"rpr generate ui {name}",
|
|
178
192
|
)
|
|
179
193
|
)
|
|
@@ -202,7 +216,15 @@ def check_packages(project_dir: Path, variables: dict[str, str]) -> list[CheckRe
|
|
|
202
216
|
_check_project_targets(
|
|
203
217
|
area="Web targets",
|
|
204
218
|
project_json=web_dir / "project.json",
|
|
205
|
-
required_targets={
|
|
219
|
+
required_targets={
|
|
220
|
+
"serve",
|
|
221
|
+
"build",
|
|
222
|
+
"lint",
|
|
223
|
+
"format",
|
|
224
|
+
"format:check",
|
|
225
|
+
"test",
|
|
226
|
+
"typecheck",
|
|
227
|
+
},
|
|
206
228
|
suggestion=f"rpr generate ui {name} --no-library",
|
|
207
229
|
)
|
|
208
230
|
)
|
|
@@ -235,6 +257,8 @@ def check_packages(project_dir: Path, variables: dict[str, str]) -> list[CheckRe
|
|
|
235
257
|
"serve",
|
|
236
258
|
"build",
|
|
237
259
|
"lint",
|
|
260
|
+
"format",
|
|
261
|
+
"format:check",
|
|
238
262
|
"test",
|
|
239
263
|
"typecheck",
|
|
240
264
|
"storybook",
|
|
@@ -264,6 +288,19 @@ def check_packages(project_dir: Path, variables: dict[str, str]) -> list[CheckRe
|
|
|
264
288
|
)
|
|
265
289
|
)
|
|
266
290
|
if engine_dir is not None:
|
|
291
|
+
results.append(
|
|
292
|
+
_check_project_targets(
|
|
293
|
+
area="Engine targets",
|
|
294
|
+
project_json=engine_dir / "project.json",
|
|
295
|
+
required_targets={
|
|
296
|
+
"engine:build",
|
|
297
|
+
"engine:lint",
|
|
298
|
+
"format",
|
|
299
|
+
"format:check",
|
|
300
|
+
},
|
|
301
|
+
suggestion=f"rpr generate engine {name}",
|
|
302
|
+
)
|
|
303
|
+
)
|
|
267
304
|
results.append(
|
|
268
305
|
_check_engine_install_metadata(
|
|
269
306
|
engine_dir=engine_dir,
|
|
@@ -279,7 +316,7 @@ def _load_json(path: Path) -> dict[str, object] | None:
|
|
|
279
316
|
return None
|
|
280
317
|
try:
|
|
281
318
|
data = json.loads(path.read_text())
|
|
282
|
-
except OSError, json.JSONDecodeError:
|
|
319
|
+
except (OSError, json.JSONDecodeError):
|
|
283
320
|
return None
|
|
284
321
|
return data if isinstance(data, dict) else None
|
|
285
322
|
|
|
@@ -289,7 +326,7 @@ def _load_toml(path: Path) -> dict[str, object] | None:
|
|
|
289
326
|
return None
|
|
290
327
|
try:
|
|
291
328
|
data = tomllib.loads(path.read_text())
|
|
292
|
-
except OSError, tomllib.TOMLDecodeError:
|
|
329
|
+
except (OSError, tomllib.TOMLDecodeError):
|
|
293
330
|
return None
|
|
294
331
|
return data if isinstance(data, dict) else None
|
|
295
332
|
|
|
@@ -76,8 +76,12 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
|
|
|
76
76
|
uv_require_version = "required-version" in tool.get("uv", {})
|
|
77
77
|
pytest_config = "pytest" in tool and "ini_options" in tool["pytest"]
|
|
78
78
|
|
|
79
|
-
dependency_groups =
|
|
80
|
-
|
|
79
|
+
dependency_groups = (
|
|
80
|
+
pyproject_data.get("dependency-groups", {}) if pyproject_data else {}
|
|
81
|
+
)
|
|
82
|
+
dev_dependencies = (
|
|
83
|
+
dependency_groups.get("dev", []) if isinstance(dependency_groups, dict) else []
|
|
84
|
+
)
|
|
81
85
|
if isinstance(dev_dependencies, list):
|
|
82
86
|
required = {
|
|
83
87
|
"pytest",
|
|
@@ -139,7 +143,9 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
|
|
|
139
143
|
"nbstripout",
|
|
140
144
|
"uv run ruff format",
|
|
141
145
|
"uv run ruff check --fix",
|
|
142
|
-
"npx
|
|
146
|
+
"npx oxfmt --write .",
|
|
147
|
+
"npx nx run-many --target=lint --all --exclude=engine -- --fix",
|
|
148
|
+
"npx depcruise apps packages/node",
|
|
143
149
|
)
|
|
144
150
|
)
|
|
145
151
|
|
|
@@ -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(
|