rpr-cli 0.1.30__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rpr_cli-0.1.30/README.md → rpr_cli-0.2.1/PKG-INFO +23 -0
- rpr_cli-0.1.30/PKG-INFO → rpr_cli-0.2.1/README.md +6 -15
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/pyproject.toml +2 -0
- rpr_cli-0.2.1/src/rpr/__init__.py +1 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/catalog.py +61 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/cli.py +8 -0
- rpr_cli-0.2.1/src/rpr/commands/update.py +222 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/manifest_refresh.py +50 -0
- rpr_cli-0.2.1/src/rpr/package_updates.py +731 -0
- rpr_cli-0.2.1/stories/package-maintenance/rpr-update-packages.md +183 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_catalog.py +22 -2
- rpr_cli-0.2.1/tests/test_package_updates.py +175 -0
- rpr_cli-0.2.1/tests/test_update_packages.py +209 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/uv.lock +16 -3
- rpr_cli-0.1.30/src/rpr/__init__.py +0 -1
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/.github/agents/story.agent.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/.github/workflows/publish-pypi.yml +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/.gitignore +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/CLAUDE.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/GEMINI.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/LICENSE +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/instructions/all.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/instructions/api.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/instructions/domain.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/instructions/frontend.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/instructions/rust-engine.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/instructions/setup-guide.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/instructions/tooling-setup.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/instructions/tooling.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/README.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/api/main.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/domain/base-repo.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/domain/base_entity.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/frontend/api.service.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/frontend/useStateNavigation.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponent.spec.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponent.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.spec.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/frontend/virtual-list/VirtualComponentList.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/Sample-dot-github/scaffolds/frontend/virtual-list/index.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/changelogs/mui_v9.txt +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/code-map.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/nx_uv_setup.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/patch_output.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/plan-languageAwareTemplateAdd.prompt.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/Cargo.lock +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/Cargo.toml +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/pyproject.toml +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/rpr_parser.pyi +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/config/container.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/config/mod.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/config/settings.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/graph.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/lib.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/models/dtos/mod.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/models/entities/mod.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/models/entities/users.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/models/mod.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/parse.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/repos/base.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/repos/mod.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/repos/users.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/resolve.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/src/walker.rs +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/rpr-parser/uv.lock +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/special_files.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/approval.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/bootstrap.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/client.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/control.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/mock.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/runtime.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/session.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/tools/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/tools/base.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/tools/mutating.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/tools/readonly.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/agent/tools/registry.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/chat_service.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/checks.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/cli_adapter.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/completer.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/conversation_service.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/prompt_service.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/selector.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/application/shell.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/checks/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/checks/base.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/checks/instructions.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/checks/packages.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/checks/workspace.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/add.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/chat.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/check.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/generate/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/generate/api.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/generate/domain.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/generate/engine.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/generate/storybook.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/generate/ui.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/init.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/map.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/refresh.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/settings.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/commands/sync.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/context.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/dependencies.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/dependency_manifest_data.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/generators/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/generators/base.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/generators/claude.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/generators/copilot.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/generators/cursor.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/generators/gemini.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/generators/github.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/architecture.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/chains.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/classifier.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/coverage.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/dependencies.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/extractor.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/graph.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/output.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/responsibility.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/topology.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/map/walker.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/domain/base_entity.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/domain/base_repo.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/domain/container.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/domain/settings.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/instructions/all.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/instructions/api.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/instructions/domain.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/instructions/frontend.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/instructions/rust-engine.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/README.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/client/index.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/client/types.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.spec.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/ChatComposer.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/__screenshots__/ChatComposer.spec.tsx/ChatComposer-renders-custom-action-buttons-beside-the-attachment-control-1.png +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.spec.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/fileDrop.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/index.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatComposerMentionTokens.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/ChatSuggestionsPopover.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/LocalFileSuggestionAction.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/index.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.spec.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/localFileSuggestions.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.spec.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/triggerDetection.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/types.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/suggestions/useChatSuggestions.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/types.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/useChatComposer.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.spec.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/composer/useChatStream.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/index.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/testing/createMockChatStreamClient.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/testing/createMockSuggestionProvider.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/testing/index.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessage.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.spec.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/ChatMessageContent.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.spec.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/ChatThread.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/README.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/contentFormat.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/index.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/streaming.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/thread/types.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.spec.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponent.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.spec.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/virtual-list/VirtualComponentList.tsx +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/chat/virtual-list/index.ts +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/sticky-navigation.spec.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/js_special_files/vitest-browser-config.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/special_files/camel_case_model.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/special_files/domain_container.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/special_files/domain_settings.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/special_files/encrypted_column.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/templates/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/templates/registry.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/ui/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/ui/console.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/ui/markdown.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/ui/prompt_session.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/ui/renderers.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/ui/theme.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/src/rpr/workspace.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/README.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/00-bootstrap-cli.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/01-rpr-init.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/02-rpr-generate-domain.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/03-rpr-generate-api.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/04-rpr-generate-ui.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/05-rpr-generate-engine.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/06-rpr-generate-storybook.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/07-rpr-sync-rules.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/08-rpr-add-template.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/09-rpr-check.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/10-rpr-domain-config.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/18-rpr-terminal-ui-foundation.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/19-rpr-markdown-rendering.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/20-rpr-chat-repl.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/21-rpr-agent-tool-loop.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/22-rpr-chat-tui.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/23-rpr-chat-unified-command-shell.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/24-rpr-async-chat-runtime-and-services.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/25-rpr-prompt-service-and-conversation-lifecycle.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/26-rpr-shared-command-catalog.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/27-rpr-slash-command-selection-panel.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/28-rpr-chat-cancellable-and-multiline-input.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/chat/29-rpr-file-context-selection.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/11-rpr-map-command.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/12-rpr-map-file-walker.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/13-rpr-map-rust-engine.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/13a-rpr-map-gitignore.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/14-rpr-map-graph-builder.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/15-rpr-map-analysis-bridge.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/16-rpr-map-layer-classifier.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/17-rpr-map-output.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/17a-rpr-map-directory-topology.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/17b-rpr-map-architecture-assessment.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/17c-rpr-map-representative-chains.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/completed/map/17d-rpr-map-multi-resolution-output.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/map/30-rpr-map-directory-view-and-cycle-detection.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/map/31-rpr-map-coupling-hotspots-and-verdict-reasoning.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/stories/map/32-rpr-map-dependencies-responsibilities-and-test-coverage.md +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/__init__.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_add.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_architecture.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_architecture_unwrapped.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_chat.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_chat_service.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_check.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_completer.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_context.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_generate_api.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_generate_domain.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_generate_engine.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_generate_storybook.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_generate_ui.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_init.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_chains.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_classifier.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_coverage.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_dependencies.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_extractor.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_graph.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_output.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_responsibility.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_topology.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_map_walker.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_packaging.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_prompt_session.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_refresh.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_rpr_parser_stub.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_selector.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_settings.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_sync.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/tests/test_ui.py +0 -0
- {rpr_cli-0.1.30 → rpr_cli-0.2.1}/update_output.py +0 -0
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rpr-cli
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.14
|
|
8
|
+
Requires-Dist: jinja2>=3.1.5
|
|
9
|
+
Requires-Dist: packaging>=26.2
|
|
10
|
+
Requires-Dist: pathspec>=1.0.4
|
|
11
|
+
Requires-Dist: prompt-toolkit>=3.0.52
|
|
12
|
+
Requires-Dist: pyyaml>=6.0.2
|
|
13
|
+
Requires-Dist: rich>=14.3.3
|
|
14
|
+
Requires-Dist: tomlkit>=0.15.0
|
|
15
|
+
Requires-Dist: typer>=0.24.1
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
1
18
|
# RPR CLI
|
|
2
19
|
|
|
3
20
|
React Python Rust monorepo scaffolding orchestrator.
|
|
@@ -85,6 +102,8 @@ RPR keeps dependencies close to the package that uses them.
|
|
|
85
102
|
|
|
86
103
|
Python dependency changes are made with `uv` so they are tracked in `pyproject.toml`. Node dependency changes are made through npm workspace package metadata and root `npm install`.
|
|
87
104
|
|
|
105
|
+
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.
|
|
106
|
+
|
|
88
107
|
The scaffold version manifest that powers generated dependency specs and the synced AI tech-stack overview lives in `src/rpr/dependency_manifest_data.py`. Refresh it from upstream registries with `rpr refresh manifest` when you want the repo-owned defaults to move forward.
|
|
89
108
|
|
|
90
109
|
### 🧠 AI Instructions & Code Templates
|
|
@@ -133,6 +152,8 @@ Keep your project healthy and explore its structure.
|
|
|
133
152
|
|
|
134
153
|
```bash
|
|
135
154
|
rpr refresh manifest # Refresh the scaffold dependency manifest from npm, PyPI, and crates.io
|
|
155
|
+
rpr update node # Update package.json dependencies and run npm install
|
|
156
|
+
rpr update python # Update pyproject.toml or requirements.txt and sync Python dependencies
|
|
136
157
|
rpr check # Inspect project health and report setup status
|
|
137
158
|
rpr map # Generate a structured code map of your project
|
|
138
159
|
rpr settings # Inspect persisted shell settings
|
|
@@ -149,6 +170,8 @@ Persisted settings currently include:
|
|
|
149
170
|
|
|
150
171
|
`rpr refresh manifest` is a repo-maintenance command. It rewrites `src/rpr/dependency_manifest_data.py`, which feeds scaffold dependency versions in `rpr generate ...` and the versioned overview text produced by `rpr sync rules`. Use `--dry-run` to preview the manifest rewrite without writing the file.
|
|
151
172
|
|
|
173
|
+
`rpr update node` and `rpr update python` are project-maintenance commands. They update the selected package manifest, print applied and held-back dependency changes, and run the matching installer only when live changes are written. Without `--include-major`, RPR chooses the latest stable version inside the current major version and reports higher-major candidates as held back. Python updates cover `[project].dependencies`, `[dependency-groups].*`, and `requirements.txt`; build backend packages in `[build-system].requires` are left unchanged unless a future explicit build-system update option is added.
|
|
174
|
+
|
|
152
175
|
### ⚙️ Common Flags
|
|
153
176
|
|
|
154
177
|
Most commands support these global flags:
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: rpr-cli
|
|
3
|
-
Version: 0.1.30
|
|
4
|
-
Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
License-File: LICENSE
|
|
7
|
-
Requires-Python: >=3.14
|
|
8
|
-
Requires-Dist: jinja2>=3.1.5
|
|
9
|
-
Requires-Dist: pathspec>=1.0.4
|
|
10
|
-
Requires-Dist: prompt-toolkit>=3.0.52
|
|
11
|
-
Requires-Dist: pyyaml>=6.0.2
|
|
12
|
-
Requires-Dist: rich>=14.3.3
|
|
13
|
-
Requires-Dist: typer>=0.24.1
|
|
14
|
-
Description-Content-Type: text/markdown
|
|
15
|
-
|
|
16
1
|
# RPR CLI
|
|
17
2
|
|
|
18
3
|
React Python Rust monorepo scaffolding orchestrator.
|
|
@@ -100,6 +85,8 @@ RPR keeps dependencies close to the package that uses them.
|
|
|
100
85
|
|
|
101
86
|
Python dependency changes are made with `uv` so they are tracked in `pyproject.toml`. Node dependency changes are made through npm workspace package metadata and root `npm install`.
|
|
102
87
|
|
|
88
|
+
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.
|
|
89
|
+
|
|
103
90
|
The scaffold version manifest that powers generated dependency specs and the synced AI tech-stack overview lives in `src/rpr/dependency_manifest_data.py`. Refresh it from upstream registries with `rpr refresh manifest` when you want the repo-owned defaults to move forward.
|
|
104
91
|
|
|
105
92
|
### 🧠 AI Instructions & Code Templates
|
|
@@ -148,6 +135,8 @@ Keep your project healthy and explore its structure.
|
|
|
148
135
|
|
|
149
136
|
```bash
|
|
150
137
|
rpr refresh manifest # Refresh the scaffold dependency manifest from npm, PyPI, and crates.io
|
|
138
|
+
rpr update node # Update package.json dependencies and run npm install
|
|
139
|
+
rpr update python # Update pyproject.toml or requirements.txt and sync Python dependencies
|
|
151
140
|
rpr check # Inspect project health and report setup status
|
|
152
141
|
rpr map # Generate a structured code map of your project
|
|
153
142
|
rpr settings # Inspect persisted shell settings
|
|
@@ -164,6 +153,8 @@ Persisted settings currently include:
|
|
|
164
153
|
|
|
165
154
|
`rpr refresh manifest` is a repo-maintenance command. It rewrites `src/rpr/dependency_manifest_data.py`, which feeds scaffold dependency versions in `rpr generate ...` and the versioned overview text produced by `rpr sync rules`. Use `--dry-run` to preview the manifest rewrite without writing the file.
|
|
166
155
|
|
|
156
|
+
`rpr update node` and `rpr update python` are project-maintenance commands. They update the selected package manifest, print applied and held-back dependency changes, and run the matching installer only when live changes are written. Without `--include-major`, RPR chooses the latest stable version inside the current major version and reports higher-major candidates as held back. Python updates cover `[project].dependencies`, `[dependency-groups].*`, and `requirements.txt`; build backend packages in `[build-system].requires` are left unchanged unless a future explicit build-system update option is added.
|
|
157
|
+
|
|
167
158
|
### ⚙️ Common Flags
|
|
168
159
|
|
|
169
160
|
Most commands support these global flags:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.1"
|
|
@@ -241,6 +241,67 @@ COMMAND_CATALOG: tuple[CommandDefinition, ...] = (
|
|
|
241
241
|
),
|
|
242
242
|
),
|
|
243
243
|
),
|
|
244
|
+
CommandDefinition(
|
|
245
|
+
name="update",
|
|
246
|
+
description="Update project package manifests from upstream registries.",
|
|
247
|
+
action_id="update.dispatch",
|
|
248
|
+
children=(
|
|
249
|
+
CommandDefinition(
|
|
250
|
+
name="node",
|
|
251
|
+
description="Update a package.json manifest and run npm install.",
|
|
252
|
+
action_id="update.node",
|
|
253
|
+
options=(
|
|
254
|
+
CommandOption(
|
|
255
|
+
"--file",
|
|
256
|
+
"Package manifest to update.",
|
|
257
|
+
kind="value",
|
|
258
|
+
value_name="PATH",
|
|
259
|
+
),
|
|
260
|
+
CommandOption(
|
|
261
|
+
"--include-major",
|
|
262
|
+
"Apply available updates across major versions.",
|
|
263
|
+
kind="flag",
|
|
264
|
+
),
|
|
265
|
+
CommandOption(
|
|
266
|
+
"--timeout",
|
|
267
|
+
"Per-request registry timeout in seconds.",
|
|
268
|
+
kind="value",
|
|
269
|
+
value_name="SECONDS",
|
|
270
|
+
),
|
|
271
|
+
CommandOption(
|
|
272
|
+
"--dry-run", "Preview changes without writing.", kind="flag"
|
|
273
|
+
),
|
|
274
|
+
),
|
|
275
|
+
),
|
|
276
|
+
CommandDefinition(
|
|
277
|
+
name="python",
|
|
278
|
+
description="Update a Python manifest and run the matching sync command.",
|
|
279
|
+
action_id="update.python",
|
|
280
|
+
options=(
|
|
281
|
+
CommandOption(
|
|
282
|
+
"--file",
|
|
283
|
+
"Package manifest to update.",
|
|
284
|
+
kind="value",
|
|
285
|
+
value_name="PATH",
|
|
286
|
+
),
|
|
287
|
+
CommandOption(
|
|
288
|
+
"--include-major",
|
|
289
|
+
"Apply available updates across major versions.",
|
|
290
|
+
kind="flag",
|
|
291
|
+
),
|
|
292
|
+
CommandOption(
|
|
293
|
+
"--timeout",
|
|
294
|
+
"Per-request registry timeout in seconds.",
|
|
295
|
+
kind="value",
|
|
296
|
+
value_name="SECONDS",
|
|
297
|
+
),
|
|
298
|
+
CommandOption(
|
|
299
|
+
"--dry-run", "Preview changes without writing.", kind="flag"
|
|
300
|
+
),
|
|
301
|
+
),
|
|
302
|
+
),
|
|
303
|
+
),
|
|
304
|
+
),
|
|
244
305
|
CommandDefinition(
|
|
245
306
|
name="add",
|
|
246
307
|
description="Write a registered template into the current project.",
|
|
@@ -39,6 +39,13 @@ refresh_app = typer.Typer(
|
|
|
39
39
|
)
|
|
40
40
|
app.add_typer(refresh_app, name="refresh")
|
|
41
41
|
|
|
42
|
+
update_app = typer.Typer(
|
|
43
|
+
name="update",
|
|
44
|
+
help="Update project package manifests from upstream registries.",
|
|
45
|
+
no_args_is_help=True,
|
|
46
|
+
)
|
|
47
|
+
app.add_typer(update_app, name="update")
|
|
48
|
+
|
|
42
49
|
add_app = typer.Typer(
|
|
43
50
|
name="add",
|
|
44
51
|
help="Add code templates to the current project.",
|
|
@@ -54,6 +61,7 @@ from rpr.commands.generate import engine as _engine_mod # noqa: E402, F401
|
|
|
54
61
|
from rpr.commands.generate import storybook as _storybook_mod # noqa: E402, F401
|
|
55
62
|
from rpr.commands import sync as _sync_mod # noqa: E402, F401
|
|
56
63
|
from rpr.commands import refresh as _refresh_mod # noqa: E402, F401
|
|
64
|
+
from rpr.commands import update as _update_mod # noqa: E402, F401
|
|
57
65
|
from rpr.commands import add as _add_mod # noqa: E402, F401
|
|
58
66
|
|
|
59
67
|
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
|
|
9
|
+
from rpr.cli import update_app
|
|
10
|
+
from rpr.context import RunContext
|
|
11
|
+
from rpr.package_updates import (
|
|
12
|
+
PackageFileKind,
|
|
13
|
+
PackageUpdateError,
|
|
14
|
+
PackageUpdatePlan,
|
|
15
|
+
plan_package_updates,
|
|
16
|
+
)
|
|
17
|
+
from rpr.ui.renderers import render_table
|
|
18
|
+
|
|
19
|
+
console = Console()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@update_app.command("node")
|
|
23
|
+
def node(
|
|
24
|
+
file: Annotated[
|
|
25
|
+
str | None,
|
|
26
|
+
typer.Option("--file", help="Package manifest to update."),
|
|
27
|
+
] = None,
|
|
28
|
+
include_major: Annotated[
|
|
29
|
+
bool,
|
|
30
|
+
typer.Option(
|
|
31
|
+
"--include-major", help="Apply available updates across major versions."
|
|
32
|
+
),
|
|
33
|
+
] = False,
|
|
34
|
+
dry_run: Annotated[
|
|
35
|
+
bool, typer.Option("--dry-run", help="Preview changes without writing.")
|
|
36
|
+
] = False,
|
|
37
|
+
timeout: Annotated[
|
|
38
|
+
float,
|
|
39
|
+
typer.Option(
|
|
40
|
+
"--timeout",
|
|
41
|
+
min=1.0,
|
|
42
|
+
help="Per-request timeout in seconds when talking to registries.",
|
|
43
|
+
),
|
|
44
|
+
] = 10.0,
|
|
45
|
+
) -> None:
|
|
46
|
+
"""Update a package.json manifest and run npm install."""
|
|
47
|
+
ctx = RunContext(dry_run=dry_run, project_dir=Path.cwd())
|
|
48
|
+
manifest_path = _resolve_manifest_path(file, default=ctx.project_dir / "package.json")
|
|
49
|
+
plan = _build_plan(
|
|
50
|
+
manifest_path,
|
|
51
|
+
"node",
|
|
52
|
+
include_major=include_major,
|
|
53
|
+
dry_run=dry_run,
|
|
54
|
+
timeout=timeout,
|
|
55
|
+
)
|
|
56
|
+
_apply_plan(ctx, plan)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@update_app.command("python")
|
|
60
|
+
def python(
|
|
61
|
+
file: Annotated[
|
|
62
|
+
str | None,
|
|
63
|
+
typer.Option("--file", help="Package manifest to update."),
|
|
64
|
+
] = None,
|
|
65
|
+
include_major: Annotated[
|
|
66
|
+
bool,
|
|
67
|
+
typer.Option(
|
|
68
|
+
"--include-major", help="Apply available updates across major versions."
|
|
69
|
+
),
|
|
70
|
+
] = False,
|
|
71
|
+
dry_run: Annotated[
|
|
72
|
+
bool, typer.Option("--dry-run", help="Preview changes without writing.")
|
|
73
|
+
] = False,
|
|
74
|
+
timeout: Annotated[
|
|
75
|
+
float,
|
|
76
|
+
typer.Option(
|
|
77
|
+
"--timeout",
|
|
78
|
+
min=1.0,
|
|
79
|
+
help="Per-request timeout in seconds when talking to registries.",
|
|
80
|
+
),
|
|
81
|
+
] = 10.0,
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Update a Python manifest and run the matching sync command."""
|
|
84
|
+
ctx = RunContext(dry_run=dry_run, project_dir=Path.cwd())
|
|
85
|
+
manifest_path = _resolve_manifest_path(
|
|
86
|
+
file,
|
|
87
|
+
default=_default_python_manifest(ctx.project_dir),
|
|
88
|
+
)
|
|
89
|
+
plan = _build_plan(
|
|
90
|
+
manifest_path,
|
|
91
|
+
"python",
|
|
92
|
+
include_major=include_major,
|
|
93
|
+
dry_run=dry_run,
|
|
94
|
+
timeout=timeout,
|
|
95
|
+
)
|
|
96
|
+
_apply_plan(ctx, plan)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _resolve_manifest_path(file: str | None, *, default: Path) -> Path:
|
|
100
|
+
if file is None:
|
|
101
|
+
return default
|
|
102
|
+
path = Path(file).expanduser()
|
|
103
|
+
if path.is_absolute():
|
|
104
|
+
return path
|
|
105
|
+
return Path.cwd() / path
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _default_python_manifest(project_dir: Path) -> Path:
|
|
109
|
+
pyproject = project_dir / "pyproject.toml"
|
|
110
|
+
if pyproject.exists():
|
|
111
|
+
return pyproject
|
|
112
|
+
return project_dir / "requirements.txt"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _build_plan(
|
|
116
|
+
manifest_path: Path,
|
|
117
|
+
target: str,
|
|
118
|
+
*,
|
|
119
|
+
include_major: bool,
|
|
120
|
+
dry_run: bool,
|
|
121
|
+
timeout: float,
|
|
122
|
+
) -> PackageUpdatePlan:
|
|
123
|
+
try:
|
|
124
|
+
plan = plan_package_updates(
|
|
125
|
+
manifest_path,
|
|
126
|
+
target, # type: ignore[arg-type]
|
|
127
|
+
include_major=include_major,
|
|
128
|
+
timeout=timeout,
|
|
129
|
+
)
|
|
130
|
+
except PackageUpdateError as exc:
|
|
131
|
+
console.print(f"[bold red]Error:[/] {exc}")
|
|
132
|
+
raise typer.Exit(1) from exc
|
|
133
|
+
|
|
134
|
+
_render_plan(plan, dry_run=dry_run)
|
|
135
|
+
return plan
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _render_plan(plan: PackageUpdatePlan, *, dry_run: bool) -> None:
|
|
139
|
+
if not plan.changes:
|
|
140
|
+
if plan.supported_section_count == 0:
|
|
141
|
+
console.print(
|
|
142
|
+
f"[bold green]Done![/] No supported dependency sections in {plan.path}."
|
|
143
|
+
)
|
|
144
|
+
else:
|
|
145
|
+
console.print(f"[bold green]Done![/] {plan.path} is already up to date.")
|
|
146
|
+
_render_skipped(plan)
|
|
147
|
+
if dry_run:
|
|
148
|
+
console.print(
|
|
149
|
+
"\n[bold yellow]Dry run complete.[/] No manifest or installer command was changed."
|
|
150
|
+
)
|
|
151
|
+
return
|
|
152
|
+
|
|
153
|
+
action = "Planned" if dry_run else "Applying"
|
|
154
|
+
console.print(f"\n[bold]{action} package updates[/] ({len(plan.changes)} updates)\n")
|
|
155
|
+
render_table(
|
|
156
|
+
"Package updates",
|
|
157
|
+
["Path", "Section", "Package", "Old", "New", "Major"],
|
|
158
|
+
[
|
|
159
|
+
[
|
|
160
|
+
str(change.path),
|
|
161
|
+
change.section,
|
|
162
|
+
change.package,
|
|
163
|
+
change.old_specifier,
|
|
164
|
+
change.new_specifier,
|
|
165
|
+
"yes" if change.is_major else "no",
|
|
166
|
+
]
|
|
167
|
+
for change in plan.changes
|
|
168
|
+
],
|
|
169
|
+
)
|
|
170
|
+
_render_skipped(plan)
|
|
171
|
+
if dry_run:
|
|
172
|
+
console.print(
|
|
173
|
+
"\n[bold yellow]Dry run complete.[/] No manifest or installer command was changed."
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _render_skipped(plan: PackageUpdatePlan) -> None:
|
|
178
|
+
if not plan.skipped:
|
|
179
|
+
return
|
|
180
|
+
rows = []
|
|
181
|
+
for skipped in plan.skipped:
|
|
182
|
+
reason = skipped.reason
|
|
183
|
+
if skipped.latest_version:
|
|
184
|
+
reason = f"{reason} (latest: {skipped.latest_version})"
|
|
185
|
+
rows.append(
|
|
186
|
+
[
|
|
187
|
+
str(skipped.path),
|
|
188
|
+
skipped.section,
|
|
189
|
+
skipped.package,
|
|
190
|
+
skipped.specifier,
|
|
191
|
+
reason,
|
|
192
|
+
]
|
|
193
|
+
)
|
|
194
|
+
render_table(
|
|
195
|
+
"Skipped package updates",
|
|
196
|
+
["Path", "Section", "Package", "Specifier", "Reason"],
|
|
197
|
+
rows,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _apply_plan(ctx: RunContext, plan: PackageUpdatePlan) -> None:
|
|
202
|
+
if not plan.has_changes:
|
|
203
|
+
return
|
|
204
|
+
if ctx.dry_run:
|
|
205
|
+
return
|
|
206
|
+
|
|
207
|
+
ctx.update_file(plan.path, plan.updated_content)
|
|
208
|
+
_run_installer(ctx, plan.file_kind, plan.path)
|
|
209
|
+
console.print(f"\n[bold green]Done![/] Updated package manifest at {plan.path}")
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def _run_installer(ctx: RunContext, file_kind: PackageFileKind, manifest_path: Path) -> None:
|
|
213
|
+
if file_kind == "package-json":
|
|
214
|
+
ctx.run_command(["npm", "install"], cwd=ctx.project_dir)
|
|
215
|
+
return
|
|
216
|
+
if file_kind == "pyproject-toml":
|
|
217
|
+
ctx.run_uv_command(["uv", "sync", "--all-packages"], cwd=ctx.project_dir)
|
|
218
|
+
return
|
|
219
|
+
ctx.run_command(
|
|
220
|
+
["python", "-m", "pip", "install", "-r", str(manifest_path)],
|
|
221
|
+
cwd=ctx.project_dir,
|
|
222
|
+
)
|
|
@@ -8,6 +8,8 @@ from typing import Literal
|
|
|
8
8
|
from urllib.parse import quote
|
|
9
9
|
from urllib.request import Request, urlopen
|
|
10
10
|
|
|
11
|
+
from packaging.version import InvalidVersion, Version
|
|
12
|
+
|
|
11
13
|
RegistryName = Literal["npm", "pypi", "cratesio"]
|
|
12
14
|
RefreshStrategy = Literal[
|
|
13
15
|
"caret", "minimum", "exact", "major-range", "latest", "pinned-major"
|
|
@@ -64,6 +66,54 @@ def fetch_latest_version(
|
|
|
64
66
|
) from exc
|
|
65
67
|
|
|
66
68
|
|
|
69
|
+
def fetch_available_versions(
|
|
70
|
+
registry: RegistryName, package: str, *, timeout: float = 10.0
|
|
71
|
+
) -> list[str]:
|
|
72
|
+
if registry == "npm":
|
|
73
|
+
url = f"https://registry.npmjs.org/{quote(package, safe='')}"
|
|
74
|
+
elif registry == "pypi":
|
|
75
|
+
url = f"https://pypi.org/pypi/{quote(package, safe='')}/json"
|
|
76
|
+
else:
|
|
77
|
+
raise ManifestRefreshError(
|
|
78
|
+
f"Available-version lookup is not supported for {registry} packages"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
request = Request(url, headers={"User-Agent": _USER_AGENT})
|
|
82
|
+
try:
|
|
83
|
+
with urlopen(request, timeout=timeout) as response:
|
|
84
|
+
payload = json.load(response)
|
|
85
|
+
except Exception as exc: # pragma: no cover - exercised through command tests
|
|
86
|
+
raise ManifestRefreshError(
|
|
87
|
+
f"Failed to fetch {registry} metadata for {package}: {exc}"
|
|
88
|
+
) from exc
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
raw_versions = (
|
|
92
|
+
payload["versions"].keys() if registry == "npm" else payload["releases"].keys()
|
|
93
|
+
)
|
|
94
|
+
except Exception as exc: # pragma: no cover - exercised through command tests
|
|
95
|
+
raise ManifestRefreshError(
|
|
96
|
+
f"Registry response for {package} did not include available versions"
|
|
97
|
+
) from exc
|
|
98
|
+
|
|
99
|
+
versions: list[tuple[Version, str]] = []
|
|
100
|
+
for raw_version in raw_versions:
|
|
101
|
+
try:
|
|
102
|
+
parsed = Version(str(raw_version))
|
|
103
|
+
except InvalidVersion:
|
|
104
|
+
continue
|
|
105
|
+
if parsed.is_prerelease or parsed.is_devrelease:
|
|
106
|
+
continue
|
|
107
|
+
versions.append((parsed, str(raw_version)))
|
|
108
|
+
|
|
109
|
+
if not versions:
|
|
110
|
+
raise ManifestRefreshError(
|
|
111
|
+
f"Registry response for {package} did not include stable versions"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
return [raw_version for _, raw_version in sorted(versions, reverse=True)]
|
|
115
|
+
|
|
116
|
+
|
|
67
117
|
def refresh_dependency_manifest(
|
|
68
118
|
manifest: Manifest,
|
|
69
119
|
*,
|