rpr-cli 0.3.10__tar.gz → 0.3.12__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.10/README.md → rpr_cli-0.3.12/PKG-INFO +24 -3
- rpr_cli-0.3.10/PKG-INFO → rpr_cli-0.3.12/README.md +6 -21
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/pyproject.toml +9 -2
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/Cargo.lock +1 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/Cargo.toml +1 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/graph.rs +8 -15
- rpr_cli-0.3.12/rpr-parser/src/models/dtos/mod.rs +1 -0
- rpr_cli-0.3.12/rpr-parser/src/models/mod.rs +2 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/parse.rs +11 -6
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/resolve.rs +8 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/walker.rs +11 -2
- rpr_cli-0.3.12/src/rpr/__init__.py +1 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/tools/readonly.py +2 -2
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/catalog.py +18 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/chat_service.py +23 -2
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/checks.py +7 -3
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/prompt_service.py +1 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/shell.py +65 -11
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/checks/base.py +0 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/checks/packages.py +18 -9
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/checks/workspace.py +12 -5
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/cli.py +2 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/add.py +4 -4
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/check.py +10 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/generate/domain.py +1 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/generate/storybook.py +21 -86
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/generate/ui.py +22 -240
- rpr_cli-0.3.12/src/rpr/commands/generate/web.py +468 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/init.py +63 -59
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/rename.py +1 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/version.py +9 -9
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/context.py +2 -2
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/dependencies.py +17 -9
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/dependency_manifest_data.py +15 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/generators/base.py +18 -3
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/generators/claude.py +2 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/generators/cursor.py +3 -3
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/generators/github.py +3 -3
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/graph.py +3 -3
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/package_updates.py +3 -3
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/project_rename.py +21 -7
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/all.instructions.md +13 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/frontend.instructions.md +19 -2
- rpr_cli-0.3.12/src/rpr/scaffolds/instructions/notebook.instructions.md +10 -0
- rpr_cli-0.3.12/src/rpr/scaffolds/instructions/stories-tracking.instructions.md +12 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +3 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/templates/registry.py +9 -6
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/ui/prompt_session.py +1 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/ui/theme.py +14 -12
- rpr_cli-0.3.12/src/rpr/workspace.py +303 -0
- rpr_cli-0.3.10/rpr-parser/src/models/dtos/mod.rs +0 -0
- rpr_cli-0.3.10/rpr-parser/src/models/mod.rs +0 -2
- rpr_cli-0.3.10/src/rpr/__init__.py +0 -1
- rpr_cli-0.3.10/src/rpr/workspace.py +0 -139
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/LICENSE +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/config/container.rs +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/config/mod.rs +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/config/settings.rs +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/lib.rs +1 -1
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/models/entities/mod.rs +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/models/entities/users.rs +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/rename.rs +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/repos/base.rs +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/repos/mod.rs +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/rpr-parser/src/repos/users.rs +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/_native.pyi +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/approval.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/bootstrap.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/client.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/control.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/mock.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/runtime.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/session.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/tools/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/tools/base.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/tools/mutating.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/agent/tools/registry.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/cli_adapter.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/completer.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/conversation_service.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/application/selector.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/checks/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/checks/instructions.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/chat.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/generate/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/generate/api.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/generate/engine.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/map.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/refresh.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/settings.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/sync.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/commands/update.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/generators/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/generators/codex.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/generators/copilot.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/generators/gemini.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/manifest_refresh.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/architecture.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/chains.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/classifier.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/coverage.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/dependencies.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/extractor.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/output.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/responsibility.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/topology.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/map/walker.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/domain/base_entity.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/domain/base_repo.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/domain/container.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/domain/settings.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/api.instructions.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/domain.instructions.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/rust-engine.instructions.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/BACKEND_FLOW.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/README.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/content.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/httpChatStreamClient.spec.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/httpChatStreamClient.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/index.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/client/types.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.spec.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/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.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.spec.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/index.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatComposerMentionTokens.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatSuggestionsPopover.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/LocalFileSuggestionAction.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/index.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.spec.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.spec.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/types.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/useChatSuggestions.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/types.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/useChatComposer.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.spec.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperience.spec.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperience.styles.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperience.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceComposer.styles.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceComposer.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceHeader.styles.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ChatExperienceHeader.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ThreadHistory.styles.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/ThreadHistory.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/chatStorage.spec.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/chatStorage.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/index.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/types.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/useChatExperience.spec.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/experience/useChatExperience.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/index.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/testing/createMockChatStreamClient.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/testing/createMockSuggestionProvider.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/testing/index.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessage.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageActions.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.spec.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.spec.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/README.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/contentFormat.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/index.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/streaming.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/thread/types.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.spec.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.spec.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.tsx +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/chat/virtual-list/index.ts +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/sticky-navigation.spec.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/js_special_files/vitest-browser-config.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/api/routes/chat_routes.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/api/tests/test_chat.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/models/dtos/chat_dtos.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/models/dtos/conversation_history_dtos.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/models/entities/conversation_history.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/repos/conversation_history.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/agent_session_codec.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/chat_service.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/conversation_history_service.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/conversation_operations.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/history_codec.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/in_memory_history_store.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/postgres_history_store.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/protocols/conversation_history_store.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/protocols/conversation_runtime.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/services/protocols/llm_provider.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_chat_dtos.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_chat_service.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_history_codec.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_history_projection.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_persistence_config.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/chat/domain/tests/test_postgres_history_store.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/models/dtos/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/models/dtos/vllm_model_dtos.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/VLLM_SETUP.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/model_catalog.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/vllm_agent_factory.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/vllm_agent_factory_protocol.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/agents/vllm_inference_coordinator.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/runtimes/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/runtimes/agents_sdk.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/services/runtimes/agents_sdk_message_mapping.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/tests/test_agents_sdk_runtime.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/tests/test_vllm_model_catalog.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/py_special_files/vllm_provider/domain/tests/test_vllm_provider.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/camel_case_model.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/domain_container.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/domain_settings.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/encrypted_column.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/logging.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/scaffolds/special_files/test_encrypted_column.md +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/templates/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/ui/__init__.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/ui/console.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/ui/markdown.py +0 -0
- {rpr_cli-0.3.10 → rpr_cli-0.3.12}/src/rpr/ui/renderers.py +0 -0
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rpr-cli
|
|
3
|
+
Version: 0.3.12
|
|
4
|
+
Requires-Dist: typer>=0.24.1,<0.26
|
|
5
|
+
Requires-Dist: jinja2>=3.1.5
|
|
6
|
+
Requires-Dist: pyyaml>=6.0.2
|
|
7
|
+
Requires-Dist: rich>=14.3.3
|
|
8
|
+
Requires-Dist: pathspec>=1.0.4
|
|
9
|
+
Requires-Dist: prompt-toolkit>=3.0.52
|
|
10
|
+
Requires-Dist: tomlkit>=0.15.0
|
|
11
|
+
Requires-Dist: packaging>=26.2
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
|
|
14
|
+
License-Expression: MIT
|
|
15
|
+
Requires-Python: >=3.14
|
|
16
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
17
|
+
|
|
1
18
|
# RPR CLI
|
|
2
19
|
|
|
3
20
|
React Python Rust monorepo scaffolding orchestrator.
|
|
@@ -53,6 +70,7 @@ cd my-app
|
|
|
53
70
|
rpr generate domain my-app # Add a Python domain package
|
|
54
71
|
rpr generate api my-app # Add a FastAPI application
|
|
55
72
|
rpr generate ui my-app # Add a React UI library and web app
|
|
73
|
+
rpr generate web landing # Add another web app; asks whether to depend on the UI library
|
|
56
74
|
rpr generate engine my-app # Add a Rust/PyO3 computation engine
|
|
57
75
|
rpr generate storybook # Add Storybook for UI component development
|
|
58
76
|
rpr rename new-app # Rename the workspace identity and references
|
|
@@ -107,14 +125,16 @@ Available scaffolds are:
|
|
|
107
125
|
|
|
108
126
|
### Dependency Placement
|
|
109
127
|
|
|
110
|
-
RPR keeps dependencies close to the package that uses them.
|
|
128
|
+
RPR keeps Python dependencies close to the package that uses them and Node dependencies at the workspace root.
|
|
111
129
|
|
|
112
130
|
- Root Python tooling such as Ruff, pytest, pyright, pre-commit, and maturin lives in the root `pyproject.toml`.
|
|
113
131
|
- Domain runtime dependencies such as `sqlmodel`, `asyncpg`, `pydantic-settings`, and optional `alembic` are added to `packages/python/domain/pyproject.toml`.
|
|
114
132
|
- API runtime dependencies such as `fastapi`, `uvicorn`, and the workspace domain package are added to `apps/<name>-api/pyproject.toml`.
|
|
115
|
-
- Node dependencies are
|
|
133
|
+
- Node dependencies are declared and installed only in the root `package.json`, so every app and package shares one version of each. Package-level `package.json` files carry metadata and workspace links such as `@my-app/ui`. Generators install only the dependencies the root does not already declare, so adding another app never bumps existing versions.
|
|
134
|
+
|
|
135
|
+
`rpr generate web <name>` adds another web app (for example a landing page) at `apps/<name>-web`. When a UI library exists it asks whether to add the library as a dependency (`--link-ui` / `--no-link-ui` skip the prompt); linked apps get a starter page in the library's `src/pages/`, and unlinked apps are fully standalone. Each web app gets its own dev-server port (3000, 3001, ...), so `npx nx serve <name>-web` runs alongside the others. The generated workspace requires Node 24 LTS or newer.
|
|
116
136
|
|
|
117
|
-
Python dependency changes are made with `uv` so they are tracked in `pyproject.toml`. Node dependency changes are made
|
|
137
|
+
Python dependency changes are made with `uv` so they are tracked in `pyproject.toml`. Node dependency changes are made from the root with `npm install`.
|
|
118
138
|
|
|
119
139
|
Update project-owned package manifests from upstream registries with `rpr update node` or `rpr update python`. Node updates target `package.json`; Python updates target `pyproject.toml` by default and fall back to `requirements.txt` when no `pyproject.toml` exists. Use `--file` to update a nested manifest, `--dry-run` to preview without changing files or running installers, and `--include-major` to opt into major-version updates.
|
|
120
140
|
|
|
@@ -278,3 +298,4 @@ git push origin main --tags
|
|
|
278
298
|
The workflow in `.github/workflows/publish-pypi.yml` checks both version declarations against the
|
|
279
299
|
tag, builds an sdist plus native wheels for Linux x86-64/AArch64, Windows x86-64, and macOS
|
|
280
300
|
x86-64/Apple Silicon, then publishes all artifacts to PyPI.
|
|
301
|
+
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: rpr-cli
|
|
3
|
-
Version: 0.3.10
|
|
4
|
-
Requires-Dist: typer>=0.24.1
|
|
5
|
-
Requires-Dist: jinja2>=3.1.5
|
|
6
|
-
Requires-Dist: pyyaml>=6.0.2
|
|
7
|
-
Requires-Dist: rich>=14.3.3
|
|
8
|
-
Requires-Dist: pathspec>=1.0.4
|
|
9
|
-
Requires-Dist: prompt-toolkit>=3.0.52
|
|
10
|
-
Requires-Dist: tomlkit>=0.15.0
|
|
11
|
-
Requires-Dist: packaging>=26.2
|
|
12
|
-
License-File: LICENSE
|
|
13
|
-
Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
|
|
14
|
-
License-Expression: MIT
|
|
15
|
-
Requires-Python: >=3.14
|
|
16
|
-
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
17
|
-
|
|
18
1
|
# RPR CLI
|
|
19
2
|
|
|
20
3
|
React Python Rust monorepo scaffolding orchestrator.
|
|
@@ -70,6 +53,7 @@ cd my-app
|
|
|
70
53
|
rpr generate domain my-app # Add a Python domain package
|
|
71
54
|
rpr generate api my-app # Add a FastAPI application
|
|
72
55
|
rpr generate ui my-app # Add a React UI library and web app
|
|
56
|
+
rpr generate web landing # Add another web app; asks whether to depend on the UI library
|
|
73
57
|
rpr generate engine my-app # Add a Rust/PyO3 computation engine
|
|
74
58
|
rpr generate storybook # Add Storybook for UI component development
|
|
75
59
|
rpr rename new-app # Rename the workspace identity and references
|
|
@@ -124,14 +108,16 @@ Available scaffolds are:
|
|
|
124
108
|
|
|
125
109
|
### Dependency Placement
|
|
126
110
|
|
|
127
|
-
RPR keeps dependencies close to the package that uses them.
|
|
111
|
+
RPR keeps Python dependencies close to the package that uses them and Node dependencies at the workspace root.
|
|
128
112
|
|
|
129
113
|
- Root Python tooling such as Ruff, pytest, pyright, pre-commit, and maturin lives in the root `pyproject.toml`.
|
|
130
114
|
- Domain runtime dependencies such as `sqlmodel`, `asyncpg`, `pydantic-settings`, and optional `alembic` are added to `packages/python/domain/pyproject.toml`.
|
|
131
115
|
- API runtime dependencies such as `fastapi`, `uvicorn`, and the workspace domain package are added to `apps/<name>-api/pyproject.toml`.
|
|
132
|
-
- Node dependencies are
|
|
116
|
+
- Node dependencies are declared and installed only in the root `package.json`, so every app and package shares one version of each. Package-level `package.json` files carry metadata and workspace links such as `@my-app/ui`. Generators install only the dependencies the root does not already declare, so adding another app never bumps existing versions.
|
|
117
|
+
|
|
118
|
+
`rpr generate web <name>` adds another web app (for example a landing page) at `apps/<name>-web`. When a UI library exists it asks whether to add the library as a dependency (`--link-ui` / `--no-link-ui` skip the prompt); linked apps get a starter page in the library's `src/pages/`, and unlinked apps are fully standalone. Each web app gets its own dev-server port (3000, 3001, ...), so `npx nx serve <name>-web` runs alongside the others. The generated workspace requires Node 24 LTS or newer.
|
|
133
119
|
|
|
134
|
-
Python dependency changes are made with `uv` so they are tracked in `pyproject.toml`. Node dependency changes are made
|
|
120
|
+
Python dependency changes are made with `uv` so they are tracked in `pyproject.toml`. Node dependency changes are made from the root with `npm install`.
|
|
135
121
|
|
|
136
122
|
Update project-owned package manifests from upstream registries with `rpr update node` or `rpr update python`. Node updates target `package.json`; Python updates target `pyproject.toml` by default and fall back to `requirements.txt` when no `pyproject.toml` exists. Use `--file` to update a nested manifest, `--dry-run` to preview without changing files or running installers, and `--include-major` to opt into major-version updates.
|
|
137
123
|
|
|
@@ -295,4 +281,3 @@ git push origin main --tags
|
|
|
295
281
|
The workflow in `.github/workflows/publish-pypi.yml` checks both version declarations against the
|
|
296
282
|
tag, builds an sdist plus native wheels for Linux x86-64/AArch64, Windows x86-64, and macOS
|
|
297
283
|
x86-64/Apple Silicon, then publishes all artifacts to PyPI.
|
|
298
|
-
|
|
@@ -6,7 +6,7 @@ readme = "README.md"
|
|
|
6
6
|
license = "MIT"
|
|
7
7
|
requires-python = ">=3.14"
|
|
8
8
|
dependencies = [
|
|
9
|
-
"typer>=0.24.1",
|
|
9
|
+
"typer>=0.24.1,<0.26",
|
|
10
10
|
"jinja2>=3.1.5",
|
|
11
11
|
"pyyaml>=6.0.2",
|
|
12
12
|
"rich>=14.3.3",
|
|
@@ -20,7 +20,7 @@ dependencies = [
|
|
|
20
20
|
rpr = "rpr.cli:app"
|
|
21
21
|
|
|
22
22
|
[dependency-groups]
|
|
23
|
-
dev = ["pytest>=9.0.2", "maturin>=1.
|
|
23
|
+
dev = ["pytest>=9.0.2", "maturin>=1.12.6,<2.0", "ruff>=0.15"]
|
|
24
24
|
|
|
25
25
|
[build-system]
|
|
26
26
|
requires = ["maturin>=1.12.6,<2.0"]
|
|
@@ -35,3 +35,10 @@ include = [{ path = "LICENSE", format = "sdist" }]
|
|
|
35
35
|
|
|
36
36
|
[tool.pytest.ini_options]
|
|
37
37
|
testpaths = ["tests"]
|
|
38
|
+
|
|
39
|
+
[tool.ruff]
|
|
40
|
+
# The scaffolds are templates (many are not valid Python/TS until rendered).
|
|
41
|
+
extend-exclude = ["src/rpr/scaffolds", "rpr-parser/target"]
|
|
42
|
+
|
|
43
|
+
[tool.ruff.lint]
|
|
44
|
+
select = ["E4", "E7", "E9", "F"]
|
|
@@ -127,14 +127,9 @@ fn dfs_iterative<'a>(
|
|
|
127
127
|
match color.get(neighbor).copied().unwrap_or(0) {
|
|
128
128
|
1 => {
|
|
129
129
|
// Back edge — found a cycle. Trace path back to neighbor.
|
|
130
|
-
let cycle_start = path
|
|
131
|
-
|
|
132
|
-
.
|
|
133
|
-
.unwrap_or(0);
|
|
134
|
-
let mut cycle: Vec<String> = path[cycle_start..]
|
|
135
|
-
.iter()
|
|
136
|
-
.map(|s| s.to_string())
|
|
137
|
-
.collect();
|
|
130
|
+
let cycle_start = path.iter().position(|&n| n == neighbor).unwrap_or(0);
|
|
131
|
+
let mut cycle: Vec<String> =
|
|
132
|
+
path[cycle_start..].iter().map(|s| s.to_string()).collect();
|
|
138
133
|
cycle.push(neighbor.to_string()); // close the cycle
|
|
139
134
|
cycles.push(cycle);
|
|
140
135
|
}
|
|
@@ -163,12 +158,7 @@ mod tests {
|
|
|
163
158
|
fn edges(pairs: &[(&str, &[&str])]) -> HashMap<String, Vec<String>> {
|
|
164
159
|
pairs
|
|
165
160
|
.iter()
|
|
166
|
-
.map(|(k, vs)|
|
|
167
|
-
(
|
|
168
|
-
k.to_string(),
|
|
169
|
-
vs.iter().map(|s| s.to_string()).collect(),
|
|
170
|
-
)
|
|
171
|
-
})
|
|
161
|
+
.map(|(k, vs)| (k.to_string(), vs.iter().map(|s| s.to_string()).collect()))
|
|
172
162
|
.collect()
|
|
173
163
|
}
|
|
174
164
|
|
|
@@ -235,7 +225,10 @@ mod tests {
|
|
|
235
225
|
// Simulate what build() does for dedup
|
|
236
226
|
let deps = vec!["B".to_string(), "B".to_string(), "C".to_string()];
|
|
237
227
|
let mut seen: HashSet<String> = HashSet::new();
|
|
238
|
-
let deduped: Vec<String> = deps
|
|
228
|
+
let deduped: Vec<String> = deps
|
|
229
|
+
.into_iter()
|
|
230
|
+
.filter(|d| seen.insert(d.clone()))
|
|
231
|
+
.collect();
|
|
239
232
|
assert_eq!(deduped.len(), 2);
|
|
240
233
|
assert!(deduped.contains(&"B".to_string()));
|
|
241
234
|
assert!(deduped.contains(&"C".to_string()));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -166,7 +166,10 @@ fn extract_js_ts_imports(source: &[u8], parser: &mut Parser) -> Vec<String> {
|
|
|
166
166
|
let mut cursor = node.walk();
|
|
167
167
|
for child in node.children(&mut cursor) {
|
|
168
168
|
if child.kind() == "string" {
|
|
169
|
-
let raw = node_text(child, source)
|
|
169
|
+
let raw = node_text(child, source)
|
|
170
|
+
.trim_matches('"')
|
|
171
|
+
.trim_matches('\'')
|
|
172
|
+
.to_string();
|
|
170
173
|
if !raw.is_empty() {
|
|
171
174
|
imports.push(raw);
|
|
172
175
|
}
|
|
@@ -257,7 +260,9 @@ fn parse_rust(source: &[u8]) -> Vec<String> {
|
|
|
257
260
|
// Only `mod foo;` (without a body block), not `mod foo { ... }`
|
|
258
261
|
let has_body = {
|
|
259
262
|
let mut cursor = node.walk();
|
|
260
|
-
let result = node
|
|
263
|
+
let result = node
|
|
264
|
+
.children(&mut cursor)
|
|
265
|
+
.any(|c| c.kind() == "declaration_list");
|
|
261
266
|
result
|
|
262
267
|
};
|
|
263
268
|
if !has_body {
|
|
@@ -317,9 +322,7 @@ fn parse_cpp(source: &[u8]) -> Vec<String> {
|
|
|
317
322
|
match child.kind() {
|
|
318
323
|
"string_literal" => {
|
|
319
324
|
// Quoted include — keep it (strip surrounding quotes)
|
|
320
|
-
let raw = node_text(child, source)
|
|
321
|
-
.trim_matches('"')
|
|
322
|
-
.to_string();
|
|
325
|
+
let raw = node_text(child, source).trim_matches('"').to_string();
|
|
323
326
|
if !raw.is_empty() {
|
|
324
327
|
imports.push(raw);
|
|
325
328
|
}
|
|
@@ -475,7 +478,9 @@ mod tests {
|
|
|
475
478
|
let f = rs_file();
|
|
476
479
|
let src = b"use crate::map::walker;";
|
|
477
480
|
let result = parse_imports(&f, src);
|
|
478
|
-
assert!(result
|
|
481
|
+
assert!(result
|
|
482
|
+
.iter()
|
|
483
|
+
.any(|s| s.contains("map") && s.contains("walker")));
|
|
479
484
|
}
|
|
480
485
|
|
|
481
486
|
#[test]
|
|
@@ -3,7 +3,14 @@ use std::collections::HashMap;
|
|
|
3
3
|
use std::path::{Path, PathBuf};
|
|
4
4
|
|
|
5
5
|
const TS_JS_EXTENSIONS: &[&str] = &["ts", "tsx", "js", "jsx", "mjs", "cjs"];
|
|
6
|
-
const INDEX_NAMES: &[&str] = &[
|
|
6
|
+
const INDEX_NAMES: &[&str] = &[
|
|
7
|
+
"index.ts",
|
|
8
|
+
"index.tsx",
|
|
9
|
+
"index.js",
|
|
10
|
+
"index.jsx",
|
|
11
|
+
"index.mjs",
|
|
12
|
+
"index.cjs",
|
|
13
|
+
];
|
|
7
14
|
|
|
8
15
|
pub fn resolve_imports(
|
|
9
16
|
file: &SourceFile,
|
|
@@ -2,8 +2,17 @@ use ignore::WalkBuilder;
|
|
|
2
2
|
use std::path::{Path, PathBuf};
|
|
3
3
|
|
|
4
4
|
const IGNORED_DIRS: &[&str] = &[
|
|
5
|
-
".venv",
|
|
6
|
-
"
|
|
5
|
+
".venv",
|
|
6
|
+
"venv",
|
|
7
|
+
".env",
|
|
8
|
+
"node_modules",
|
|
9
|
+
"__pycache__",
|
|
10
|
+
"dist",
|
|
11
|
+
"build",
|
|
12
|
+
".nx",
|
|
13
|
+
"target",
|
|
14
|
+
".git",
|
|
15
|
+
"vendor",
|
|
7
16
|
];
|
|
8
17
|
|
|
9
18
|
#[derive(Debug, Clone, PartialEq)]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.12"
|
|
@@ -31,7 +31,7 @@ class ReadFileTool(AgentTool):
|
|
|
31
31
|
path = resolve_project_path(ctx.project_dir, arguments.get("path"))
|
|
32
32
|
start_line = int(arguments.get("start_line", 1))
|
|
33
33
|
end_line = arguments.get("end_line")
|
|
34
|
-
content = path.read_text()
|
|
34
|
+
content = path.read_text(encoding="utf-8")
|
|
35
35
|
lines = content.splitlines()
|
|
36
36
|
if end_line is None:
|
|
37
37
|
end_line = len(lines)
|
|
@@ -122,7 +122,7 @@ class SearchTextTool(AgentTool):
|
|
|
122
122
|
)
|
|
123
123
|
path = current_root / file_name
|
|
124
124
|
try:
|
|
125
|
-
content = path.read_text()
|
|
125
|
+
content = path.read_text(encoding="utf-8")
|
|
126
126
|
except (OSError, UnicodeDecodeError):
|
|
127
127
|
continue
|
|
128
128
|
|
|
@@ -188,6 +188,23 @@ COMMAND_CATALOG: tuple[CommandDefinition, ...] = (
|
|
|
188
188
|
),
|
|
189
189
|
),
|
|
190
190
|
),
|
|
191
|
+
CommandDefinition(
|
|
192
|
+
name="web",
|
|
193
|
+
description="Generate a web app.",
|
|
194
|
+
action_id="generate.web",
|
|
195
|
+
arguments=(CommandArgument("name", "App name."),),
|
|
196
|
+
options=(
|
|
197
|
+
CommandOption(
|
|
198
|
+
"--ui-package",
|
|
199
|
+
"Target UI package.",
|
|
200
|
+
kind="value",
|
|
201
|
+
value_name="PACKAGE",
|
|
202
|
+
),
|
|
203
|
+
CommandOption(
|
|
204
|
+
"--dry-run", "Preview changes without writing.", kind="flag"
|
|
205
|
+
),
|
|
206
|
+
),
|
|
207
|
+
),
|
|
191
208
|
CommandDefinition(
|
|
192
209
|
name="engine",
|
|
193
210
|
description="Generate a Rust engine package.",
|
|
@@ -462,7 +479,7 @@ def usage_string(cmd: CommandDefinition) -> str:
|
|
|
462
479
|
|
|
463
480
|
Group commands show pipe-separated child names::
|
|
464
481
|
|
|
465
|
-
/generate <domain|api|ui|engine|storybook>
|
|
482
|
+
/generate <domain|api|ui|web|engine|storybook>
|
|
466
483
|
|
|
467
484
|
Leaf commands show arguments and options::
|
|
468
485
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import sys
|
|
4
5
|
from collections import deque
|
|
5
6
|
from contextlib import suppress
|
|
6
7
|
from dataclasses import dataclass
|
|
@@ -9,7 +10,9 @@ from typing import ClassVar
|
|
|
9
10
|
|
|
10
11
|
from prompt_toolkit import print_formatted_text
|
|
11
12
|
from prompt_toolkit.application.current import get_app_session
|
|
13
|
+
from prompt_toolkit.data_structures import Size
|
|
12
14
|
from prompt_toolkit.formatted_text import FormattedText
|
|
15
|
+
from prompt_toolkit.output.vt100 import Vt100_Output
|
|
13
16
|
|
|
14
17
|
from rpr.agent.approval import ApprovalDecision, ApprovalMode
|
|
15
18
|
from rpr.agent.bootstrap import build_chat_runtime_bundle
|
|
@@ -26,7 +29,7 @@ from rpr.application.completer import (
|
|
|
26
29
|
from rpr.application.prompt_service import PromptService
|
|
27
30
|
from rpr.application.shell import CommandShellService, ShellPresenter
|
|
28
31
|
from rpr.context import RunContext
|
|
29
|
-
from rpr.ui.console import
|
|
32
|
+
from rpr.ui.console import refresh_console
|
|
30
33
|
from rpr.ui.renderers import (
|
|
31
34
|
render_approval_prompt,
|
|
32
35
|
render_chat_hint,
|
|
@@ -47,6 +50,24 @@ type AgentClientFactory = Callable[[str | None, str | None], AgentClient]
|
|
|
47
50
|
type ContextFactory = Callable[[], RunContext]
|
|
48
51
|
|
|
49
52
|
|
|
53
|
+
def _terminal_output():
|
|
54
|
+
"""Return prompt_toolkit's output, falling back to plain stdout.
|
|
55
|
+
|
|
56
|
+
On Windows prompt_toolkit raises when stdout is not a real console (piped
|
|
57
|
+
output, CI, redirected runs). Binding a plain VT100 writer to `sys.stdout`
|
|
58
|
+
keeps `rpr chat` working there; `reset()` clears it with the app session.
|
|
59
|
+
"""
|
|
60
|
+
session = get_app_session()
|
|
61
|
+
try:
|
|
62
|
+
return session.output
|
|
63
|
+
except Exception:
|
|
64
|
+
output = Vt100_Output(
|
|
65
|
+
sys.stdout, lambda: Size(rows=24, columns=80), term="dumb"
|
|
66
|
+
)
|
|
67
|
+
session._output = output
|
|
68
|
+
return output
|
|
69
|
+
|
|
70
|
+
|
|
50
71
|
@dataclass(slots=True)
|
|
51
72
|
class AssistantStreamRenderer:
|
|
52
73
|
_accumulated: str = ""
|
|
@@ -54,7 +75,7 @@ class AssistantStreamRenderer:
|
|
|
54
75
|
|
|
55
76
|
def append(self, chunk: str) -> None:
|
|
56
77
|
self._accumulated += chunk
|
|
57
|
-
output =
|
|
78
|
+
output = _terminal_output()
|
|
58
79
|
if self._lines_printed > 0:
|
|
59
80
|
output.cursor_up(self._lines_printed)
|
|
60
81
|
output.erase_down()
|
|
@@ -3,16 +3,20 @@ from __future__ import annotations
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
+
from rpr.checks.base import CheckResult
|
|
6
7
|
from rpr.checks.instructions import check_instructions
|
|
7
8
|
from rpr.checks.packages import check_packages
|
|
8
9
|
from rpr.checks.workspace import check_workspace
|
|
9
10
|
from rpr.generators.base import SyncConfig
|
|
10
11
|
|
|
11
12
|
|
|
13
|
+
CHECK_GROUPS = ("workspace", "instructions", "packages")
|
|
14
|
+
|
|
15
|
+
|
|
12
16
|
@dataclass(slots=True, frozen=True)
|
|
13
17
|
class CheckReport:
|
|
14
18
|
project_name: str
|
|
15
|
-
results: list[
|
|
19
|
+
results: list[CheckResult]
|
|
16
20
|
|
|
17
21
|
|
|
18
22
|
def collect_check_report(project_dir: Path, group: str | None = None) -> CheckReport:
|
|
@@ -22,7 +26,7 @@ def collect_check_report(project_dir: Path, group: str | None = None) -> CheckRe
|
|
|
22
26
|
variables = config.variables or {}
|
|
23
27
|
project_name = variables.get("name", "(unknown)")
|
|
24
28
|
requested_group = None if group is None else group.lower()
|
|
25
|
-
results: list[
|
|
29
|
+
results: list[CheckResult] = []
|
|
26
30
|
|
|
27
31
|
if requested_group in {None, "workspace"}:
|
|
28
32
|
results.extend(check_workspace(project_dir))
|
|
@@ -36,7 +40,7 @@ def collect_check_report(project_dir: Path, group: str | None = None) -> CheckRe
|
|
|
36
40
|
return CheckReport(project_name=project_name, results=results)
|
|
37
41
|
|
|
38
42
|
|
|
39
|
-
def serialize_check_results(results: list[
|
|
43
|
+
def serialize_check_results(results: list[CheckResult]) -> list[dict[str, object]]:
|
|
40
44
|
return [
|
|
41
45
|
{
|
|
42
46
|
"group": result.group,
|
|
@@ -12,7 +12,7 @@ from rpr.agent.session import ChatSession
|
|
|
12
12
|
from rpr.application.conversation_service import (
|
|
13
13
|
ConversationService,
|
|
14
14
|
ConversationSummary,
|
|
15
|
-
InMemoryConversationRepository,
|
|
15
|
+
InMemoryConversationRepository, # noqa: F401 (re-exported)
|
|
16
16
|
)
|
|
17
17
|
from rpr.ui.prompt_session import PromptSessionAdapter
|
|
18
18
|
|
|
@@ -6,6 +6,7 @@ from dataclasses import dataclass
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import ClassVar, Protocol
|
|
8
8
|
|
|
9
|
+
import click
|
|
9
10
|
import typer
|
|
10
11
|
|
|
11
12
|
from rpr.agent.bootstrap import ChatRuntimeBundle
|
|
@@ -287,6 +288,7 @@ class CommandShellService:
|
|
|
287
288
|
self._active_presenter.info(f"Running /init for {project_name}.")
|
|
288
289
|
exit_code = self._invoke_command(
|
|
289
290
|
init_command.init,
|
|
291
|
+
typer.Context(click.Command("init")),
|
|
290
292
|
project_name=project_name,
|
|
291
293
|
dry_run=namespace.dry_run,
|
|
292
294
|
python_version=namespace.python,
|
|
@@ -301,6 +303,9 @@ class CommandShellService:
|
|
|
301
303
|
from rpr.commands.generate import engine as generate_engine_command
|
|
302
304
|
from rpr.commands.generate import storybook as generate_storybook_command
|
|
303
305
|
from rpr.commands.generate import ui as generate_ui_command
|
|
306
|
+
from rpr.commands.generate import web as generate_web_command
|
|
307
|
+
from rpr.dependencies import node_project_name, ui_package_name
|
|
308
|
+
from rpr.workspace import find_ui_packages
|
|
304
309
|
|
|
305
310
|
parser = ShellArgumentParser(prog="/generate", add_help=False)
|
|
306
311
|
subparsers = parser.add_subparsers(dest="target")
|
|
@@ -314,11 +319,21 @@ class CommandShellService:
|
|
|
314
319
|
storybook_parser.add_argument("--dry-run", action="store_true")
|
|
315
320
|
storybook_parser.add_argument("--ui-package")
|
|
316
321
|
|
|
322
|
+
web_parser = subparsers.add_parser("web", add_help=False)
|
|
323
|
+
web_parser.add_argument("name", nargs="?")
|
|
324
|
+
web_parser.add_argument("--dry-run", action="store_true")
|
|
325
|
+
web_parser.add_argument("--ui-package")
|
|
326
|
+
web_parser.add_argument(
|
|
327
|
+
"--link-ui", action=argparse.BooleanOptionalAction, default=None
|
|
328
|
+
)
|
|
329
|
+
|
|
317
330
|
namespace = self._parse_args(parser, parsed.args)
|
|
318
331
|
if namespace is None:
|
|
319
332
|
return True
|
|
320
333
|
if namespace.target is None:
|
|
321
|
-
raise ValueError(
|
|
334
|
+
raise ValueError(
|
|
335
|
+
"Usage: /generate <domain|api|ui|web|engine|storybook> ..."
|
|
336
|
+
)
|
|
322
337
|
|
|
323
338
|
if namespace.target == "domain":
|
|
324
339
|
name = namespace.name or await self._active_prompts.prompt("App name")
|
|
@@ -345,11 +360,43 @@ class CommandShellService:
|
|
|
345
360
|
)
|
|
346
361
|
return True
|
|
347
362
|
|
|
363
|
+
if namespace.target == "web":
|
|
364
|
+
name = namespace.name or await self._active_prompts.prompt("App name")
|
|
365
|
+
ui_package = namespace.ui_package
|
|
366
|
+
link_ui = namespace.link_ui
|
|
367
|
+
ui_packages = find_ui_packages(self._bundle.ctx.project_dir)
|
|
368
|
+
if ui_packages and not ui_package:
|
|
369
|
+
ui_package = ui_packages[0]
|
|
370
|
+
if len(ui_packages) > 1:
|
|
371
|
+
self._active_presenter.table(
|
|
372
|
+
"Web App Targets",
|
|
373
|
+
["Package"],
|
|
374
|
+
[[package] for package in ui_packages],
|
|
375
|
+
)
|
|
376
|
+
ui_package = (
|
|
377
|
+
await self._active_prompts.prompt(
|
|
378
|
+
"UI package", default=ui_packages[0]
|
|
379
|
+
)
|
|
380
|
+
).strip() or ui_packages[0]
|
|
381
|
+
if ui_package and link_ui is None:
|
|
382
|
+
answer = await self._active_prompts.prompt(
|
|
383
|
+
f"Add {ui_package_name(ui_package)} as a dependency of "
|
|
384
|
+
f"{node_project_name(name, 'web')}? (Y/n)",
|
|
385
|
+
default="y",
|
|
386
|
+
)
|
|
387
|
+
link_ui = answer.strip().lower() not in {"n", "no"}
|
|
388
|
+
self._invoke_command(
|
|
389
|
+
generate_web_command.web,
|
|
390
|
+
name=name,
|
|
391
|
+
ui_package=ui_package,
|
|
392
|
+
link_ui=link_ui,
|
|
393
|
+
dry_run=namespace.dry_run,
|
|
394
|
+
)
|
|
395
|
+
return True
|
|
396
|
+
|
|
348
397
|
ui_package = namespace.ui_package
|
|
349
398
|
if not ui_package:
|
|
350
|
-
ui_packages =
|
|
351
|
-
self._bundle.ctx.project_dir
|
|
352
|
-
)
|
|
399
|
+
ui_packages = find_ui_packages(self._bundle.ctx.project_dir)
|
|
353
400
|
if len(ui_packages) == 1:
|
|
354
401
|
ui_package = ui_packages[0]
|
|
355
402
|
elif len(ui_packages) > 1:
|
|
@@ -376,7 +423,7 @@ class CommandShellService:
|
|
|
376
423
|
|
|
377
424
|
parser = ShellArgumentParser(prog="/sync", add_help=False)
|
|
378
425
|
parser.add_argument("action", nargs="?", default="rules")
|
|
379
|
-
parser.add_argument("--target")
|
|
426
|
+
parser.add_argument("--target", action="append")
|
|
380
427
|
parser.add_argument("--dry-run", action="store_true")
|
|
381
428
|
namespace = self._parse_args(parser, parsed.args)
|
|
382
429
|
if namespace is None:
|
|
@@ -385,7 +432,9 @@ class CommandShellService:
|
|
|
385
432
|
raise ValueError("Usage: /sync [rules] [--target cursor] [--dry-run]")
|
|
386
433
|
|
|
387
434
|
self._invoke_command(
|
|
388
|
-
sync_command.rules,
|
|
435
|
+
sync_command.rules,
|
|
436
|
+
target=namespace.target or [],
|
|
437
|
+
dry_run=namespace.dry_run,
|
|
389
438
|
)
|
|
390
439
|
return True
|
|
391
440
|
|
|
@@ -395,6 +444,7 @@ class CommandShellService:
|
|
|
395
444
|
parser = ShellArgumentParser(prog="/add", add_help=False)
|
|
396
445
|
parser.add_argument("action", nargs="?", default="template")
|
|
397
446
|
parser.add_argument("template_id", nargs="?")
|
|
447
|
+
parser.add_argument("template_name", nargs="?")
|
|
398
448
|
parser.add_argument("--list", action="store_true")
|
|
399
449
|
parser.add_argument("--force", action="store_true")
|
|
400
450
|
parser.add_argument("--name")
|
|
@@ -405,16 +455,20 @@ class CommandShellService:
|
|
|
405
455
|
return True
|
|
406
456
|
if namespace.action != "template":
|
|
407
457
|
raise ValueError(
|
|
408
|
-
"Usage: /add template <template-id>
|
|
458
|
+
"Usage: /add template [node|python] <template-id> "
|
|
459
|
+
"[--name app] [--force] [--dry-run]"
|
|
409
460
|
)
|
|
410
461
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
462
|
+
# `/add template [lang] <id>`: the command takes the language (or the id,
|
|
463
|
+
# when no language is given) as its first positional argument.
|
|
464
|
+
lang_or_template_id = namespace.template_id
|
|
465
|
+
if lang_or_template_id is None and not namespace.list:
|
|
466
|
+
lang_or_template_id = await self._active_prompts.prompt("Template ID")
|
|
414
467
|
|
|
415
468
|
self._invoke_command(
|
|
416
469
|
add_command.template,
|
|
417
|
-
|
|
470
|
+
lang_or_template_id=lang_or_template_id,
|
|
471
|
+
template_id=namespace.template_name,
|
|
418
472
|
list_templates=namespace.list,
|
|
419
473
|
force=namespace.force,
|
|
420
474
|
name=namespace.name,
|