rpr-cli 0.1.5__tar.gz → 0.1.7__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.5 → rpr_cli-0.1.7}/PKG-INFO +3 -2
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/README.md +2 -1
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/instructions/frontend.instructions.md +1 -1
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/nx_uv_setup.md +36 -41
- rpr_cli-0.1.7/src/rpr/__init__.py +1 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/checks/workspace.py +1 -1
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/generate/api.py +9 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/generate/domain.py +9 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/init.py +39 -5
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/instructions/frontend.instructions.md +1 -1
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_check.py +1 -1
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_generate_api.py +2 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_generate_domain.py +2 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_init.py +81 -2
- rpr_cli-0.1.5/src/rpr/__init__.py +0 -1
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/.github/agents/story.agent.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/.github/workflows/publish-pypi.yml +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/.gitignore +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/CLAUDE.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/GEMINI.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/LICENSE +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/instructions/all.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/instructions/api.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/instructions/domain.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/instructions/rust-engine.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/instructions/setup-guide.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/instructions/tooling-setup.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/instructions/tooling.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/scaffolds/README.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/scaffolds/api/main.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/scaffolds/domain/base-repo.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/scaffolds/domain/base_entity.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/scaffolds/frontend/api.service.ts +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/scaffolds/frontend/useStateNavigation.ts +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/changelogs/mui_v9.txt +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/code-map.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/patch_output.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/pyproject.toml +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/Cargo.lock +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/Cargo.toml +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/pyproject.toml +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/rpr_parser.pyi +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/config/container.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/config/mod.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/config/settings.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/graph.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/lib.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/models/dtos/mod.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/models/entities/mod.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/models/entities/users.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/models/mod.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/parse.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/repos/base.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/repos/mod.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/repos/users.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/resolve.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/src/walker.rs +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/rpr-parser/uv.lock +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/special_files.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/approval.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/bootstrap.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/client.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/control.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/mock.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/runtime.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/session.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/tools/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/tools/base.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/tools/mutating.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/tools/readonly.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/agent/tools/registry.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/catalog.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/chat_service.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/checks.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/cli_adapter.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/completer.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/conversation_service.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/prompt_service.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/selector.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/application/shell.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/checks/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/checks/base.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/checks/instructions.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/checks/packages.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/cli.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/add.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/chat.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/check.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/generate/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/generate/engine.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/generate/storybook.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/generate/ui.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/map.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/refresh.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/settings.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/commands/sync.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/context.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/dependencies.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/dependency_manifest_data.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/generators/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/generators/base.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/generators/claude.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/generators/copilot.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/generators/cursor.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/generators/gemini.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/manifest_refresh.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/architecture.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/chains.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/classifier.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/coverage.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/dependencies.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/extractor.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/graph.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/output.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/responsibility.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/topology.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/map/walker.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/domain/base_entity.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/domain/base_repo.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/domain/container.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/domain/settings.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/instructions/all.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/instructions/api.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/instructions/domain.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/instructions/rust-engine.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/instructions/setup-guide.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/instructions/tooling.instructions.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/js_special_files/fetch.service.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/js_special_files/sticky-navigation.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/special_files/domain_container.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/special_files/domain_settings.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/special_files/dto_util.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/special_files/encrypted_column.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/special_files/mapper_util.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/scaffolds/special_files/partial_update.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/templates/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/templates/registry.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/ui/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/ui/console.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/ui/markdown.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/ui/prompt_session.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/ui/renderers.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/ui/theme.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/src/rpr/workspace.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/README.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/00-bootstrap-cli.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/01-rpr-init.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/02-rpr-generate-domain.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/03-rpr-generate-api.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/04-rpr-generate-ui.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/05-rpr-generate-engine.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/06-rpr-generate-storybook.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/07-rpr-sync-rules.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/08-rpr-add-template.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/09-rpr-check.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/10-rpr-domain-config.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/18-rpr-terminal-ui-foundation.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/19-rpr-markdown-rendering.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/20-rpr-chat-repl.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/21-rpr-agent-tool-loop.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/22-rpr-chat-tui.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/23-rpr-chat-unified-command-shell.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/24-rpr-async-chat-runtime-and-services.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/25-rpr-prompt-service-and-conversation-lifecycle.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/26-rpr-shared-command-catalog.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/27-rpr-slash-command-selection-panel.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/28-rpr-chat-cancellable-and-multiline-input.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/chat/29-rpr-file-context-selection.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/11-rpr-map-command.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/12-rpr-map-file-walker.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/13-rpr-map-rust-engine.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/13a-rpr-map-gitignore.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/14-rpr-map-graph-builder.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/15-rpr-map-analysis-bridge.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/16-rpr-map-layer-classifier.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/17-rpr-map-output.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/17a-rpr-map-directory-topology.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/17b-rpr-map-architecture-assessment.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/17c-rpr-map-representative-chains.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/completed/map/17d-rpr-map-multi-resolution-output.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/map/30-rpr-map-directory-view-and-cycle-detection.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/map/31-rpr-map-coupling-hotspots-and-verdict-reasoning.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/stories/map/32-rpr-map-dependencies-responsibilities-and-test-coverage.md +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/__init__.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_add.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_architecture.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_architecture_unwrapped.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_catalog.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_chat.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_chat_service.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_completer.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_context.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_generate_engine.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_generate_storybook.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_generate_ui.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_chains.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_classifier.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_coverage.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_dependencies.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_extractor.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_graph.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_output.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_responsibility.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_topology.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_map_walker.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_packaging.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_prompt_session.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_refresh.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_rpr_parser_stub.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_selector.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_settings.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_sync.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/tests/test_ui.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/update_output.py +0 -0
- {rpr_cli-0.1.5 → rpr_cli-0.1.7}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rpr-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
4
4
|
Summary: RPR CLI -- React Python Rust monorepo scaffolding orchestrator
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -69,12 +69,13 @@ rpr generate storybook # Add Storybook for UI component development
|
|
|
69
69
|
|
|
70
70
|
`rpr init <project-name>` creates the project directory when it does not exist. If the directory already exists and is not an NX workspace, RPR initializes Git and runs `nx init` inside that directory.
|
|
71
71
|
|
|
72
|
-
By default, `rpr init` scaffolds the root workspace and AI instructions only. To create project components during initialization, repeat `--scaffold
|
|
72
|
+
By default, `rpr init` scaffolds the root workspace and AI instructions only. To create project components during initialization, repeat `--scaffold` or pass a comma-separated list:
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
75
|
rpr init todo-list --scaffold domain
|
|
76
76
|
rpr init todo-list --scaffold api --domain-migrations
|
|
77
77
|
rpr init todo-list --scaffold api --scaffold web --domain-migrations
|
|
78
|
+
rpr init todo-list --scaffold instructions, domain, api, ui, web, storybook
|
|
78
79
|
```
|
|
79
80
|
|
|
80
81
|
Available scaffolds are:
|
|
@@ -54,12 +54,13 @@ rpr generate storybook # Add Storybook for UI component development
|
|
|
54
54
|
|
|
55
55
|
`rpr init <project-name>` creates the project directory when it does not exist. If the directory already exists and is not an NX workspace, RPR initializes Git and runs `nx init` inside that directory.
|
|
56
56
|
|
|
57
|
-
By default, `rpr init` scaffolds the root workspace and AI instructions only. To create project components during initialization, repeat `--scaffold
|
|
57
|
+
By default, `rpr init` scaffolds the root workspace and AI instructions only. To create project components during initialization, repeat `--scaffold` or pass a comma-separated list:
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
60
|
rpr init todo-list --scaffold domain
|
|
61
61
|
rpr init todo-list --scaffold api --domain-migrations
|
|
62
62
|
rpr init todo-list --scaffold api --scaffold web --domain-migrations
|
|
63
|
+
rpr init todo-list --scaffold instructions, domain, api, ui, web, storybook
|
|
63
64
|
```
|
|
64
65
|
|
|
65
66
|
Available scaffolds are:
|
|
@@ -84,7 +84,7 @@ export const SomeContainer = styled(Box)`
|
|
|
84
84
|
|
|
85
85
|
- Type every API payload and mutation input.
|
|
86
86
|
- Prefer `type` aliases for DTO-shaped data, `interface` for extendable service contracts, and classes only when the UI genuinely needs behavior.
|
|
87
|
-
- For components with children, prefer `React.PropsWithChildren<T>` over manually
|
|
87
|
+
- For components with children, prefer `React.PropsWithChildren<T>` over manually redeclaring a `children` field.
|
|
88
88
|
|
|
89
89
|
## Components
|
|
90
90
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# NX + UV Monorepo Setup Guide
|
|
2
2
|
|
|
3
|
-
This guide explains how to
|
|
3
|
+
This guide explains how to set up a monorepo that combines NX (for Node / TypeScript) and UV (for Python).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Prerequisites
|
|
6
6
|
|
|
7
7
|
Install the following:
|
|
8
8
|
|
|
@@ -10,30 +10,30 @@ Install the following:
|
|
|
10
10
|
- **npm**: comes with Node.js
|
|
11
11
|
- **UV**: install from [uv.io](https://uv.io/)
|
|
12
12
|
- **Python**: latest version from [python.org](https://www.python.org/)
|
|
13
|
-
- **
|
|
14
|
-
- **Rust**: latest version from [rust-lang.org](https://www.rust-lang.org/)(optional, for Rust-based engines)
|
|
13
|
+
- **Git**: latest version from [git-scm.com](https://git-scm.com/)
|
|
14
|
+
- **Rust**: latest version from [rust-lang.org](https://www.rust-lang.org/) (optional, for Rust-based engines)
|
|
15
15
|
|
|
16
16
|
## Initial Setup
|
|
17
17
|
|
|
18
18
|
### Step 1: Create NX Workspace
|
|
19
19
|
|
|
20
20
|
```shell
|
|
21
|
-
npx create-nx-workspace@latest my-monorepo --
|
|
21
|
+
npx create-nx-workspace@latest my-monorepo --preset=apps --nxCloud=never --interactive=false
|
|
22
22
|
cd my-monorepo
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
If you already have an existing directory, you can initialize NX in it:
|
|
26
26
|
|
|
27
27
|
```shell
|
|
28
|
-
npx
|
|
28
|
+
npx nx init --interactive=false --nxCloud=false
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
### Step 2: Initialize UV
|
|
32
32
|
|
|
33
|
-
Create a root `pyproject.toml`file for UV workspace management
|
|
33
|
+
Create a root `pyproject.toml` file for UV workspace management
|
|
34
34
|
|
|
35
35
|
```shell
|
|
36
|
-
uv init --no-
|
|
36
|
+
uv init --no-readme --no-pin-python --python {python_version}
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
Edit the generated `pyproject.toml` to include the following configuration:
|
|
@@ -140,7 +140,7 @@ npx nx g @nx/storybook:configuration {sb-name} --uiFramework=@storybook/react-vi
|
|
|
140
140
|
|
|
141
141
|
## Adding Python Projects
|
|
142
142
|
|
|
143
|
-
Python
|
|
143
|
+
Python projects require manual setup since NX doesn't have built-in Python plugins.
|
|
144
144
|
|
|
145
145
|
### Step 1: Create Directory Structure
|
|
146
146
|
|
|
@@ -170,7 +170,7 @@ requires-python = ">={python_version}"
|
|
|
170
170
|
dependencies = []
|
|
171
171
|
|
|
172
172
|
[tool.uv]
|
|
173
|
-
|
|
173
|
+
required-version = ">={uv_version}" # use the latest you have installed
|
|
174
174
|
|
|
175
175
|
[tool.uv.workspace]
|
|
176
176
|
members = [
|
|
@@ -190,8 +190,8 @@ dev = [
|
|
|
190
190
|
]
|
|
191
191
|
[tool.ruff]
|
|
192
192
|
line-length = 88
|
|
193
|
-
target-version="py314" # Update to match your target Python version
|
|
194
|
-
exclude = [**/migrations/**]
|
|
193
|
+
target-version = "py314" # Update to match your target Python version
|
|
194
|
+
exclude = ["**/migrations/**"]
|
|
195
195
|
|
|
196
196
|
[tool.ruff.lint]
|
|
197
197
|
select = [
|
|
@@ -207,17 +207,17 @@ ignore = [
|
|
|
207
207
|
"C901" # Complexity, can be handled by refactoring when needed, but not a hard rule
|
|
208
208
|
]
|
|
209
209
|
|
|
210
|
-
[tool.ruff.lint.
|
|
211
|
-
"
|
|
210
|
+
[tool.ruff.lint.per-file-ignores]
|
|
211
|
+
"__init__.py" = [
|
|
212
212
|
"F401", # Allow unused imports in __init__.py for package exports
|
|
213
213
|
]
|
|
214
|
-
"tests
|
|
214
|
+
"tests/**/*.py" = ["F841"]
|
|
215
215
|
|
|
216
216
|
[tool.ruff.format]
|
|
217
|
-
quote-style="double"
|
|
218
|
-
indent-style="space"
|
|
219
|
-
skip-magic-trailing-comma=false
|
|
220
|
-
line-ending="lf"
|
|
217
|
+
quote-style = "double"
|
|
218
|
+
indent-style = "space"
|
|
219
|
+
skip-magic-trailing-comma = false
|
|
220
|
+
line-ending = "lf"
|
|
221
221
|
|
|
222
222
|
[tool.pytest.ini_options]
|
|
223
223
|
pythonpath = [
|
|
@@ -230,7 +230,7 @@ testpaths = [
|
|
|
230
230
|
]
|
|
231
231
|
```
|
|
232
232
|
|
|
233
|
-
**For a
|
|
233
|
+
**For a FastAPI application (`apps/{my-python-app}/pyproject.toml`)**
|
|
234
234
|
|
|
235
235
|
```toml
|
|
236
236
|
[project]
|
|
@@ -245,13 +245,8 @@ dependencies = [
|
|
|
245
245
|
# Add other workspace dependencies here e.g. "{my-python-lib}" must be defined in tool.uv.sources
|
|
246
246
|
]
|
|
247
247
|
|
|
248
|
-
[tool.uv.workspace]
|
|
249
|
-
members = [
|
|
250
|
-
"apps/{my-python-app}"
|
|
251
|
-
]
|
|
252
|
-
|
|
253
248
|
[tool.uv.sources]
|
|
254
|
-
{my-python-lib} = { workspace = true }
|
|
249
|
+
"{my-python-lib}" = { workspace = true }
|
|
255
250
|
|
|
256
251
|
[project.optional-dependencies]
|
|
257
252
|
dev = [
|
|
@@ -263,11 +258,11 @@ dev = [
|
|
|
263
258
|
]
|
|
264
259
|
|
|
265
260
|
[build-system]
|
|
266
|
-
requires=["hatchling"]
|
|
267
|
-
build-backend="hatchling.build"
|
|
261
|
+
requires = ["hatchling"]
|
|
262
|
+
build-backend = "hatchling.build"
|
|
268
263
|
|
|
269
|
-
[tool.hatch.build.targets.wheel
|
|
270
|
-
"src
|
|
264
|
+
[tool.hatch.build.targets.wheel]
|
|
265
|
+
packages = ["src/{my_python_app}"]
|
|
271
266
|
|
|
272
267
|
[tool.coverage.run]
|
|
273
268
|
source = ["src"]
|
|
@@ -279,8 +274,8 @@ omit = [
|
|
|
279
274
|
"*/.venv/*"
|
|
280
275
|
]
|
|
281
276
|
|
|
282
|
-
[tool.coverage.
|
|
283
|
-
output="coverage.xml"
|
|
277
|
+
[tool.coverage.xml]
|
|
278
|
+
output = "coverage.xml"
|
|
284
279
|
|
|
285
280
|
[tool.coverage.report]
|
|
286
281
|
exclude_lines = [
|
|
@@ -313,10 +308,10 @@ dependencies = []
|
|
|
313
308
|
# another-lib = { workspace = true }
|
|
314
309
|
|
|
315
310
|
[build-system]
|
|
316
|
-
requires=["hatchling"]
|
|
317
|
-
build-backend="hatchling.build"
|
|
311
|
+
requires = ["hatchling"]
|
|
312
|
+
build-backend = "hatchling.build"
|
|
318
313
|
|
|
319
|
-
[tool.hatch.build.targets.wheel
|
|
314
|
+
[tool.hatch.build.targets.wheel]
|
|
320
315
|
packages = ["src/{my_python_lib}"]
|
|
321
316
|
|
|
322
317
|
# if you have files that are not code like json or yaml you can include them in the wheel with:
|
|
@@ -497,7 +492,7 @@ Alembic autogeneration relies on model discovery, make sure the new entity modul
|
|
|
497
492
|
|
|
498
493
|
## Adding other languages (e.g. Rust)
|
|
499
494
|
|
|
500
|
-
The same pattern can be applied to other languages. Here how you would
|
|
495
|
+
The same pattern can be applied to other languages. Here is how you would set up a Rust project:
|
|
501
496
|
|
|
502
497
|
### Step 1: Create Directory Structure
|
|
503
498
|
|
|
@@ -646,7 +641,7 @@ Example:
|
|
|
646
641
|
- Use `.env.example` to document required environment variables without exposing sensitive information
|
|
647
642
|
- Never commit `.env` files to version control
|
|
648
643
|
- For python use `python-dotenv` or `pydantic-settings` to load environment variables in your application
|
|
649
|
-
- For Node.js
|
|
644
|
+
- For Node.js use `dotenv` or Vite's built-in environment variable support
|
|
650
645
|
|
|
651
646
|
### 6. Testing
|
|
652
647
|
|
|
@@ -710,7 +705,7 @@ repos:
|
|
|
710
705
|
|
|
711
706
|
- id: prettier
|
|
712
707
|
name: Prettier format
|
|
713
|
-
entry: npx prettier --write --
|
|
708
|
+
entry: npx prettier --write --log-level=warn
|
|
714
709
|
language: system
|
|
715
710
|
types_or: [javascript, jsx, ts, tsx, json, css, scss, html, markdown]
|
|
716
711
|
exclude: \.ipynb$ # Exclude Jupyter notebooks from Prettier formatting
|
|
@@ -726,7 +721,7 @@ repos:
|
|
|
726
721
|
|
|
727
722
|
### 9. CI / CD Considerations
|
|
728
723
|
|
|
729
|
-
- Use NX's
|
|
724
|
+
- Use NX's affected commands to only test/build changed projects
|
|
730
725
|
- Cache build between CI runs
|
|
731
726
|
- Example GitHub Actions:
|
|
732
727
|
|
|
@@ -815,7 +810,7 @@ uvx ruff format . # Format Python code with Ruff
|
|
|
815
810
|
**Problem:**
|
|
816
811
|
|
|
817
812
|
1. The package is not listed in the root `pyproject.toml` under `[tool.uv.workspace].members`
|
|
818
|
-
2. You have not
|
|
813
|
+
2. You have not run `uv sync --all-packages` after adding the package to the workspace configuration
|
|
819
814
|
3. The workspace dependency was not declared with `{ workspace = true }` in the `[tool.uv.sources]` section of the dependent package's `pyproject.toml`
|
|
820
815
|
|
|
821
816
|
### Issue: NX can't find Python projects
|
|
@@ -838,7 +833,7 @@ uvx ruff format . # Format Python code with Ruff
|
|
|
838
833
|
|
|
839
834
|
This setup gives you the best of both worlds:
|
|
840
835
|
|
|
841
|
-
- **NX** for Node.js/
|
|
836
|
+
- **NX** for Node.js/TypeScript projects with excellent tooling and generators
|
|
842
837
|
- **UV** for Python projects with modern dependency management and workspace support
|
|
843
838
|
- A unified monorepo structure that allows you to manage both ecosystems in one place.
|
|
844
839
|
- Extensible to other languages like Rust with manual setup.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.7"
|
|
@@ -73,7 +73,7 @@ def check_workspace(project_dir: Path) -> list[CheckResult]:
|
|
|
73
73
|
pytest_config = False
|
|
74
74
|
dev_dependencies_ok = False
|
|
75
75
|
if tool:
|
|
76
|
-
uv_require_version = "
|
|
76
|
+
uv_require_version = "required-version" in tool.get("uv", {})
|
|
77
77
|
pytest_config = "pytest" in tool and "ini_options" in tool["pytest"]
|
|
78
78
|
|
|
79
79
|
dependency_groups = pyproject_data.get("dependency-groups", {}) if pyproject_data else {}
|
|
@@ -42,6 +42,7 @@ def api(
|
|
|
42
42
|
ctx.ensure_dir(tests_root)
|
|
43
43
|
|
|
44
44
|
_write_api_pyproject(ctx, api_root, name, app_name, app_name_underscore)
|
|
45
|
+
_write_api_readme(ctx, api_root, name)
|
|
45
46
|
_write_api_project_json(ctx, api_root, app_name, app_name_underscore)
|
|
46
47
|
_write_main(ctx, src_root / "main.py", name, domain_underscore)
|
|
47
48
|
_write_init_file(ctx, src_root / "__init__.py")
|
|
@@ -98,6 +99,14 @@ testpaths = ["tests"]
|
|
|
98
99
|
ctx.write_file(api_root / "pyproject.toml", content)
|
|
99
100
|
|
|
100
101
|
|
|
102
|
+
def _write_api_readme(ctx: RunContext, api_root: Path, name: str) -> None:
|
|
103
|
+
content = f"""# {name} API
|
|
104
|
+
|
|
105
|
+
FastAPI application generated by RPR.
|
|
106
|
+
"""
|
|
107
|
+
ctx.write_file(api_root / "README.md", content)
|
|
108
|
+
|
|
109
|
+
|
|
101
110
|
def _write_api_project_json(
|
|
102
111
|
ctx: RunContext, api_root: Path, app_name: str, app_name_underscore: str
|
|
103
112
|
) -> None:
|
|
@@ -60,6 +60,7 @@ def domain(
|
|
|
60
60
|
|
|
61
61
|
# --- project metadata --------------------------------------------------
|
|
62
62
|
_write_domain_pyproject(ctx, domain_root, name, pkg_name_underscore)
|
|
63
|
+
_write_domain_readme(ctx, domain_root, name)
|
|
63
64
|
_write_project_json(ctx, domain_root, include_migrations=migrations)
|
|
64
65
|
|
|
65
66
|
# --- __init__.py files -------------------------------------------------
|
|
@@ -142,6 +143,14 @@ testpaths = ["tests"]
|
|
|
142
143
|
ctx.write_file(domain_root / "pyproject.toml", content)
|
|
143
144
|
|
|
144
145
|
|
|
146
|
+
def _write_domain_readme(ctx: RunContext, domain_root: Path, name: str) -> None:
|
|
147
|
+
content = f"""# {name} Domain
|
|
148
|
+
|
|
149
|
+
Domain layer package generated by RPR.
|
|
150
|
+
"""
|
|
151
|
+
ctx.write_file(domain_root / "README.md", content)
|
|
152
|
+
|
|
153
|
+
|
|
145
154
|
def _write_project_json(
|
|
146
155
|
ctx: RunContext, domain_root: Path, *, include_migrations: bool
|
|
147
156
|
) -> None:
|
|
@@ -106,6 +106,25 @@ def _normalize_scaffold_name(value: str) -> ScaffoldName:
|
|
|
106
106
|
return normalized # type: ignore[return-value]
|
|
107
107
|
|
|
108
108
|
|
|
109
|
+
def _parse_scaffold_values(
|
|
110
|
+
values: list[str] | None,
|
|
111
|
+
extra_args: list[str],
|
|
112
|
+
) -> list[ScaffoldName]:
|
|
113
|
+
raw_values = values or []
|
|
114
|
+
if extra_args and not raw_values:
|
|
115
|
+
raise typer.BadParameter(
|
|
116
|
+
"Unexpected extra arguments. Use --scaffold to select components."
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
scaffolds: list[ScaffoldName] = []
|
|
120
|
+
for raw_value in [*raw_values, *extra_args]:
|
|
121
|
+
for value in raw_value.split(","):
|
|
122
|
+
value = value.strip()
|
|
123
|
+
if value:
|
|
124
|
+
scaffolds.append(_normalize_scaffold_name(value))
|
|
125
|
+
return scaffolds
|
|
126
|
+
|
|
127
|
+
|
|
109
128
|
def _resolve_scaffolds(scaffolds: list[ScaffoldName] | None) -> list[ScaffoldName]:
|
|
110
129
|
requested = scaffolds or ["instructions"]
|
|
111
130
|
resolved: list[ScaffoldName] = []
|
|
@@ -336,7 +355,7 @@ requires-python = ">={python_version}"
|
|
|
336
355
|
dependencies = []
|
|
337
356
|
|
|
338
357
|
[tool.uv]
|
|
339
|
-
|
|
358
|
+
required-version = "{uv_require_version}"
|
|
340
359
|
|
|
341
360
|
[tool.uv.workspace]
|
|
342
361
|
members = []
|
|
@@ -379,6 +398,18 @@ testpaths = []
|
|
|
379
398
|
ctx.update_file(ctx.project_dir / "pyproject.toml", content)
|
|
380
399
|
|
|
381
400
|
|
|
401
|
+
def _write_root_readme(ctx: RunContext, project_name: str) -> None:
|
|
402
|
+
path = ctx.project_dir / "README.md"
|
|
403
|
+
if path.exists():
|
|
404
|
+
return
|
|
405
|
+
|
|
406
|
+
content = f"""# {project_name}
|
|
407
|
+
|
|
408
|
+
RPR NX + UV monorepo.
|
|
409
|
+
"""
|
|
410
|
+
ctx.write_file(path, content)
|
|
411
|
+
|
|
412
|
+
|
|
382
413
|
def _detect_uv_require_version() -> str:
|
|
383
414
|
try:
|
|
384
415
|
result = subprocess.run(
|
|
@@ -675,8 +706,9 @@ API_BASE_URL=http://localhost:8000
|
|
|
675
706
|
# ---------------------------------------------------------------------------
|
|
676
707
|
|
|
677
708
|
|
|
678
|
-
@app.command()
|
|
709
|
+
@app.command(context_settings={"allow_extra_args": True})
|
|
679
710
|
def init(
|
|
711
|
+
ctx: typer.Context,
|
|
680
712
|
project_name: Annotated[
|
|
681
713
|
str | None, typer.Argument(help="Name of the project to create.")
|
|
682
714
|
] = None,
|
|
@@ -691,8 +723,9 @@ def init(
|
|
|
691
723
|
typer.Option(
|
|
692
724
|
"--scaffold",
|
|
693
725
|
help=(
|
|
694
|
-
"Repeat to scaffold additional
|
|
695
|
-
"api, ui, web, storybook,
|
|
726
|
+
"Repeat or pass a comma-separated list to scaffold additional "
|
|
727
|
+
"components: instructions, domain, api, ui, web, storybook, "
|
|
728
|
+
"engine. Defaults to instructions only."
|
|
696
729
|
),
|
|
697
730
|
),
|
|
698
731
|
] = None,
|
|
@@ -712,7 +745,7 @@ def init(
|
|
|
712
745
|
project_name = typer.prompt("Project name")
|
|
713
746
|
|
|
714
747
|
selected_scaffolds = _resolve_scaffolds(
|
|
715
|
-
|
|
748
|
+
_parse_scaffold_values(scaffold, list(ctx.args))
|
|
716
749
|
)
|
|
717
750
|
if domain_migrations and "domain" not in selected_scaffolds:
|
|
718
751
|
raise typer.BadParameter(
|
|
@@ -792,6 +825,7 @@ def init(
|
|
|
792
825
|
# ------------------------------------------------------------------
|
|
793
826
|
_write_nx_json(ctx)
|
|
794
827
|
_write_root_pyproject(ctx, project_name, python_version)
|
|
828
|
+
_write_root_readme(ctx, project_name)
|
|
795
829
|
_write_root_package_json(ctx, project_name)
|
|
796
830
|
_write_tsconfig_base(ctx)
|
|
797
831
|
_write_root_eslint_config(ctx)
|
|
@@ -96,7 +96,7 @@ export const SomeContainer = styled(Box)`
|
|
|
96
96
|
|
|
97
97
|
- Type every API payload and mutation input.
|
|
98
98
|
- Prefer `type` aliases for DTO-shaped data, `interface` for extendable service contracts, and classes only when the UI genuinely needs behavior.
|
|
99
|
-
- For components with children, prefer `React.PropsWithChildren<T>` over manually
|
|
99
|
+
- For components with children, prefer `React.PropsWithChildren<T>` over manually redeclaring a `children` field.
|
|
100
100
|
|
|
101
101
|
## Components
|
|
102
102
|
|
|
@@ -59,6 +59,7 @@ def test_generate_api_scaffolds_src_layout_tests_and_build_target(monkeypatch):
|
|
|
59
59
|
assert (src_root / "__init__.py").exists()
|
|
60
60
|
assert (src_root / "routes" / "__init__.py").exists()
|
|
61
61
|
assert (tests_root / "test_health.py").exists()
|
|
62
|
+
assert (api_root / "README.md").read_text().startswith("# my-app API")
|
|
62
63
|
|
|
63
64
|
pyproject = (api_root / "pyproject.toml").read_text()
|
|
64
65
|
project = json.loads((api_root / "project.json").read_text())
|
|
@@ -67,6 +68,7 @@ def test_generate_api_scaffolds_src_layout_tests_and_build_target(monkeypatch):
|
|
|
67
68
|
root_pyproject = Path("pyproject.toml").read_text()
|
|
68
69
|
|
|
69
70
|
assert 'packages = ["src/my_app_api"]' in pyproject
|
|
71
|
+
assert 'readme = "README.md"' in pyproject
|
|
70
72
|
assert '[tool.pytest.ini_options]' in pyproject
|
|
71
73
|
assert 'testpaths = ["tests"]' in pyproject
|
|
72
74
|
assert project["name"] == "my-app-api"
|
|
@@ -68,6 +68,7 @@ def test_generate_domain_scaffolds_config_and_metadata(monkeypatch):
|
|
|
68
68
|
assert (src_root / "entities" / "base.py").exists()
|
|
69
69
|
assert (src_root / "repos" / "base.py").exists()
|
|
70
70
|
assert (domain_root / "tests" / "test_package.py").exists()
|
|
71
|
+
assert (domain_root / "README.md").read_text().startswith("# my-app Domain")
|
|
71
72
|
|
|
72
73
|
for package_dir in [
|
|
73
74
|
"",
|
|
@@ -125,6 +126,7 @@ def test_generate_domain_scaffolds_config_and_metadata(monkeypatch):
|
|
|
125
126
|
)
|
|
126
127
|
assert "migrate" not in project["targets"]
|
|
127
128
|
assert '[tool.pytest.ini_options]' in (domain_root / "pyproject.toml").read_text()
|
|
129
|
+
assert 'readme = "README.md"' in (domain_root / "pyproject.toml").read_text()
|
|
128
130
|
assert 'members = ["packages/python/domain"]' in root_pyproject
|
|
129
131
|
|
|
130
132
|
assert recorded_calls[0][0] == ["uv", "sync"]
|
|
@@ -56,7 +56,7 @@ def test_init_new_workspace_disables_nx_cloud(monkeypatch):
|
|
|
56
56
|
assert 'name = "my-app"' in pyproject
|
|
57
57
|
assert 'readme = "README.md"' in pyproject
|
|
58
58
|
assert '[tool.uv]' in pyproject
|
|
59
|
-
assert '
|
|
59
|
+
assert 'required-version = ">=' in pyproject
|
|
60
60
|
assert '"pytest-asyncio"' in pyproject
|
|
61
61
|
assert '"pytest-cov"' in pyproject
|
|
62
62
|
assert '"ipykernel"' in pyproject
|
|
@@ -90,6 +90,7 @@ def test_init_new_workspace_disables_nx_cloud(monkeypatch):
|
|
|
90
90
|
assert (project_dir / ".prettierrc").exists()
|
|
91
91
|
assert (project_dir / ".prettierignore").exists()
|
|
92
92
|
assert (project_dir / ".pre-commit-config.yaml").exists()
|
|
93
|
+
assert (project_dir / "README.md").read_text().startswith("# my-app")
|
|
93
94
|
|
|
94
95
|
|
|
95
96
|
def test_init_existing_workspace_disables_nx_cloud(monkeypatch):
|
|
@@ -132,8 +133,9 @@ def test_init_existing_workspace_disables_nx_cloud(monkeypatch):
|
|
|
132
133
|
assert '"neverConnectToCloud": true' in nx_json
|
|
133
134
|
assert '"plugin": "@nx/eslint/plugin"' in nx_json
|
|
134
135
|
assert 'name = "my-app"' in pyproject
|
|
135
|
-
assert '
|
|
136
|
+
assert 'required-version = ">=' in pyproject
|
|
136
137
|
assert 'testpaths = []' in pyproject
|
|
138
|
+
assert (project_dir / "README.md").read_text() == "existing"
|
|
137
139
|
assert 'repo: https://github.com/pre-commit/pre-commit-hooks' in pre_commit
|
|
138
140
|
assert 'repo: https://github.com/kynan/nbstripout' in pre_commit
|
|
139
141
|
assert 'entry: npx nx run-many --target=lint --all --fix --exclude=engine' in pre_commit
|
|
@@ -219,6 +221,83 @@ def test_init_scaffold_selection_runs_requested_generators_in_dependency_order(
|
|
|
219
221
|
]
|
|
220
222
|
|
|
221
223
|
|
|
224
|
+
def test_init_accepts_comma_separated_scaffold_values(monkeypatch):
|
|
225
|
+
scaffold_calls: list[str] = []
|
|
226
|
+
instructions_calls: list[dict[str, object]] = []
|
|
227
|
+
|
|
228
|
+
def fake_run_command(
|
|
229
|
+
self, cmd, *, cwd=None, env=None, capture=False, supports_dry_run=False
|
|
230
|
+
):
|
|
231
|
+
return _completed(cmd)
|
|
232
|
+
|
|
233
|
+
def fake_domain(*, name, dry_run, migrations=False):
|
|
234
|
+
scaffold_calls.append(f"domain:{name}:{dry_run}:{migrations}")
|
|
235
|
+
|
|
236
|
+
def fake_api(*, name, dry_run):
|
|
237
|
+
scaffold_calls.append(f"api:{name}:{dry_run}")
|
|
238
|
+
|
|
239
|
+
def fake_ui(*, name, dry_run, include_library=True, include_web=True):
|
|
240
|
+
scaffold_calls.append(
|
|
241
|
+
f"ui:{name}:{dry_run}:{include_library}:{include_web}"
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
def fake_storybook(*, ui_package=None, dry_run):
|
|
245
|
+
scaffold_calls.append(f"storybook:{ui_package}:{dry_run}")
|
|
246
|
+
|
|
247
|
+
monkeypatch.setattr("rpr.context.RunContext.run_command", fake_run_command)
|
|
248
|
+
monkeypatch.setattr(
|
|
249
|
+
"rpr.commands.init._scaffold_ai_instructions",
|
|
250
|
+
lambda *args, **kwargs: instructions_calls.append({"args": args, "kwargs": kwargs}),
|
|
251
|
+
)
|
|
252
|
+
monkeypatch.setattr("rpr.commands.generate.domain.domain", fake_domain)
|
|
253
|
+
monkeypatch.setattr("rpr.commands.generate.api.api", fake_api)
|
|
254
|
+
monkeypatch.setattr("rpr.commands.generate.ui.ui", fake_ui)
|
|
255
|
+
monkeypatch.setattr("rpr.commands.generate.storybook.storybook", fake_storybook)
|
|
256
|
+
|
|
257
|
+
commands = [
|
|
258
|
+
[
|
|
259
|
+
"init",
|
|
260
|
+
"comma-space",
|
|
261
|
+
"--scaffold",
|
|
262
|
+
"instructions,",
|
|
263
|
+
"domain,",
|
|
264
|
+
"api,",
|
|
265
|
+
"ui,",
|
|
266
|
+
"web,",
|
|
267
|
+
"storybook",
|
|
268
|
+
],
|
|
269
|
+
[
|
|
270
|
+
"init",
|
|
271
|
+
"comma-tight",
|
|
272
|
+
"--scaffold",
|
|
273
|
+
"instructions,domain,api,ui,web,storybook",
|
|
274
|
+
],
|
|
275
|
+
[
|
|
276
|
+
"init",
|
|
277
|
+
"comma-quoted",
|
|
278
|
+
"--scaffold",
|
|
279
|
+
"instructions, domain, api, ui, web, storybook",
|
|
280
|
+
],
|
|
281
|
+
]
|
|
282
|
+
|
|
283
|
+
with runner.isolated_filesystem():
|
|
284
|
+
for command in commands:
|
|
285
|
+
scaffold_calls.clear()
|
|
286
|
+
instructions_calls.clear()
|
|
287
|
+
|
|
288
|
+
result = runner.invoke(app, command)
|
|
289
|
+
|
|
290
|
+
project_name = command[1]
|
|
291
|
+
assert result.exit_code == 0, result.stdout
|
|
292
|
+
assert len(instructions_calls) == 1
|
|
293
|
+
assert scaffold_calls == [
|
|
294
|
+
f"domain:{project_name}:False:False",
|
|
295
|
+
f"api:{project_name}:False",
|
|
296
|
+
f"ui:{project_name}:False:True:True",
|
|
297
|
+
f"storybook:{project_name}-ui:False",
|
|
298
|
+
]
|
|
299
|
+
|
|
300
|
+
|
|
222
301
|
def test_init_forwards_domain_migrations(monkeypatch):
|
|
223
302
|
recorded_calls: list[dict[str, object]] = []
|
|
224
303
|
scaffold_calls: list[str] = []
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.5"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rpr_cli-0.1.5 → rpr_cli-0.1.7}/Sample-dot-github/instructions/tooling-setup.instructions.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|