Implement typed command core with safety - #7
Conversation
Introduce a new module `sh` providing a typed core for building `SafeCmd` instances from curated `Program` values. The `sh.make` function enforces the curated catalogue allowlist upfront, converts positional and keyword arguments to a structured argv tuple, and attaches project metadata to produced commands. This facilitates safer CLI command assembly, carrying metadata for downstream runtime layers without executing commands at this phase. Includes: - `SafeCmd` dataclass to encapsulate program, argv, and project metadata - `SafeCmdBuilder` callable factory to build parameterized commands - Validation against the `ProgramCatalogue` with `UnknownProgramError` on unknown programs - Stringification of arguments with `None` rejection - Conversion of keyword args to CLI flags `--flag=value` with underscores to hyphens Also adds unit tests, documentation updates, and BDD features covering this new typed command core. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
Reviewer's GuideIntroduces a new typed SafeCmd command core and sh.make factory for building catalogue-validated command objects with structured argv and attached project metadata, wires these into the public cuprum API, and adds behaviour/docs/tests around safe argv handling and builder usage. Sequence diagram for sh.make usage and SafeCmd constructionsequenceDiagram
actor Client
participant sh as sh_module
participant Catalogue as ProgramCatalogue
participant Builder as SafeCmdBuilder
participant Cmd as SafeCmd
Client->>sh: make(program, catalogue)
sh->>Catalogue: lookup(program)
alt program known
Catalogue-->>sh: ProgramEntry(program, project)
sh-->>Client: Builder
Client->>Builder: __call__(*args, **kwargs)
Builder->>Builder: _coerce_argv(args, kwargs)
Builder->>Cmd: construct SafeCmd(program, argv, project)
Cmd-->>Client: SafeCmd instance
Client->>Cmd: argv_with_program
Cmd-->>Client: (program, *argv)
else program unknown
Catalogue-->>sh: raise UnknownProgramError
sh-->>Client: UnknownProgramError
end
Class diagram for SafeCmd core and sh.make factoryclassDiagram
class Program {
}
class ProjectSettings {
}
class ProgramCatalogue {
+lookup(program: Program) ProgramEntry
}
class ProgramEntry {
+program: Program
+project: ProjectSettings
}
class SafeCmd~Out_co~ {
+program: Program
+argv: tuple~str,...~
+project: ProjectSettings
+argv_with_program() tuple~str,...~
}
class SafeCmd_str {
}
class SafeCmdBuilder {
<<callable>>
+__call__(*args: object, **kwargs: object) SafeCmd~str~
}
class sh_module {
+_stringify_arg(value: object) str
+_serialize_kwargs(kwargs: dict~str,object~) tuple~str,...~
+_coerce_argv(args: tuple~object,...~, kwargs: dict~str,object~) tuple~str,...~
+make(program: Program, catalogue: ProgramCatalogue) SafeCmdBuilder
}
ProgramCatalogue --> ProgramEntry : returns
ProgramEntry --> Program : has
ProgramEntry --> ProjectSettings : has
SafeCmd~Out_co~ --> Program : uses
SafeCmd~Out_co~ --> ProjectSettings : uses
SafeCmd_str --> SafeCmd~Out_co~ : specializes
SafeCmdBuilder --> SafeCmd_str : builds
sh_module --> ProgramCatalogue : uses
sh_module --> SafeCmdBuilder : returns
sh_module --> SafeCmd_str : constructs
sh_module --> SafeCmd~Out_co~ : constructs
Flow diagram for argv construction in SafeCmd builderflowchart TD
A["Start: builder(*args, **kwargs)"] --> B["Iterate over positional args"]
B --> C["For each arg: _stringify_arg(arg)"]
C --> D{"arg is None?"}
D -->|Yes| E["Raise TypeError: None is not a valid argv element"]
D -->|No| F["Append str(arg) to positional list"]
F --> G{"More positional args?"}
G -->|Yes| C
G -->|No| H["Iterate over keyword items"]
H --> I["For each key, value in kwargs"]
I --> J["Normalize key: key.replace('_','-')"]
J --> K["_stringify_arg(value)"]
K --> L{"value is None?"}
L -->|Yes| E
L -->|No| M["Build flag '--{normalized_key}={value_str}'"]
M --> N["Append flag to flags list"]
N --> O{"More keyword items?"}
O -->|Yes| I
O -->|No| P["Combine positional tuple + flags tuple"]
P --> Q["Return argv tuple of str"]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Warning Rate limit exceeded@leynos has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 12 minutes and 24 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Summary by CodeRabbitRelease Notes
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughAdd a frozen Changes
Sequence DiagramsequenceDiagram
participant Client
participant sh as "cuprum.sh"
participant Catalogue as "ProgrammeCatalogue"
participant SafeCmdObj as "SafeCmd"
Client->>sh: make(program_name)
sh->>Catalogue: lookup(program_name)
alt programme found
Catalogue-->>sh: ProgrammeEntry
sh-->>Client: builder(callable)
Client->>builder: invoke(*args, **kwargs)
builder->>builder: _coerce_argv(*args, **kwargs)
builder->>builder: _stringify_arg(each)
builder->>builder: _serialize_kwargs(**kwargs)
builder->>SafeCmdObj: construct SafeCmd(program, argv, project)
SafeCmdObj-->>Client: SafeCmd instance
else programme not found
Catalogue-->>sh: not found
sh-->>Client: raise UnknownProgramError
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
Comment |
- Refined SafeCmd typing to remove Out_co generic. - Added support for Path in argument types. - Normalized keyword argument names from underscores to hyphens. - Reject None values as invalid positional or keyword args. - Updated tests to cover these new behaviors. - Improved docs with detailed design diagrams and clarifications. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
|
@coderabbitai Has this now been resolved in the latest commit? Use codegraph analysis to determine your answer. suggestion (testing): Cover underscore-to-hyphen conversion for keyword flags This test only covers simple kwarg → --k=v conversion and never passes a name containing an underscore. Please add or extend a test to call builder("hello", user_id=42) and assert that the flag is --user-id=42. That way the normalisation logic is exercised and the expected CLI flag style is explicitly captured in tests. |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 3682 🏁 Script executed: Length of output: 655 🏁 Script executed: Length of output: 409 @leynos Yes, this has been resolved in the latest commit. ✅ The test file now includes def test_keyword_arguments_normalise_underscores() -> None:
"""Kwarg names are normalised from underscores to hyphens."""
builder = sh.make(ECHO)
cmd = builder("hello", user_id=42)
assert cmd.argv[-1] == "--user-id=42", "Underscores should become hyphens"This test matches exactly what you requested in your original suggestion—it passes a keyword argument with an underscore ( |
There was a problem hiding this comment.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (8)
cuprum/__init__.py(2 hunks)cuprum/sh.py(1 hunks)cuprum/unittests/test_sh.py(1 hunks)docs/cuprum-design.md(8 hunks)docs/roadmap.md(1 hunks)docs/users-guide.md(1 hunks)tests/behaviour/test_catalogue_behaviour.py(5 hunks)tests/features/catalogue.feature(1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/**/*.md: Use markdown files within thedocs/directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in thedocs/directory to reflect the latest state.
All documentation must adhere to the documentation style guide atdocs/documentation-style-guide.md.
Record any design decisions made in the relevant design document.
Files:
docs/users-guide.mddocs/cuprum-design.mddocs/roadmap.md
docs/users-guide.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/users-guide.md: Ensure new functionality is clearly documented in thedocs/users-guide.mdfile.
Ensure revised functionality is clearly documented in thedocs/users-guide.mdfile.
docs/users-guide.md: Document the expected builder pattern indocs/users-guide.md
Provide a scaffold and guidance for project-specific builders, including a template module and checklist indocs/users-guide.md
Document policy switches and recommended defaults indocs/users-guide.mdand add release notes describing the migration path for existing users
Files:
docs/users-guide.md
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
**/*.md: For Markdown files (.md only), ensure linting passes by runningmake markdownlint.
For Markdown files, validate Mermaid diagrams by runningmake nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.
Validate Markdown files usingmake markdownlint.
Runmake fmtafter any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by runningmake nixie.
Files:
docs/users-guide.mddocs/cuprum-design.mddocs/roadmap.md
⚙️ CodeRabbit configuration file
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Headings must not be wrapped.
- Documents must start with a level 1 heading
- Headings must correctly increase or decrease by no more than one level at a time
- Use GitHub-flavoured Markdown style for footnotes and endnotes.
- Numbered footnotes must be numbered by order of appearance in the document.
Files:
docs/users-guide.mddocs/cuprum-design.mddocs/roadmap.md
docs/**/*.{md,mdx,rst,txt}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
docs/**/*.{md,mdx,rst,txt}: Use British English based on Oxford English Dictionary (en-GB-oxendict) conventions: use -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse, catalyse), -our suffixes (colour, behaviour, neighbour), -re suffixes (calibre, centre, fibre), double 'l' (cancelled, counsellor, cruellest), maintain 'e' (likeable, liveable, rateable), -ogue suffixes (analogue, catalogue)
The word 'outwith' is acceptable in documentation
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation, for example 'Lille Industries are expanding'
Write headings in sentence case in documentation
Use Markdown headings (#,##,###, and so on) in order without skipping levels
Always provide a language identifier for fenced code blocks in documentation; use 'plaintext' for non-code text
Use-as the first level bullet and renumber lists when items change in documentation
Prefer inline links using[text](url)or angle brackets around the URL in documentation
Ensure blank lines before and after bulleted lists and fenced blocks in documentation
Ensure tables have a delimiter line below the header row in documentation
Expand any uncommon acronym on first use in documentation, for example 'Continuous Integration (CI)'
Wrap paragraphs at 80 columns in documentation
Wrap code at 120 columns in documentation
Do not wrap tables in documentation
Use footnotes referenced with[^label]in documentation
Include Mermaid diagrams in documentation where they add clarity
When embedding figures in documentation, useand provide brief alt text describing the content
Add a short description before each Mermaid diagram in documentation so screen readers can understand it
Files:
docs/users-guide.mddocs/cuprum-design.mddocs/roadmap.md
docs/**/*.{md,mdx,rst,txt,rs}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Keep US spelling when used in API contexts, for example 'color'
Files:
docs/users-guide.mddocs/cuprum-design.mddocs/roadmap.md
docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Follow markdownlint recommendations for Markdown formatting
Files:
docs/users-guide.mddocs/cuprum-design.mddocs/roadmap.md
**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
**/*.py: For Python files, ensure testing passes all relevant unit and behavioral tests by runningmake test.
For Python files, ensure linting passes by runningmake lint.
For Python files, ensure formatting adheres to standards by runningmake check-fmtand applyingmake fmtif needed.
For Python files, ensure type checking passes by runningmake typecheck.
For Python development, refer to Python-specific guidelines in the.rules/directory, including Python Code Style Guidelines, Context Managers, Exceptions and Logging, Generators, Project Configuration, Return Patterns, and Typing.
**/*.py: Use snake_case for Python filenames (e.g., http_client.py, task_queue.py)
Use PascalCase for class names
Use snake_case for variable and function names
Use UPPER_SNAKE_CASE for module-level constants
Prefix private/internal functions and variables with a single underscore (_)
Enable full static type coverage using Pyright and maintain typing throughout the codebase
Use TypedDict or Dataclass for structured data, preferring @DataClass(slots=True) for internal-only usage
Avoid using Any type; use Unknown, generics, or cast() with documentation instead
Provide explicit return type annotations (e.g., -> None, -> str) for all public functions and class methods
Enforce strict mode in Pyright and treat all Pyright warnings as CI errors; use # pyright: ignore sparingly with explanation
Avoid side effects at import time; modules should not modify global state or perform actions on import
Use .env or settings modules for environment-specific configuration; never hardcode secrets
Use Ruff for formatting; let Ruff handle whitespace and formatting entirely
Use NumPy-format docstrings for public functions, classes, and modules
Use inline comments to explain tricky or non-obvious code logic and decisions
**/*.py: Use context managers (withcontextlib.contextmanageror class-based__enter__/__exit__) to encapsulate setup and teardown logic for resource management (f...
Files:
cuprum/unittests/test_sh.pycuprum/sh.pytests/behaviour/test_catalogue_behaviour.pycuprum/__init__.py
⚙️ CodeRabbit configuration file
**/*.py: - Keep C90 / mccabe complexity ≤ 9
- Follow single responsibility and CQRS (command/query segregation)
- Prefer structural pattern matching to
- Prefer structural pattern matching over
isinstance()or imperative decomposition.- Docstrings must follow the
numpystyle guide. Use a single-line summary for private functions and methods, and full structured docs for all public interfaces.- Move conditionals with >2 branches to predicate/helper functions
- Avoid
eval,exec,pickle, monkey-patching,ctypes, unsafe shell- Every module must begin with a triple-quoted docstring explaining its purpose, utility, and usage, including example calls if appropriate.
- Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Lint suppressions:
- Blanket
# noqa, file-level skips, and categories are forbidden- Only narrow in-line disables (
# noqa: XYZ) are permitted, and must be accompanied byFIXME:or a ticket link, and used only as a last resort.- Use
pytestfixtures for shared setup (conftest.pyorfixtures/)- Replace duplicate tests with
@pytest.mark.parametrize- Prefer
pytest-mockorunittest.mockfor stubs/mocks- Use
assert …, "message"over bare asserts- Reflect all API/behaviour changes in
docs/and update roadmap on completion- Files must not exceed 400 logical lines:
- Decompose large modules into subpackages
- Split large
match/caseor dispatch tables by domain and collocate with targets if appropriate- Move bulky data (fixtures, templates) to external files for parsing at runtime
- Mutable defaults and shadowed built-ins are forbidden
- All code must have clear type hints using modern style (
A | B,list[str],class Foo[A]:,type Bar = int, etc.), with ABC imports drawn from the correct stdlib module.- All path manipulation must be performed using pathlib for cross platform safety. Do not use string manipulation for extraction of path components or filename ele...
Files:
cuprum/unittests/test_sh.pycuprum/sh.pytests/behaviour/test_catalogue_behaviour.pycuprum/__init__.py
**/unittests/test_*.py
📄 CodeRabbit inference engine (.rules/python-00.md)
Colocate unit tests with code using an unittests subdirectory with test_ prefix (e.g., user_auth/unittests/test_models.py)
Files:
cuprum/unittests/test_sh.py
**/test_*.py
📄 CodeRabbit inference engine (.rules/python-00.md)
**/test_*.py: Use pytest idioms: prefer fixtures over setup/teardown methods, parametrize broadly, avoid unnecessary mocks
Group related tests using class with method names prefixed by test_
Write tests from a user's perspective; test public behavior rather than internals
Avoid mocking too much; prefer test doubles only for external services or non-deterministic behaviors
Files:
cuprum/unittests/test_sh.pytests/behaviour/test_catalogue_behaviour.py
**/*test*.py
📄 CodeRabbit inference engine (.rules/python-exception-design-raising-handling-and-logging.md)
Use specific exception types and message constraints with
pytest.raises(SpecificError, match=r"pattern")in tests; avoid overly broad exception assertions (B017)
Files:
cuprum/unittests/test_sh.pytests/behaviour/test_catalogue_behaviour.py
🧬 Code graph analysis (4)
cuprum/unittests/test_sh.py (2)
cuprum/catalogue.py (3)
ProgramCatalogue(56-119)ProjectSettings(30-40)UnknownProgramError(25-26)cuprum/sh.py (4)
make(76-92)builder(88-90)SafeCmd(63-73)argv_with_program(71-73)
cuprum/sh.py (1)
cuprum/catalogue.py (4)
ProgramCatalogue(56-119)ProjectSettings(30-40)UnknownProgramError(25-26)lookup(76-83)
tests/behaviour/test_catalogue_behaviour.py (2)
cuprum/catalogue.py (4)
ProgramCatalogue(56-119)ProgramEntry(44-53)ProjectSettings(30-40)UnknownProgramError(25-26)cuprum/sh.py (4)
SafeCmd(63-73)builder(88-90)make(76-92)argv_with_program(71-73)
cuprum/__init__.py (1)
cuprum/sh.py (1)
SafeCmd(63-73)
🪛 LanguageTool
docs/users-guide.md
[uncategorized] ~46-~46: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...nd carry project metadata alongside argv so downstream services can apply noise rul...
(COMMA_COMPOUND_SENTENCE_2)
[style] ~68-~68: Would you like to use the Oxford spelling “centralize”? The spelling ‘centralise’ is also correct.
Context: ...s Wrap sh.make in project modules to centralise validation and expose a clear API for c...
(OXFORD_SPELLING_Z_NOT_S)
docs/cuprum-design.md
[style] ~459-~459: Would you like to use the Oxford spelling “serialized”? The spelling ‘serialised’ is also correct.
Context: ...d with str(). Keyword arguments are serialised as --flag=value, replacing underscore...
(OXFORD_SPELLING_Z_NOT_S)
[style] ~467-~467: Would you like to use the Oxford spelling “summarizes”? The spelling ‘summarises’ is also correct.
Context: ... extra lookup. The following diagram summarises the relationships in the typed command ...
(OXFORD_SPELLING_Z_NOT_S)
🔍 Remote MCP
Let me try a different approach and search for the general cuprum project repository information:Based on the context provided in the PR summary, I have sufficient information to provide a concise review summary. The Deepwiki searches couldn't access the leynos/cuprum repository, but the AI summaries and PR objectives provide comprehensive details about the changes. Let me compile the relevant findings:
Summary of Key Review Context
Based on analysis of the provided PR documentation, here are the relevant facts for reviewing this pull request:
Core Component Integration
The PR introduces SafeCmd as a typed wrapper for command representations that integrates with existing Programme and ProgrammeCatalogue infrastructure. The implementation provides:
- SafeCmd dataclass: Contains (program, argv, project) fields and an
argv_with_programproperty that includes the program name in the argv - sh.make() factory: Validates programs exist in a catalogue before returning a builder, raising
UnknownProgramErrorif not found - Argument handling: Supports positional argument stringification, keyword argument serialization to CLI flags (--flag=value), and underscore-to-hyphen conversion
Public API Expansion
The changes make SafeCmd, SafeCmdBuilder, and the sh submodule publicly available via cuprum/__init__.py, marking a new public surface area that requires stability considerations for future releases.
Test Coverage Status
Unit tests in cuprum/unittests/test_sh.py cover:
- Unknown program rejection
- Metadata population from catalogues
- Keyword argument serialization
- Non-string positional argument stringification
- None value rejection with TypeError
- Custom catalogue injection
Note from comments: There is an open testing suggestion to explicitly verify underscore-to-hyphen conversion with a test case like builder("hello", user_id=42) asserting --user-id=42. Current tests check simple kwarg conversion but may not explicitly exercise the normalization logic.
Documentation Updates
- docs/cuprum-design.md: Added implementation notes with component relationship diagrams for the typed command core
- docs/users-guide.md: New section documenting sh.make workflow, argument formatting, and error handling
- docs/roadmap.md: sh.make task marked complete
Scope Clarification
SafeCmd is intentionally limited to command representation only; command execution functionality is out of scope for this PR.
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Sourcery review
🔇 Additional comments (18)
docs/users-guide.md (1)
41-97: Documentation for the typed command core is clear and comprehensive.The new section accurately documents the sh.make workflow, argument handling rules, and project-specific builder patterns. Examples align with the implementation in cuprum/sh.py.
docs/roadmap.md (1)
18-20: Roadmap update accurately reflects the delivered functionality.The sh.make task is correctly marked complete, and the description aligns with the implemented SafeCmd builder and documentation additions.
docs/cuprum-design.md (1)
469-523: Mermaid diagram accurately captures the typed command core relationships.The class diagram correctly illustrates the relationships between Program, ProgramCatalogue, ProgramEntry, SafeCmd, SafeCmdBuilder, and sh_module, aligning with the implementation in cuprum/sh.py and cuprum/catalogue.py.
tests/features/catalogue.feature (1)
19-23: Feature scenario provides good behavioural coverage for the SafeCmd builder.The scenario exercises the sh.make facade, verifying argv construction and metadata exposure, aligning with the implementation in cuprum/sh.py.
cuprum/__init__.py (1)
30-32: Package exports correctly expose the new typed command core.The imports and all additions properly expose SafeCmd, SafeCmdBuilder, and the sh submodule, enabling both direct imports (
from cuprum import SafeCmd) and facade access (cuprum.sh.make()).cuprum/unittests/test_sh.py (4)
59-65: Underscore-to-hyphen normalisation test addresses the past review concern.This test explicitly exercises the flag name normalisation logic, confirming that
user_id=42becomes--user-id=42.
81-98: None rejection tests correctly lock in the expected behaviour.Both positional and keyword argument None rejection are tested, ensuring the TypeError with "None" in the message is raised as specified in the documentation.
101-118: Custom catalogue injection test ensures metadata flows correctly.The test verifies that a custom ProgramCatalogue's metadata is surfaced in the resulting SafeCmd, which is essential for downstream services.
68-78: Ensure Path objects are stringified consistently across platforms in_stringify_arg.The test expects
working_dir.as_posix()in argv, but if the implementation usesstr(working_dir), this will fail on Windows becausestr(Path)returns backslash-separated paths while.as_posix()always returns forward slashes. Either update the implementation to explicitly call.as_posix()for Path objects, or align the test assertion to usestr(working_dir)if that matches the actual implementation.tests/behaviour/test_catalogue_behaviour.py (3)
102-108: Fixture creates Program without validating catalogue presence.The
given_curated_programfixture creates a Program directly without verifying it exists in DEFAULT_CATALOGUE. The validation happens insh.make()during the When step, which is appropriate, but the Given step's docstring ("curated Program value for sh.make scenarios") could be clearer that catalogue validation is deferred.
129-140: When step correctly constructs SafeCmd via sh.make facade.The step builds a SafeCmd using the provided arguments, exercising the builder pattern as intended.
188-209: Then steps provide appropriate assertions for argv and metadata.The assertions verify both the argv_with_program structure and the exposure of project metadata (noise_rules, documentation_locations), ensuring downstream services can access the required information.
cuprum/sh.py (6)
1-7: Module docstring clearly establishes scope and intent.The docstring effectively communicates the module's focus on typed command construction whilst explicitly excluding execution concerns. This boundary is essential for maintaining separation of concerns.
9-24: Imports follow best practices.The use of deferred annotations, standard aliases (
cabc), and theTYPE_CHECKINGguard forProgramdemonstrates adherence to modern Python typing patterns and avoids circular import issues.
26-27: Type aliases use modern PEP 695 syntax correctly.The explicit exclusion of
Nonefrom_ArgValuepaired with the runtime check in_stringify_argprovides both static and dynamic safety.
62-74: SafeCmd correctly implements frozen dataclass with proper type handling.The use of
str(self.program)inargv_with_programcorrectly addresses the past review concern, ensuring the returned tuple contains onlystrelements as per the annotation. Thefrozen=True, slots=Trueconfiguration follows guidelines for internal data structures.
95-95: Explicit__all__correctly defines the public API surface.
30-59: Add explicit return type annotations to private helpers for Pyright strict mode compatibility.Whilst the coding guidelines mandate return annotations only for public functions and class methods, Pyright in strict mode benefits from explicit annotations on all functions. Add
-> strto_stringify_arg,-> tuple[str, ...]to_serialize_kwargs, and-> tuple[str, ...]to_coerce_argv.Apply this diff to add return type annotations:
-def _stringify_arg(value: _ArgValue) -> str: +def _stringify_arg(value: _ArgValue) -> str: """Convert values into argv-safe strings. ``None`` is disallowed because it is almost always a mistake in CLI argv construction. Callers should decide how to represent missing values (for example, omit the flag) before invoking ``sh.make``. """ if value is None: msg = "None is not a valid argv element for sh.make" raise TypeError(msg) return str(value) -def _serialize_kwargs(kwargs: dict[str, _ArgValue]) -> tuple[str, ...]: +def _serialize_kwargs(kwargs: dict[str, _ArgValue]) -> tuple[str, ...]: """Serialise keyword arguments to CLI-style ``--flag=value`` entries.""" flags: list[str] = [] for key, value in kwargs.items(): normalized_key = key.replace("_", "-") flags.append(f"--{normalized_key}={_stringify_arg(value)}") return tuple(flags) -def _coerce_argv( +def _coerce_argv( args: tuple[_ArgValue, ...], kwargs: dict[str, _ArgValue], -) -> tuple[str, ...]: +) -> tuple[str, ...]: """Convert positional and keyword arguments into a single argv tuple.""" positional = tuple(_stringify_arg(arg) for arg in args) flags = _serialize_kwargs(kwargs) return positional + flagsLikely an incorrect or invalid review comment.
Corrected spelling from British English to American English for consistency in the documentation: - serialised -> serialized - summarises -> summarizes - centralise -> centralize This improves clarity and aligns with the project's language style guidelines. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
|
@coderabbitai have the following now been resolved?
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 2985 @leynos Yes, all three issues have been resolved in the current implementation. ✅
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 4
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
docs/cuprum-design.md(8 hunks)docs/users-guide.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/**/*.md: Use markdown files within thedocs/directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in thedocs/directory to reflect the latest state.
All documentation must adhere to the documentation style guide atdocs/documentation-style-guide.md.
Record any design decisions made in the relevant design document.
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/users-guide.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/users-guide.md: Ensure new functionality is clearly documented in thedocs/users-guide.mdfile.
Ensure revised functionality is clearly documented in thedocs/users-guide.mdfile.
docs/users-guide.md: Document the expected builder pattern indocs/users-guide.md
Provide a scaffold and guidance for project-specific builders, including a template module and checklist indocs/users-guide.md
Document policy switches and recommended defaults indocs/users-guide.mdand add release notes describing the migration path for existing users
Files:
docs/users-guide.md
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
**/*.md: For Markdown files (.md only), ensure linting passes by runningmake markdownlint.
For Markdown files, validate Mermaid diagrams by runningmake nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.
Validate Markdown files usingmake markdownlint.
Runmake fmtafter any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by runningmake nixie.
Files:
docs/users-guide.mddocs/cuprum-design.md
⚙️ CodeRabbit configuration file
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Headings must not be wrapped.
- Documents must start with a level 1 heading
- Headings must correctly increase or decrease by no more than one level at a time
- Use GitHub-flavoured Markdown style for footnotes and endnotes.
- Numbered footnotes must be numbered by order of appearance in the document.
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/**/*.{md,mdx,rst,txt}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
docs/**/*.{md,mdx,rst,txt}: Use British English based on Oxford English Dictionary (en-GB-oxendict) conventions: use -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse, catalyse), -our suffixes (colour, behaviour, neighbour), -re suffixes (calibre, centre, fibre), double 'l' (cancelled, counsellor, cruellest), maintain 'e' (likeable, liveable, rateable), -ogue suffixes (analogue, catalogue)
The word 'outwith' is acceptable in documentation
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation, for example 'Lille Industries are expanding'
Write headings in sentence case in documentation
Use Markdown headings (#,##,###, and so on) in order without skipping levels
Always provide a language identifier for fenced code blocks in documentation; use 'plaintext' for non-code text
Use-as the first level bullet and renumber lists when items change in documentation
Prefer inline links using[text](url)or angle brackets around the URL in documentation
Ensure blank lines before and after bulleted lists and fenced blocks in documentation
Ensure tables have a delimiter line below the header row in documentation
Expand any uncommon acronym on first use in documentation, for example 'Continuous Integration (CI)'
Wrap paragraphs at 80 columns in documentation
Wrap code at 120 columns in documentation
Do not wrap tables in documentation
Use footnotes referenced with[^label]in documentation
Include Mermaid diagrams in documentation where they add clarity
When embedding figures in documentation, useand provide brief alt text describing the content
Add a short description before each Mermaid diagram in documentation so screen readers can understand it
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/**/*.{md,mdx,rst,txt,rs}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Keep US spelling when used in API contexts, for example 'color'
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Follow markdownlint recommendations for Markdown formatting
Files:
docs/users-guide.mddocs/cuprum-design.md
🪛 LanguageTool
docs/users-guide.md
[uncategorized] ~46-~46: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...nd carry project metadata alongside argv so downstream services can apply noise rul...
(COMMA_COMPOUND_SENTENCE_2)
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Sourcery review
🔇 Additional comments (2)
docs/users-guide.md (1)
87-87: Verify generic parameter onSafeCmdtype annotation.The documentation shows
sh.SafeCmd[str]with a generic parameter, but the PR objectives state that the SafeCmd generic was removed and is now a plain dataclass. Clarify whether this example should usesh.SafeCmdwithout parameterisation, or document the generic's purpose if it is still present.docs/cuprum-design.md (1)
467-523: Validate Mermaid diagram syntax.Run
make nixieto confirm the Mermaid diagram (lines 469–523) validates without errors. Ensure all class names, relationships, and generic parameter syntax are correct.
- Added heading markup for implementation notes in cuprum-design.md - Fixed multiline code formatting and imports for clarity - Improved code snippet formatting for async commands - Corrected tuple ellipsis character - Adjusted line wrapping and punctuation for better readability - Minor text tweaks for users-guide.md formatting consistency Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
docs/cuprum-design.md(2 hunks)docs/users-guide.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/**/*.md: Use markdown files within thedocs/directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in thedocs/directory to reflect the latest state.
All documentation must adhere to the documentation style guide atdocs/documentation-style-guide.md.
Record any design decisions made in the relevant design document.
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/users-guide.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/users-guide.md: Ensure new functionality is clearly documented in thedocs/users-guide.mdfile.
Ensure revised functionality is clearly documented in thedocs/users-guide.mdfile.
docs/users-guide.md: Document the expected builder pattern indocs/users-guide.md
Provide a scaffold and guidance for project-specific builders, including a template module and checklist indocs/users-guide.md
Document policy switches and recommended defaults indocs/users-guide.mdand add release notes describing the migration path for existing users
Files:
docs/users-guide.md
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
**/*.md: For Markdown files (.md only), ensure linting passes by runningmake markdownlint.
For Markdown files, validate Mermaid diagrams by runningmake nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.
Validate Markdown files usingmake markdownlint.
Runmake fmtafter any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by runningmake nixie.
Files:
docs/users-guide.mddocs/cuprum-design.md
⚙️ CodeRabbit configuration file
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Headings must not be wrapped.
- Documents must start with a level 1 heading
- Headings must correctly increase or decrease by no more than one level at a time
- Use GitHub-flavoured Markdown style for footnotes and endnotes.
- Numbered footnotes must be numbered by order of appearance in the document.
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/**/*.{md,mdx,rst,txt}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
docs/**/*.{md,mdx,rst,txt}: Use British English based on Oxford English Dictionary (en-GB-oxendict) conventions: use -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse, catalyse), -our suffixes (colour, behaviour, neighbour), -re suffixes (calibre, centre, fibre), double 'l' (cancelled, counsellor, cruellest), maintain 'e' (likeable, liveable, rateable), -ogue suffixes (analogue, catalogue)
The word 'outwith' is acceptable in documentation
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation, for example 'Lille Industries are expanding'
Write headings in sentence case in documentation
Use Markdown headings (#,##,###, and so on) in order without skipping levels
Always provide a language identifier for fenced code blocks in documentation; use 'plaintext' for non-code text
Use-as the first level bullet and renumber lists when items change in documentation
Prefer inline links using[text](url)or angle brackets around the URL in documentation
Ensure blank lines before and after bulleted lists and fenced blocks in documentation
Ensure tables have a delimiter line below the header row in documentation
Expand any uncommon acronym on first use in documentation, for example 'Continuous Integration (CI)'
Wrap paragraphs at 80 columns in documentation
Wrap code at 120 columns in documentation
Do not wrap tables in documentation
Use footnotes referenced with[^label]in documentation
Include Mermaid diagrams in documentation where they add clarity
When embedding figures in documentation, useand provide brief alt text describing the content
Add a short description before each Mermaid diagram in documentation so screen readers can understand it
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/**/*.{md,mdx,rst,txt,rs}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Keep US spelling when used in API contexts, for example 'color'
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Follow markdownlint recommendations for Markdown formatting
Files:
docs/users-guide.mddocs/cuprum-design.md
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Sourcery review
🔇 Additional comments (1)
docs/cuprum-design.md (1)
512-522: This review comment is incorrect. TheSafeCmdclass definition still usesGeneric[Out]in the source code, so the Mermaid diagram representation usingSafeCmd~Out_co~(covariant generic) remains appropriate and accurate. No changes to these diagram relationships are needed.Likely an incorrect or invalid review comment.
…usage example Updated the class diagram in cuprum-design.md to replace outdated SafeCmd~Out_co~ and SafeCmd_str references with SafeCmd. Adjusted SafeCmdBuilder connections accordingly. Also corrected import and type annotation in users-guide.md to reflect the updated SafeCmd usage. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
docs/cuprum-design.md(2 hunks)docs/users-guide.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/**/*.md: Use markdown files within thedocs/directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in thedocs/directory to reflect the latest state.
All documentation must adhere to the documentation style guide atdocs/documentation-style-guide.md.
Record any design decisions made in the relevant design document.
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/users-guide.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/users-guide.md: Ensure new functionality is clearly documented in thedocs/users-guide.mdfile.
Ensure revised functionality is clearly documented in thedocs/users-guide.mdfile.
docs/users-guide.md: Document the expected builder pattern indocs/users-guide.md
Provide a scaffold and guidance for project-specific builders, including a template module and checklist indocs/users-guide.md
Document policy switches and recommended defaults indocs/users-guide.mdand add release notes describing the migration path for existing users
Files:
docs/users-guide.md
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
**/*.md: For Markdown files (.md only), ensure linting passes by runningmake markdownlint.
For Markdown files, validate Mermaid diagrams by runningmake nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.
Validate Markdown files usingmake markdownlint.
Runmake fmtafter any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by runningmake nixie.
Files:
docs/users-guide.mddocs/cuprum-design.md
⚙️ CodeRabbit configuration file
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Headings must not be wrapped.
- Documents must start with a level 1 heading
- Headings must correctly increase or decrease by no more than one level at a time
- Use GitHub-flavoured Markdown style for footnotes and endnotes.
- Numbered footnotes must be numbered by order of appearance in the document.
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/**/*.{md,mdx,rst,txt}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
docs/**/*.{md,mdx,rst,txt}: Use British English based on Oxford English Dictionary (en-GB-oxendict) conventions: use -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse, catalyse), -our suffixes (colour, behaviour, neighbour), -re suffixes (calibre, centre, fibre), double 'l' (cancelled, counsellor, cruellest), maintain 'e' (likeable, liveable, rateable), -ogue suffixes (analogue, catalogue)
The word 'outwith' is acceptable in documentation
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation, for example 'Lille Industries are expanding'
Write headings in sentence case in documentation
Use Markdown headings (#,##,###, and so on) in order without skipping levels
Always provide a language identifier for fenced code blocks in documentation; use 'plaintext' for non-code text
Use-as the first level bullet and renumber lists when items change in documentation
Prefer inline links using[text](url)or angle brackets around the URL in documentation
Ensure blank lines before and after bulleted lists and fenced blocks in documentation
Ensure tables have a delimiter line below the header row in documentation
Expand any uncommon acronym on first use in documentation, for example 'Continuous Integration (CI)'
Wrap paragraphs at 80 columns in documentation
Wrap code at 120 columns in documentation
Do not wrap tables in documentation
Use footnotes referenced with[^label]in documentation
Include Mermaid diagrams in documentation where they add clarity
When embedding figures in documentation, useand provide brief alt text describing the content
Add a short description before each Mermaid diagram in documentation so screen readers can understand it
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/**/*.{md,mdx,rst,txt,rs}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Keep US spelling when used in API contexts, for example 'color'
Files:
docs/users-guide.mddocs/cuprum-design.md
docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Follow markdownlint recommendations for Markdown formatting
Files:
docs/users-guide.mddocs/cuprum-design.md
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Sourcery review
🔇 Additional comments (1)
docs/users-guide.md (1)
42-97: ✓ Approved: Documentation is well-structured and addresses earlier feedback.The new "Typed command core" section integrates cleanly, with correct imports, proper return type annotations (
SafeCmdnotsh.SafeCmd[str]), compliant column wrapping, and idiomatic code examples. All prior review comments (spelling, punctuation, type annotations) have been addressed.
Corrected the return type annotation of __call__ method in SafeCmdBuilder from 'SafeCmd~str~' to 'SafeCmd'. Also simplified the classDiagram references by replacing templated types like 'SafeCmd_str' and 'SafeCmd~Out_co~' with 'SafeCmd'. This improves documentation clarity and consistency. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/cuprum-design.md (1)
251-252: Synchronise documentation with the plain SafeCmd dataclass implementation.Sections 5.2 (line 251) and 6.1.2 (line 330) still describe SafeCmd as a generic type (
SafeCmd[Out]), and the type sketch at line 342 showsclass SafeCmd(Generic[Out]). However, the implementation notes (lines 463–465) and the Mermaid diagram (line 486) correctly reflect that SafeCmd is now a plain dataclass without generics.Update sections 5.2, 6.1.2, and the type sketch at line 342 to remove all references to the generic parameter and present SafeCmd as a non-generic dataclass. Ensure the overall document presents a consistent story of SafeCmd's structure throughout.
Also applies to: 330-332, 342-342
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
docs/cuprum-design.md(2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/**/*.md: Use markdown files within thedocs/directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
When new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve, proactively update the relevant file(s) in thedocs/directory to reflect the latest state.
All documentation must adhere to the documentation style guide atdocs/documentation-style-guide.md.
Record any design decisions made in the relevant design document.
Files:
docs/cuprum-design.md
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
**/*.md: For Markdown files (.md only), ensure linting passes by runningmake markdownlint.
For Markdown files, validate Mermaid diagrams by runningmake nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Markdown tables and headings must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.
Validate Markdown files usingmake markdownlint.
Runmake fmtafter any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by runningmake nixie.
Files:
docs/cuprum-design.md
⚙️ CodeRabbit configuration file
**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")
- Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
- Headings must not be wrapped.
- Documents must start with a level 1 heading
- Headings must correctly increase or decrease by no more than one level at a time
- Use GitHub-flavoured Markdown style for footnotes and endnotes.
- Numbered footnotes must be numbered by order of appearance in the document.
Files:
docs/cuprum-design.md
docs/**/*.{md,mdx,rst,txt}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
docs/**/*.{md,mdx,rst,txt}: Use British English based on Oxford English Dictionary (en-GB-oxendict) conventions: use -ize suffixes (realize, organization), -lyse suffixes (analyse, paralyse, catalyse), -our suffixes (colour, behaviour, neighbour), -re suffixes (calibre, centre, fibre), double 'l' (cancelled, counsellor, cruellest), maintain 'e' (likeable, liveable, rateable), -ogue suffixes (analogue, catalogue)
The word 'outwith' is acceptable in documentation
Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension
Treat company names as collective nouns in documentation, for example 'Lille Industries are expanding'
Write headings in sentence case in documentation
Use Markdown headings (#,##,###, and so on) in order without skipping levels
Always provide a language identifier for fenced code blocks in documentation; use 'plaintext' for non-code text
Use-as the first level bullet and renumber lists when items change in documentation
Prefer inline links using[text](url)or angle brackets around the URL in documentation
Ensure blank lines before and after bulleted lists and fenced blocks in documentation
Ensure tables have a delimiter line below the header row in documentation
Expand any uncommon acronym on first use in documentation, for example 'Continuous Integration (CI)'
Wrap paragraphs at 80 columns in documentation
Wrap code at 120 columns in documentation
Do not wrap tables in documentation
Use footnotes referenced with[^label]in documentation
Include Mermaid diagrams in documentation where they add clarity
When embedding figures in documentation, useand provide brief alt text describing the content
Add a short description before each Mermaid diagram in documentation so screen readers can understand it
Files:
docs/cuprum-design.md
docs/**/*.{md,mdx,rst,txt,rs}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Keep US spelling when used in API contexts, for example 'color'
Files:
docs/cuprum-design.md
docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (docs/documentation-style-guide.md)
Follow markdownlint recommendations for Markdown formatting
Files:
docs/cuprum-design.md
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Sourcery review
🔇 Additional comments (1)
docs/cuprum-design.md (1)
461-464: Fix line wrapping to comply with 80-column guideline.Lines 461 and 464 exceed the 80-character limit:
- Line 461: "-
Noneis rejected as an argument value to catch accidental omissions early;" contains 81 characters.- Line 464: " noise rules and documentation links visible to downstream hooks without an" contains 82 characters.
Reflow these lines to fit within 80 columns:
- Lines 461–462: Shorten or split the `None` rejection clause so each line is ≤80 chars. - Lines 463–465: Reflow the SafeCmd clause so line 464 no longer exceeds the limit.
…ntation - Removed the generic `[Out]` type parameter from `SafeCmd` references. - Updated related type hints and docstrings to reflect this change. - Improved formatting and fixed annotation style for `ExecEvent` dataclass. - Clarified descriptions for SafeCmd and DynamicCmd in the documentation. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
Summary
sh.makethat validates programs against the catalogue and builds SafeCmd instances with structured argv and attached project metadata.--flag=valueentries (underscores in flag names are hyphenated).Nonevalues are rejected to catch mistakes early.SafeCmdandSafeCmdBuilderpublicly and wires up a small façade module (cuprum.sh).Changes
make(program, catalogue=...)factory_stringify_arg,_serialize_kwargs,_coerce_argvargv_with_programproperty for easy access to full argv including program nameUnknownProgramErrorSafeCmd,SafeCmdBuilder,UnknownProgramError, andshin cuprum/init.pyHow it works
sh.make(program, catalogue=...)validates the provided program exists in the catalogue and returns a builder.builder(*args, **kwargs), produces aSafeCmd:argvis the positional args stringified plus--flag=valueentries for kwargs (normalized keys replace_with-).argv_with_programprefixes the argv with the program name.projectholds the correspondingProjectSettingsfrom the catalogue for downstream visibility (noise rules, docs links).Examples
Testing plan
--flag=valueand underscores are hyphenatedNotes
📎 Task: https://www.terragonlabs.com/task/853937e5-d75d-4e73-b78c-60c795e47b93