rpr-cli 0.1.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.1/.github/agents/story.agent.md +165 -0
- rpr_cli-0.1.1/.github/workflows/publish-pypi.yml +54 -0
- rpr_cli-0.1.1/.gitignore +28 -0
- rpr_cli-0.1.1/CLAUDE.md +70 -0
- rpr_cli-0.1.1/GEMINI.md +0 -0
- rpr_cli-0.1.1/LICENSE +21 -0
- rpr_cli-0.1.1/PKG-INFO +201 -0
- rpr_cli-0.1.1/README.md +186 -0
- rpr_cli-0.1.1/Sample-dot-github/instructions/all.instructions.md +49 -0
- rpr_cli-0.1.1/Sample-dot-github/instructions/api.instructions.md +42 -0
- rpr_cli-0.1.1/Sample-dot-github/instructions/domain.instructions.md +93 -0
- rpr_cli-0.1.1/Sample-dot-github/instructions/frontend.instructions.md +97 -0
- rpr_cli-0.1.1/Sample-dot-github/instructions/rust-engine.instructions.md +40 -0
- rpr_cli-0.1.1/Sample-dot-github/instructions/setup-guide.instructions.md +86 -0
- rpr_cli-0.1.1/Sample-dot-github/instructions/tooling-setup.instructions.md +97 -0
- rpr_cli-0.1.1/Sample-dot-github/instructions/tooling.instructions.md +42 -0
- rpr_cli-0.1.1/Sample-dot-github/scaffolds/README.md +7 -0
- rpr_cli-0.1.1/Sample-dot-github/scaffolds/api/main.py +84 -0
- rpr_cli-0.1.1/Sample-dot-github/scaffolds/domain/base-repo.md +48 -0
- rpr_cli-0.1.1/Sample-dot-github/scaffolds/domain/base_entity.md +32 -0
- rpr_cli-0.1.1/Sample-dot-github/scaffolds/frontend/api.service.ts +200 -0
- rpr_cli-0.1.1/Sample-dot-github/scaffolds/frontend/useStateNavigation.ts +142 -0
- rpr_cli-0.1.1/code-map.md +168 -0
- rpr_cli-0.1.1/nx_uv_setup.md +846 -0
- rpr_cli-0.1.1/patch_output.py +150 -0
- rpr_cli-0.1.1/pyproject.toml +31 -0
- rpr_cli-0.1.1/rpr-parser/Cargo.lock +3542 -0
- rpr_cli-0.1.1/rpr-parser/Cargo.toml +35 -0
- rpr_cli-0.1.1/rpr-parser/pyproject.toml +12 -0
- rpr_cli-0.1.1/rpr-parser/rpr_parser.pyi +23 -0
- rpr_cli-0.1.1/rpr-parser/src/config/container.rs +30 -0
- rpr_cli-0.1.1/rpr-parser/src/config/mod.rs +2 -0
- rpr_cli-0.1.1/rpr-parser/src/config/settings.rs +29 -0
- rpr_cli-0.1.1/rpr-parser/src/graph.rs +265 -0
- rpr_cli-0.1.1/rpr-parser/src/lib.rs +142 -0
- rpr_cli-0.1.1/rpr-parser/src/models/dtos/mod.rs +0 -0
- rpr_cli-0.1.1/rpr-parser/src/models/entities/mod.rs +1 -0
- rpr_cli-0.1.1/rpr-parser/src/models/entities/users.rs +24 -0
- rpr_cli-0.1.1/rpr-parser/src/models/mod.rs +2 -0
- rpr_cli-0.1.1/rpr-parser/src/parse.rs +537 -0
- rpr_cli-0.1.1/rpr-parser/src/repos/base.rs +41 -0
- rpr_cli-0.1.1/rpr-parser/src/repos/mod.rs +2 -0
- rpr_cli-0.1.1/rpr-parser/src/repos/users.rs +15 -0
- rpr_cli-0.1.1/rpr-parser/src/resolve.rs +378 -0
- rpr_cli-0.1.1/rpr-parser/src/walker.rs +284 -0
- rpr_cli-0.1.1/rpr-parser/uv.lock +8 -0
- rpr_cli-0.1.1/special_files.md +20 -0
- rpr_cli-0.1.1/src/rpr/__init__.py +1 -0
- rpr_cli-0.1.1/src/rpr/agent/__init__.py +29 -0
- rpr_cli-0.1.1/src/rpr/agent/approval.py +19 -0
- rpr_cli-0.1.1/src/rpr/agent/bootstrap.py +60 -0
- rpr_cli-0.1.1/src/rpr/agent/client.py +115 -0
- rpr_cli-0.1.1/src/rpr/agent/control.py +16 -0
- rpr_cli-0.1.1/src/rpr/agent/mock.py +158 -0
- rpr_cli-0.1.1/src/rpr/agent/runtime.py +291 -0
- rpr_cli-0.1.1/src/rpr/agent/session.py +91 -0
- rpr_cli-0.1.1/src/rpr/agent/tools/__init__.py +10 -0
- rpr_cli-0.1.1/src/rpr/agent/tools/base.py +62 -0
- rpr_cli-0.1.1/src/rpr/agent/tools/mutating.py +47 -0
- rpr_cli-0.1.1/src/rpr/agent/tools/readonly.py +147 -0
- rpr_cli-0.1.1/src/rpr/agent/tools/registry.py +30 -0
- rpr_cli-0.1.1/src/rpr/application/__init__.py +1 -0
- rpr_cli-0.1.1/src/rpr/application/catalog.py +427 -0
- rpr_cli-0.1.1/src/rpr/application/chat_service.py +413 -0
- rpr_cli-0.1.1/src/rpr/application/checks.py +49 -0
- rpr_cli-0.1.1/src/rpr/application/cli_adapter.py +36 -0
- rpr_cli-0.1.1/src/rpr/application/completer.py +163 -0
- rpr_cli-0.1.1/src/rpr/application/conversation_service.py +92 -0
- rpr_cli-0.1.1/src/rpr/application/prompt_service.py +85 -0
- rpr_cli-0.1.1/src/rpr/application/selector.py +240 -0
- rpr_cli-0.1.1/src/rpr/application/shell.py +543 -0
- rpr_cli-0.1.1/src/rpr/checks/__init__.py +0 -0
- rpr_cli-0.1.1/src/rpr/checks/base.py +13 -0
- rpr_cli-0.1.1/src/rpr/checks/instructions.py +89 -0
- rpr_cli-0.1.1/src/rpr/checks/packages.py +619 -0
- rpr_cli-0.1.1/src/rpr/checks/workspace.py +170 -0
- rpr_cli-0.1.1/src/rpr/cli.py +78 -0
- rpr_cli-0.1.1/src/rpr/commands/__init__.py +0 -0
- rpr_cli-0.1.1/src/rpr/commands/add.py +166 -0
- rpr_cli-0.1.1/src/rpr/commands/chat.py +48 -0
- rpr_cli-0.1.1/src/rpr/commands/check.py +53 -0
- rpr_cli-0.1.1/src/rpr/commands/generate/__init__.py +0 -0
- rpr_cli-0.1.1/src/rpr/commands/generate/api.py +228 -0
- rpr_cli-0.1.1/src/rpr/commands/generate/domain.py +383 -0
- rpr_cli-0.1.1/src/rpr/commands/generate/engine.py +148 -0
- rpr_cli-0.1.1/src/rpr/commands/generate/storybook.py +442 -0
- rpr_cli-0.1.1/src/rpr/commands/generate/ui.py +414 -0
- rpr_cli-0.1.1/src/rpr/commands/init.py +822 -0
- rpr_cli-0.1.1/src/rpr/commands/map.py +113 -0
- rpr_cli-0.1.1/src/rpr/commands/settings.py +102 -0
- rpr_cli-0.1.1/src/rpr/commands/sync.py +97 -0
- rpr_cli-0.1.1/src/rpr/context.py +203 -0
- rpr_cli-0.1.1/src/rpr/generators/__init__.py +0 -0
- rpr_cli-0.1.1/src/rpr/generators/base.py +110 -0
- rpr_cli-0.1.1/src/rpr/generators/claude.py +33 -0
- rpr_cli-0.1.1/src/rpr/generators/copilot.py +36 -0
- rpr_cli-0.1.1/src/rpr/generators/cursor.py +38 -0
- rpr_cli-0.1.1/src/rpr/generators/gemini.py +33 -0
- rpr_cli-0.1.1/src/rpr/map/__init__.py +0 -0
- rpr_cli-0.1.1/src/rpr/map/architecture.py +495 -0
- rpr_cli-0.1.1/src/rpr/map/chains.py +317 -0
- rpr_cli-0.1.1/src/rpr/map/classifier.py +170 -0
- rpr_cli-0.1.1/src/rpr/map/coverage.py +200 -0
- rpr_cli-0.1.1/src/rpr/map/dependencies.py +243 -0
- rpr_cli-0.1.1/src/rpr/map/extractor.py +223 -0
- rpr_cli-0.1.1/src/rpr/map/graph.py +318 -0
- rpr_cli-0.1.1/src/rpr/map/output.py +1030 -0
- rpr_cli-0.1.1/src/rpr/map/responsibility.py +345 -0
- rpr_cli-0.1.1/src/rpr/map/topology.py +327 -0
- rpr_cli-0.1.1/src/rpr/map/walker.py +151 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/domain/base_entity.md +30 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/domain/base_repo.md +48 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/domain/container.md +76 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/domain/settings.md +57 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/instructions/all.instructions.md +50 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/instructions/api.instructions.md +42 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/instructions/domain.instructions.md +93 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/instructions/frontend.instructions.md +97 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/instructions/rust-engine.instructions.md +40 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/instructions/setup-guide.instructions.md +86 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/instructions/tooling-setup.instructions.md +97 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/instructions/tooling.instructions.md +42 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/js_special_files/fetch.service.md +222 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/js_special_files/sticky-navigation.md +164 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/special_files/domain_container.md +76 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/special_files/domain_settings.md +57 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/special_files/dto_util.md +62 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/special_files/encrypted_column.md +98 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/special_files/mapper_util.md +159 -0
- rpr_cli-0.1.1/src/rpr/scaffolds/special_files/partial_update.md +61 -0
- rpr_cli-0.1.1/src/rpr/templates/__init__.py +0 -0
- rpr_cli-0.1.1/src/rpr/templates/registry.py +81 -0
- rpr_cli-0.1.1/src/rpr/ui/__init__.py +0 -0
- rpr_cli-0.1.1/src/rpr/ui/console.py +32 -0
- rpr_cli-0.1.1/src/rpr/ui/markdown.py +59 -0
- rpr_cli-0.1.1/src/rpr/ui/prompt_session.py +430 -0
- rpr_cli-0.1.1/src/rpr/ui/renderers.py +167 -0
- rpr_cli-0.1.1/src/rpr/ui/theme.py +286 -0
- rpr_cli-0.1.1/src/rpr/workspace.py +131 -0
- rpr_cli-0.1.1/stories/README.md +93 -0
- rpr_cli-0.1.1/stories/completed/00-bootstrap-cli.md +61 -0
- rpr_cli-0.1.1/stories/completed/01-rpr-init.md +216 -0
- rpr_cli-0.1.1/stories/completed/02-rpr-generate-domain.md +89 -0
- rpr_cli-0.1.1/stories/completed/03-rpr-generate-api.md +39 -0
- rpr_cli-0.1.1/stories/completed/04-rpr-generate-ui.md +104 -0
- rpr_cli-0.1.1/stories/completed/05-rpr-generate-engine.md +111 -0
- rpr_cli-0.1.1/stories/completed/06-rpr-generate-storybook.md +89 -0
- rpr_cli-0.1.1/stories/completed/07-rpr-sync-rules.md +160 -0
- rpr_cli-0.1.1/stories/completed/08-rpr-add-template.md +68 -0
- rpr_cli-0.1.1/stories/completed/09-rpr-check.md +115 -0
- rpr_cli-0.1.1/stories/completed/10-rpr-domain-config.md +120 -0
- rpr_cli-0.1.1/stories/completed/chat/18-rpr-terminal-ui-foundation.md +37 -0
- rpr_cli-0.1.1/stories/completed/chat/19-rpr-markdown-rendering.md +38 -0
- rpr_cli-0.1.1/stories/completed/chat/20-rpr-chat-repl.md +36 -0
- rpr_cli-0.1.1/stories/completed/chat/21-rpr-agent-tool-loop.md +40 -0
- rpr_cli-0.1.1/stories/completed/chat/22-rpr-chat-tui.md +44 -0
- rpr_cli-0.1.1/stories/completed/chat/23-rpr-chat-unified-command-shell.md +96 -0
- rpr_cli-0.1.1/stories/completed/chat/24-rpr-async-chat-runtime-and-services.md +75 -0
- rpr_cli-0.1.1/stories/completed/chat/25-rpr-prompt-service-and-conversation-lifecycle.md +76 -0
- rpr_cli-0.1.1/stories/completed/chat/26-rpr-shared-command-catalog.md +213 -0
- rpr_cli-0.1.1/stories/completed/chat/27-rpr-slash-command-selection-panel.md +61 -0
- rpr_cli-0.1.1/stories/completed/chat/28-rpr-chat-cancellable-and-multiline-input.md +63 -0
- rpr_cli-0.1.1/stories/completed/chat/29-rpr-file-context-selection.md +52 -0
- rpr_cli-0.1.1/stories/completed/map/11-rpr-map-command.md +32 -0
- rpr_cli-0.1.1/stories/completed/map/12-rpr-map-file-walker.md +51 -0
- rpr_cli-0.1.1/stories/completed/map/13-rpr-map-rust-engine.md +126 -0
- rpr_cli-0.1.1/stories/completed/map/13a-rpr-map-gitignore.md +34 -0
- rpr_cli-0.1.1/stories/completed/map/14-rpr-map-graph-builder.md +94 -0
- rpr_cli-0.1.1/stories/completed/map/15-rpr-map-analysis-bridge.md +94 -0
- rpr_cli-0.1.1/stories/completed/map/16-rpr-map-layer-classifier.md +60 -0
- rpr_cli-0.1.1/stories/completed/map/17-rpr-map-output.md +94 -0
- rpr_cli-0.1.1/stories/completed/map/17a-rpr-map-directory-topology.md +65 -0
- rpr_cli-0.1.1/stories/completed/map/17b-rpr-map-architecture-assessment.md +61 -0
- rpr_cli-0.1.1/stories/completed/map/17c-rpr-map-representative-chains.md +52 -0
- rpr_cli-0.1.1/stories/completed/map/17d-rpr-map-multi-resolution-output.md +72 -0
- rpr_cli-0.1.1/stories/map/30-rpr-map-directory-view-and-cycle-detection.md +38 -0
- rpr_cli-0.1.1/stories/map/31-rpr-map-coupling-hotspots-and-verdict-reasoning.md +41 -0
- rpr_cli-0.1.1/stories/map/32-rpr-map-dependencies-responsibilities-and-test-coverage.md +98 -0
- rpr_cli-0.1.1/tests/__init__.py +0 -0
- rpr_cli-0.1.1/tests/test_add.py +154 -0
- rpr_cli-0.1.1/tests/test_architecture.py +659 -0
- rpr_cli-0.1.1/tests/test_architecture_unwrapped.py +152 -0
- rpr_cli-0.1.1/tests/test_catalog.py +201 -0
- rpr_cli-0.1.1/tests/test_chat.py +720 -0
- rpr_cli-0.1.1/tests/test_chat_service.py +282 -0
- rpr_cli-0.1.1/tests/test_check.py +617 -0
- rpr_cli-0.1.1/tests/test_completer.py +131 -0
- rpr_cli-0.1.1/tests/test_context.py +305 -0
- rpr_cli-0.1.1/tests/test_generate_api.py +111 -0
- rpr_cli-0.1.1/tests/test_generate_domain.py +244 -0
- rpr_cli-0.1.1/tests/test_generate_engine.py +128 -0
- rpr_cli-0.1.1/tests/test_generate_storybook.py +210 -0
- rpr_cli-0.1.1/tests/test_generate_ui.py +168 -0
- rpr_cli-0.1.1/tests/test_init.py +332 -0
- rpr_cli-0.1.1/tests/test_map.py +80 -0
- rpr_cli-0.1.1/tests/test_map_chains.py +554 -0
- rpr_cli-0.1.1/tests/test_map_classifier.py +330 -0
- rpr_cli-0.1.1/tests/test_map_coverage.py +182 -0
- rpr_cli-0.1.1/tests/test_map_dependencies.py +266 -0
- rpr_cli-0.1.1/tests/test_map_extractor.py +455 -0
- rpr_cli-0.1.1/tests/test_map_graph.py +309 -0
- rpr_cli-0.1.1/tests/test_map_output.py +1397 -0
- rpr_cli-0.1.1/tests/test_map_responsibility.py +220 -0
- rpr_cli-0.1.1/tests/test_map_topology.py +651 -0
- rpr_cli-0.1.1/tests/test_map_walker.py +448 -0
- rpr_cli-0.1.1/tests/test_packaging.py +19 -0
- rpr_cli-0.1.1/tests/test_prompt_session.py +236 -0
- rpr_cli-0.1.1/tests/test_rpr_parser_stub.py +12 -0
- rpr_cli-0.1.1/tests/test_selector.py +189 -0
- rpr_cli-0.1.1/tests/test_settings.py +112 -0
- rpr_cli-0.1.1/tests/test_sync.py +143 -0
- rpr_cli-0.1.1/tests/test_ui.py +133 -0
- rpr_cli-0.1.1/update_output.py +134 -0
- rpr_cli-0.1.1/uv.lock +296 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Use when researching and drafting implementation-ready user stories with concrete file touch plans, domain artifacts, and validation steps."
|
|
3
|
+
name: "Story Planning Agent"
|
|
4
|
+
tools: [execute, read, edit, search]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a Senior Story Planning Agent. Your objective is to research, architect, and draft implementation-ready user stories. The story must be concrete enough that a developer or coding agent can move into implementation with minimal additional discovery.
|
|
8
|
+
|
|
9
|
+
You do not write production code in the story. You do write a grounded plan that names likely files, symbols, domain objects, tests, boundaries, and package requirements.
|
|
10
|
+
|
|
11
|
+
## Primary Standard
|
|
12
|
+
|
|
13
|
+
Every story must be evidence-backed, vertically sliced, and specific about how the work will likely land in this repository.
|
|
14
|
+
|
|
15
|
+
Avoid abstract statements like:
|
|
16
|
+
|
|
17
|
+
- "update the backend logic"
|
|
18
|
+
- "extend the domain layer"
|
|
19
|
+
- "add tests"
|
|
20
|
+
- "handle edge cases"
|
|
21
|
+
|
|
22
|
+
Replace them with repository-grounded guidance like:
|
|
23
|
+
|
|
24
|
+
- which existing files are likely to change
|
|
25
|
+
- which new files are likely to be created
|
|
26
|
+
- which DTOs, entities, value objects, repositories, workflows, routes, commands, hooks, or components are involved
|
|
27
|
+
- which tests should be added or updated
|
|
28
|
+
- which existing patterns or scaffolds should be followed
|
|
29
|
+
|
|
30
|
+
If the codebase evidence is incomplete, say so explicitly and record the gap as an assumption or open question. Do not fill gaps with generic architecture prose.
|
|
31
|
+
|
|
32
|
+
## Agentic Workflow
|
|
33
|
+
|
|
34
|
+
You must strictly execute the following phases in order. Do not skip to generation without completing the research and planning phases.
|
|
35
|
+
|
|
36
|
+
### Phase 1: Discovery & Evidence Collection
|
|
37
|
+
|
|
38
|
+
1. Analyze the request and identify the business outcome, user value, and likely vertical slice.
|
|
39
|
+
2. Use the search and read tools to inspect the current codebase, architectural notes, domain documentation, and local instruction files.
|
|
40
|
+
3. Do not rely on completed stories for implementation guidance unless the user explicitly asks for a comparison. They may be stale.
|
|
41
|
+
4. Determine the Bounded Context.
|
|
42
|
+
5. Build an evidence set from the repository:
|
|
43
|
+
- current entrypoints or commands
|
|
44
|
+
- existing domain/application modules
|
|
45
|
+
- existing routes, services, workflows, repos, DTOs, entities, value objects, or UI components
|
|
46
|
+
- renderer/output layers and infrastructure touchpoints
|
|
47
|
+
- existing tests that cover or neighbor the feature
|
|
48
|
+
6. Identify the likely domain artifacts involved. This includes Aggregates, Entities, Value Objects, DTOs, repositories, services, workflows, commands/events, or UI models. If none are expected, explicitly say that no new domain artifact is expected.
|
|
49
|
+
7. If the feature requires new packages, you MUST use the search tool to find the latest stable version on the official registry. Do not guess the version.
|
|
50
|
+
8. For non-trivial work, collect enough evidence to name concrete files. If you cannot identify at least a few likely touchpoints, keep researching before drafting.
|
|
51
|
+
|
|
52
|
+
### Phase 2: Architectural Validation
|
|
53
|
+
|
|
54
|
+
1. Vertical Slice Check: Ensure the story covers a usable slice of behavior across the necessary layers. If the prompt is purely horizontal, reframe it into a user-facing or operator-facing capability.
|
|
55
|
+
2. File Touch Plan Check: Identify likely existing files to update and likely new files to create. For each file, capture why it belongs in the plan.
|
|
56
|
+
3. Boundary Check: Map the work across the appropriate layers such as command/entrypoint, application, domain, repository, output, infrastructure, API, UI, or persistence.
|
|
57
|
+
4. SOLID and DDD Check: Ensure responsibilities stay separated. Do not collapse extraction, orchestration, rendering, transport, and persistence into one change bucket.
|
|
58
|
+
5. Pattern Alignment Check: Follow the guidance and scaffolds in Sample-dot-github. Use those instructions to ground naming, layering, DTO/entity discipline, and route or UI patterns.
|
|
59
|
+
6. Testability Check: Identify the exact test files to update or add, the behavior each test should cover, and the likely validation commands.
|
|
60
|
+
7. Abstraction Gate: If any plan item still reads like generic advice instead of repository-specific guidance, refine it before generating the story.
|
|
61
|
+
|
|
62
|
+
### Phase 3: Story Generation
|
|
63
|
+
|
|
64
|
+
1. Formulate a concise, descriptive title.
|
|
65
|
+
2. Draft the story using the strict template below.
|
|
66
|
+
3. Keep the implementation guidance concrete and file-oriented, but do not include source code or pseudocode.
|
|
67
|
+
4. Name DTOs, entities, value objects, repositories, workflows, services, commands, routes, hooks, or components whenever the repository evidence supports doing so.
|
|
68
|
+
5. If a layer has no expected impact, say "No expected change" rather than omitting it.
|
|
69
|
+
6. Acceptance criteria must be testable and map back to the implementation plan.
|
|
70
|
+
|
|
71
|
+
### Phase 4: Review & File Operations
|
|
72
|
+
|
|
73
|
+
1. Review the story against the original request. Confirm that it captures the business need and implementation path.
|
|
74
|
+
2. Run the Concrete Story Checklist before saving:
|
|
75
|
+
- The story names concrete files or directories likely involved.
|
|
76
|
+
- The story identifies likely domain artifacts or explicitly states none are expected.
|
|
77
|
+
- The story explains how the work crosses repository layers.
|
|
78
|
+
- The story names tests to add or update.
|
|
79
|
+
- Any package dependency includes a verified version and install command.
|
|
80
|
+
- The plan does not rely on vague phrases like "update relevant files" or "add necessary tests."
|
|
81
|
+
3. Save the story in /stories/{bounded-context-or-feature-dir}/{story-name}.md using the edit or execute tools.
|
|
82
|
+
|
|
83
|
+
## Story Authoring Rules
|
|
84
|
+
|
|
85
|
+
- Prefer repository-relative file paths.
|
|
86
|
+
- When a file does not exist yet but is a likely addition, mark it clearly as a new file.
|
|
87
|
+
- Each file in the File Touch Plan must include a reason.
|
|
88
|
+
- If you infer a DTO or entity name from current naming conventions, present it as "likely" when appropriate.
|
|
89
|
+
- Keep stories implementation-ready, not code-heavy.
|
|
90
|
+
- Do not paste large code snippets into the story.
|
|
91
|
+
- Do not invent packages, versions, or architectural layers that are not supported by the codebase evidence.
|
|
92
|
+
|
|
93
|
+
## User Story Template
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
# {Story Title}
|
|
97
|
+
|
|
98
|
+
## User Story
|
|
99
|
+
As a {user type}, I want to {action} so that {benefit}.
|
|
100
|
+
|
|
101
|
+
## Business Outcome
|
|
102
|
+
- {What changes for the user, operator, or developer when this story is complete}
|
|
103
|
+
|
|
104
|
+
## Domain Context
|
|
105
|
+
- **Bounded Context:** {The specific DDD bounded context this belongs to}
|
|
106
|
+
- **Primary Capability:** {The business or technical capability being added}
|
|
107
|
+
- **Existing Artifacts Involved:** {Existing entities, value objects, DTOs, services, repos, workflows, routes, commands, components, or modules already present}
|
|
108
|
+
- **New or Updated Artifacts Likely Needed:** {Best-effort list of DTOs, entities, value objects, workflows, services, repos, routes, hooks, components, or helper modules. If none: "No new domain artifacts expected."}
|
|
109
|
+
|
|
110
|
+
## Codebase Evidence
|
|
111
|
+
- `{path}` - {Why this file or directory matters to the implementation}
|
|
112
|
+
- `{path}` - {Why this file or directory matters to the implementation}
|
|
113
|
+
- `{path}` - {Why this file or directory matters to the implementation}
|
|
114
|
+
|
|
115
|
+
## File Touch Plan
|
|
116
|
+
| Path | Change | Reason |
|
|
117
|
+
| --- | --- | --- |
|
|
118
|
+
| `{path}` | update | {What will likely change here} |
|
|
119
|
+
| `{path}` | create | {Why a new file is likely needed} |
|
|
120
|
+
| `{path}` | verify | {Why this file should be checked even if no code change is certain yet} |
|
|
121
|
+
|
|
122
|
+
## Technical Implementation Plan
|
|
123
|
+
|
|
124
|
+
### Vertical Slice Summary
|
|
125
|
+
{Summarize the end-to-end path of the feature through the repository.}
|
|
126
|
+
|
|
127
|
+
### Entry Points and Orchestration
|
|
128
|
+
{Describe command, route, workflow, or UI entrypoints involved. If no change: "No expected change."}
|
|
129
|
+
|
|
130
|
+
### Domain and Application Changes
|
|
131
|
+
{Describe DTO/entity/value object/repository/service/workflow changes with concrete references to the repository structure. If no change: "No expected change."}
|
|
132
|
+
|
|
133
|
+
### API, UI, Output, or Infrastructure Changes
|
|
134
|
+
{Describe boundary-layer changes such as route handlers, renderers, presenters, output formatters, infrastructure adapters, or UI components. If no change: "No expected change."}
|
|
135
|
+
|
|
136
|
+
### Data, Contracts, and Edge Cases
|
|
137
|
+
{Call out schema, contracts, validation, compatibility expectations, failure states, and negative paths.}
|
|
138
|
+
|
|
139
|
+
### Testing and Validation Plan
|
|
140
|
+
- `{test path}` - {Behavior to cover}
|
|
141
|
+
- `{test path}` - {Behavior to cover}
|
|
142
|
+
- Validation commands: `{command}`
|
|
143
|
+
|
|
144
|
+
## Dependency & Package Requirements
|
|
145
|
+
{List required packages, external dependencies, or infrastructural needs.
|
|
146
|
+
If none: "No new packages required."}
|
|
147
|
+
|
|
148
|
+
## Assumptions & Open Questions
|
|
149
|
+
- {Assumption grounded in current repo evidence}
|
|
150
|
+
- {Uncertainty that needs confirmation from a product owner or architect}
|
|
151
|
+
|
|
152
|
+
## Acceptance Criteria
|
|
153
|
+
- {Specific happy-path behavior with observable result}
|
|
154
|
+
- {Specific failure-path or boundary behavior}
|
|
155
|
+
- {Specific validation of files, contracts, or output shape}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Important Packaging Rules
|
|
159
|
+
|
|
160
|
+
If a story requires packages, you must include the exact native package manager command with the verified latest version. Do not hallucinate versions.
|
|
161
|
+
|
|
162
|
+
- Python: `uv add {package-name}@{version}`
|
|
163
|
+
- Node: `npm install {package-name}@{version}`
|
|
164
|
+
- Rust: `cargo add {package-name}@{version}`
|
|
165
|
+
- Golang: `go get {package-name}@{version}`
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Publish PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Check out repository
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.14"
|
|
23
|
+
|
|
24
|
+
- name: Set up uv
|
|
25
|
+
uses: astral-sh/setup-uv@v5
|
|
26
|
+
|
|
27
|
+
- name: Validate tag matches package version
|
|
28
|
+
run: |
|
|
29
|
+
python - <<'PY'
|
|
30
|
+
from pathlib import Path
|
|
31
|
+
import os
|
|
32
|
+
import re
|
|
33
|
+
|
|
34
|
+
version_text = Path("src/rpr/__init__.py").read_text()
|
|
35
|
+
match = re.search(r'__version__\s*=\s*"([^"]+)"', version_text)
|
|
36
|
+
if match is None:
|
|
37
|
+
raise SystemExit("Could not find __version__ in src/rpr/__init__.py")
|
|
38
|
+
|
|
39
|
+
version = match.group(1)
|
|
40
|
+
ref = os.environ["GITHUB_REF_NAME"]
|
|
41
|
+
if ref != f"v{version}":
|
|
42
|
+
raise SystemExit(
|
|
43
|
+
f"Tag {ref!r} does not match package version v{version!r}"
|
|
44
|
+
)
|
|
45
|
+
PY
|
|
46
|
+
|
|
47
|
+
- name: Build distribution artifacts
|
|
48
|
+
run: uv build
|
|
49
|
+
|
|
50
|
+
- name: Publish to PyPI
|
|
51
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
52
|
+
with:
|
|
53
|
+
user: __token__
|
|
54
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
rpr_cli-0.1.1/.gitignore
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.venv/
|
|
6
|
+
*.egg
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
|
|
10
|
+
# Environment
|
|
11
|
+
.env
|
|
12
|
+
.env.local
|
|
13
|
+
.env.*.local
|
|
14
|
+
|
|
15
|
+
# IDE
|
|
16
|
+
.idea/
|
|
17
|
+
.vscode/
|
|
18
|
+
*.swp
|
|
19
|
+
*.swo
|
|
20
|
+
|
|
21
|
+
# Rust
|
|
22
|
+
rpr-parser/target/
|
|
23
|
+
|
|
24
|
+
# OS
|
|
25
|
+
.DS_Store
|
|
26
|
+
Thumbs.db
|
|
27
|
+
|
|
28
|
+
.notes
|
rpr_cli-0.1.1/CLAUDE.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
uv sync
|
|
10
|
+
|
|
11
|
+
# Install CLI globally
|
|
12
|
+
uv tool install .
|
|
13
|
+
|
|
14
|
+
# Run tests
|
|
15
|
+
uv run pytest
|
|
16
|
+
|
|
17
|
+
# Run a single test file
|
|
18
|
+
uv run pytest tests/test_init.py
|
|
19
|
+
|
|
20
|
+
# Run a single test
|
|
21
|
+
uv run pytest tests/test_init.py::test_function_name
|
|
22
|
+
|
|
23
|
+
# Lint and format
|
|
24
|
+
uvx ruff check .
|
|
25
|
+
uvx ruff format .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Architecture
|
|
29
|
+
|
|
30
|
+
RPR is a CLI tool (built with Typer) that bootstraps and manages NX + UV monorepos with a Domain-Driven Design (DDD) architecture. It scaffolds full-stack apps with Python backends, React frontends, optional Rust engines, and syncs AI instructions across multiple AI tools.
|
|
31
|
+
|
|
32
|
+
### Command Structure
|
|
33
|
+
|
|
34
|
+
- `rpr init` — bootstraps an NX workspace with UV workspace configuration
|
|
35
|
+
- `rpr generate [domain|api|ui|engine|storybook]` — creates new packages/apps with boilerplate
|
|
36
|
+
- `rpr sync rules` — reads instructions from `src/rpr/scaffolds/instructions/` and generates AI tool config files (`.cursor/rules/*.mdc`, `.github/copilot-instructions.md`, `CLAUDE.md`, `GEMINI.md`)
|
|
37
|
+
- `rpr add template` — extracts code blocks from markdown templates, interpolates variables, writes to target paths
|
|
38
|
+
- `rpr check` — validates workspace structure, instructions, packages
|
|
39
|
+
|
|
40
|
+
### Core Abstractions
|
|
41
|
+
|
|
42
|
+
**`RunContext`** (`src/rpr/context.py`) — wraps all file I/O and shell execution. Every command receives a `RunContext` and uses it for all operations. Supports `--dry-run` which previews changes without writing anything.
|
|
43
|
+
|
|
44
|
+
**`SyncConfig`** (`src/rpr/generators/base.py`) — parsed from `.rpr.yaml` in the target project. Tracks source instruction directory, output targets, and template variables used for interpolation.
|
|
45
|
+
|
|
46
|
+
**`Rule`** objects — parsed from markdown instruction files. Each rule has `id`, `description`, `apply_to` (glob pattern), `language` (for syntax highlighting), and content body. Used by all AI instruction generators.
|
|
47
|
+
|
|
48
|
+
**Template registry** (`src/rpr/templates/registry.py`) — maps template IDs (e.g. `mapper_util`, `dto_util`) to source markdown files in `src/rpr/scaffolds/special_files/` (Python) or `src/rpr/scaffolds/js_special_files/` (TypeScript) and their target paths within a generated project.
|
|
49
|
+
|
|
50
|
+
### Scaffolding System
|
|
51
|
+
|
|
52
|
+
Templates live in two places:
|
|
53
|
+
|
|
54
|
+
- `src/rpr/scaffolds/instructions/` — AI instruction markdown files bundled into the package
|
|
55
|
+
- `src/rpr/scaffolds/special_files/` and `src/rpr/scaffolds/js_special_files/` — code templates (Python/TypeScript) referenced by `rpr add template`
|
|
56
|
+
|
|
57
|
+
Generate commands (ui, engine, storybook) build file trees by writing individual files via `RunContext`, not by copying directory trees. Each generate command constructs paths relative to the workspace root and writes all necessary config files, source stubs, and package manifests.
|
|
58
|
+
|
|
59
|
+
### AI Instruction Generators
|
|
60
|
+
|
|
61
|
+
Each generator in `src/rpr/generators/` takes a list of `Rule` objects and produces output in a tool-specific format:
|
|
62
|
+
|
|
63
|
+
- `cursor.py` → `.cursor/rules/*.mdc` files (one per rule)
|
|
64
|
+
- `copilot.py` → `.github/copilot-instructions.md` (single concatenated file)
|
|
65
|
+
- `claude.py` → `CLAUDE.md`
|
|
66
|
+
- `gemini.py` → `GEMINI.md`
|
|
67
|
+
|
|
68
|
+
### Check System
|
|
69
|
+
|
|
70
|
+
`src/rpr/checks/` contains health check validators that inspect a workspace and return structured `CheckResult` objects. `rpr check` aggregates these and reports issues with Rich formatting.
|
rpr_cli-0.1.1/GEMINI.md
ADDED
|
File without changes
|
rpr_cli-0.1.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Harlen Alvarez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
rpr_cli-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rpr-cli
|
|
3
|
+
Version: 0.1.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: 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
|
+
# RPR CLI
|
|
17
|
+
|
|
18
|
+
React Python Rust monorepo scaffolding orchestrator.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
Published package name: `rpr-cli`
|
|
23
|
+
|
|
24
|
+
Once published to PyPI, install by name with either:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
uv add rpr-cli
|
|
28
|
+
uv tool install rpr-cli
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Both install the `rpr` command.
|
|
32
|
+
|
|
33
|
+
For development, editable install is fine:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uv tool install -e .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For an actual distributable install you can use in other projects, build the wheel first and install the built artifact:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uv build
|
|
43
|
+
uv tool install dist/rpr_cli-*.whl
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
From another local project you can also install the built artifact directly:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uv add ../project-getting-started/dist/rpr_cli-*.whl
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
### 🚀 Scaffolding & Generation
|
|
55
|
+
|
|
56
|
+
Scaffold a complete monorepo or add new apps and libraries.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
rpr init my-app # Scaffold a new monorepo (NX + UV)
|
|
60
|
+
rpr generate domain my-app # Add a domain package (shared logic & types)
|
|
61
|
+
rpr generate api my-app # Add a FastAPI application
|
|
62
|
+
rpr generate ui my-app # Add a React UI library + application
|
|
63
|
+
rpr generate engine my-app # Add a Rust/PyO3 computation engine
|
|
64
|
+
rpr generate storybook # Add Storybook for UI component development
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 🧠 AI Instructions & Code Templates
|
|
68
|
+
|
|
69
|
+
Sync project context to your favorite AI tools and add common code patterns.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
rpr sync rules # Sync AI instructions to Cursor, Copilot, Claude Code, and Gemini
|
|
73
|
+
rpr add template mapper_util # Add a common code template to your project
|
|
74
|
+
rpr add template --list # List all available code templates
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 💬 Interactive Shell
|
|
78
|
+
|
|
79
|
+
`rpr chat` is the primary interactive shell for the product. It runs a Rich-based session with slash commands for both chat controls and existing CLI workflows.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
rpr chat # Start the interactive shell
|
|
83
|
+
rpr chat --approval-mode auto-readonly # Override the session approval mode
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Inside the shell:
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
/help List supported slash commands
|
|
90
|
+
/settings Inspect and update persisted settings in-shell
|
|
91
|
+
/init Run workspace bootstrap from chat
|
|
92
|
+
/generate Run scaffolding commands from chat
|
|
93
|
+
/sync Sync AI instructions from chat
|
|
94
|
+
/add Add a registered template from chat
|
|
95
|
+
/check Run workspace health checks from chat
|
|
96
|
+
/map Generate a code map from chat
|
|
97
|
+
/exit End the session
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
There is no separate `--tui` mode. The unified shell is the default chat experience.
|
|
101
|
+
|
|
102
|
+
### 🛠️ Maintenance & Insights
|
|
103
|
+
|
|
104
|
+
Keep your project healthy and explore its structure.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
rpr check # Inspect project health and report setup status
|
|
108
|
+
rpr map # Generate a structured code map of your project
|
|
109
|
+
rpr settings # Inspect persisted shell settings
|
|
110
|
+
rpr settings set theme ocean # Update the terminal theme
|
|
111
|
+
rpr settings set approval_mode auto-all
|
|
112
|
+
rpr settings set startup_help false
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Persisted settings currently include:
|
|
116
|
+
|
|
117
|
+
- `theme`: Rich console theme
|
|
118
|
+
- `approval_mode`: default chat approval mode (`ask`, `auto-readonly`, `auto-all`)
|
|
119
|
+
- `startup_help`: whether chat shows slash-command guidance on startup
|
|
120
|
+
|
|
121
|
+
### ⚙️ Common Flags
|
|
122
|
+
|
|
123
|
+
Most commands support these global flags:
|
|
124
|
+
|
|
125
|
+
- `--dry-run`: Preview changes without writing any files.
|
|
126
|
+
- `--help`: Show detailed help for any command or subcommand.
|
|
127
|
+
|
|
128
|
+
Example:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
rpr generate api my-app --dry-run
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The `check` command also supports:
|
|
135
|
+
|
|
136
|
+
- `--json`: Output machine-readable JSON for CI/CD integration.
|
|
137
|
+
|
|
138
|
+
The `chat` command also supports:
|
|
139
|
+
|
|
140
|
+
- `--provider`: Override the AI provider. The mock provider is the only supported provider today.
|
|
141
|
+
- `--model`: Override the active model name.
|
|
142
|
+
- `--approval-mode`: Override the session approval mode without changing persisted settings.
|
|
143
|
+
|
|
144
|
+
### Project Development
|
|
145
|
+
|
|
146
|
+
#### Setup
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Install Python dependencies
|
|
150
|
+
uv sync
|
|
151
|
+
|
|
152
|
+
# Build the Rust extension (rpr_parser) — required for rpr map acceleration
|
|
153
|
+
cd rpr-parser && uv run maturin develop && cd ..
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
> **Note:** `uv tool install dist/rpr-*.whl` uses the root hatchling build backend and does **not** build the
|
|
157
|
+
> Rust extension. You must run `maturin develop` separately before using `rpr map` with the Rust
|
|
158
|
+
> backend. Without it, `rpr map` falls back to the pure-Python implementation automatically.
|
|
159
|
+
|
|
160
|
+
#### Running Tests
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Full test suite (Python)
|
|
164
|
+
uv run pytest
|
|
165
|
+
|
|
166
|
+
# Single test file
|
|
167
|
+
uv run pytest tests/test_map_extractor.py
|
|
168
|
+
|
|
169
|
+
# Single test
|
|
170
|
+
uv run pytest tests/test_map_extractor.py::test_fallback_returns_correct_shape
|
|
171
|
+
|
|
172
|
+
# Rust unit tests (rpr_parser crate)
|
|
173
|
+
cd rpr-parser && cargo test && cd ..
|
|
174
|
+
|
|
175
|
+
# Lint and format
|
|
176
|
+
uv run ruff check .
|
|
177
|
+
uv run ruff format .
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The Rust-path tests in `tests/test_map_extractor.py` are automatically skipped if the Rust
|
|
181
|
+
extension hasn't been built yet — run `maturin develop` first to enable them.
|
|
182
|
+
|
|
183
|
+
### Publishing To PyPI
|
|
184
|
+
|
|
185
|
+
This repo is set up to publish the package `rpr-cli` to PyPI from GitHub Actions.
|
|
186
|
+
|
|
187
|
+
One-time setup:
|
|
188
|
+
|
|
189
|
+
1. Create the PyPI project `rpr-cli`.
|
|
190
|
+
2. Add a repository secret named `PYPI_API_TOKEN` with an API token that can upload that project.
|
|
191
|
+
|
|
192
|
+
Release flow:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# update src/rpr/__init__.py with the new version
|
|
196
|
+
git commit -am "Release 0.1.2"
|
|
197
|
+
git tag v0.1.2
|
|
198
|
+
git push origin main --tags
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
The workflow in `.github/workflows/publish-pypi.yml` builds the sdist and wheel, checks that the tag matches the package version, and uploads `dist/*` to PyPI.
|