strictcli 0.38.0__tar.gz → 0.40.0__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.
- strictcli-0.40.0/.gitignore +25 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/CLAUDE.md +1 -1
- {strictcli-0.38.0 → strictcli-0.40.0}/PKG-INFO +15 -3
- {strictcli-0.38.0 → strictcli-0.40.0}/README.md +13 -1
- {strictcli-0.38.0 → strictcli-0.40.0}/pyproject.toml +1 -1
- {strictcli-0.38.0 → strictcli-0.40.0}/strictcli/__init__.py +2831 -481
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/conftest.py +16 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/flagship_app.py +3 -2
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_call.py +140 -80
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_check_command.py +72 -23
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_check_provider.py +2 -2
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_check_public_api.py +23 -3
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_check_runner.py +71 -0
- strictcli-0.40.0/tests/test_claimed_rendering.py +121 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_classification.py +2 -2
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_command_tags.py +21 -21
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_config.py +20 -15
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_config_fields.py +12 -3
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_confirm.py +190 -4
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_context.py +38 -16
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_dependencies.py +11 -11
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_dry_run_unsupported.py +7 -4
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_dump_schema.py +80 -5
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_effects.py +40 -22
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_effects_bypass_check.py +4 -3
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_infra_env.py +2 -1
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_invoke.py +7 -7
- strictcli-0.40.0/tests/test_machine_mode.py +465 -0
- strictcli-0.40.0/tests/test_mcp.py +1692 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_mutex.py +191 -12
- strictcli-0.40.0/tests/test_owns_stdout.py +132 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_passthrough.py +1 -1
- strictcli-0.40.0/tests/test_payload_schema.py +576 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_provenance.py +31 -30
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_provenance_phase2.py +5 -3
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_reserved_quartet.py +22 -14
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_tool_export.py +102 -8
- strictcli-0.40.0/tests/test_trace_store.py +892 -0
- strictcli-0.40.0/tests/test_ulid_vectors.py +72 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/uv.lock +1 -1
- strictcli-0.38.0/.gitignore +0 -20
- strictcli-0.38.0/.strictcli/schema.json +0 -19
- strictcli-0.38.0/tests/test_mcp.py +0 -679
- {strictcli-0.38.0 → strictcli-0.40.0}/.claude/settings.json +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/.github/workflows/ci.yml +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/.github/workflows/publish.yml +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/.rlsbl/config.json +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/.rlsbl/lint/python.toml +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/.rlsbl/managed-files.json +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/LICENSE +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/scripts/add_effect_classification.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/scripts/add_forwarding_declaration.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/strictcli/py.typed +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_arg_default.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_arg_default_validation.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_at_prefix.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_auto_version.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_check_discovery.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_check_schema.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_check_types.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_choices.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_choices_none.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_command_help_suggestion.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_compound_types.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_config_file_path.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_config_set_bugs.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_connection_env.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_coverage.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_deep_nesting.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_deprecated.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_e2e.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_env.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_exit_codes.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_flag_sets.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_flagship_preview.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_float_format.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_float_type.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_float_vectors.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_global_flag_conflict_position.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_global_flags.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_guard_v2.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_help.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_hermetic.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_int_type.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_keyword_flags.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_nesting.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_parser.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_registration.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_repeatable.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_reserved_global_flags.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_tagdsl.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_toml_loading.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_typed_args.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_unique.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_utilities.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_validate.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_variadic.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/tests/test_visibility.py +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/todo/.defer/deferred.md +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/todo/.done/keyword-collision-in-flag-param-name.md +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/todo/.done/original-idea.md +0 -0
- {strictcli-0.38.0 → strictcli-0.40.0}/todo/.done/public-check-runner-api.md +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
node_modules/
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.pyc
|
|
4
|
+
*.log
|
|
5
|
+
.DS_Store
|
|
6
|
+
coverage/
|
|
7
|
+
dist/
|
|
8
|
+
*.egg-info/
|
|
9
|
+
.rlsbl-notes-*.tmp
|
|
10
|
+
.rlsbl/lock
|
|
11
|
+
.credentials.json
|
|
12
|
+
.*-cache.json
|
|
13
|
+
.env
|
|
14
|
+
.env.local
|
|
15
|
+
*.local-only
|
|
16
|
+
|
|
17
|
+
.rlsbl-monorepo/lock
|
|
18
|
+
|
|
19
|
+
build/
|
|
20
|
+
target/
|
|
21
|
+
|
|
22
|
+
# Test apps run with this directory as cwd write schema dumps and coverage
|
|
23
|
+
# shards here. Nothing under python/ is a maintained artifact (unlike
|
|
24
|
+
# conformance/.strictcli/, which is committed on purpose).
|
|
25
|
+
.strictcli/
|
|
@@ -18,7 +18,7 @@ Releases go through [rlsbl](https://github.com/smm-h/rlsbl) monorepo releases.
|
|
|
18
18
|
(they land in `.rlsbl-monorepo/releasables/py-strictcli/changes/unreleased.jsonl`).
|
|
19
19
|
- To release: from the repo root, run `rlsbl monorepo release init`, edit the
|
|
20
20
|
scaffolded release file (bump type, description, and context live in the file),
|
|
21
|
-
then run `rlsbl monorepo release run --no-allow-dirty --watch --
|
|
21
|
+
then run `rlsbl monorepo release run --no-allow-dirty --watch --approve-consequential`.
|
|
22
22
|
- Never publish or push manually — CI publishes to PyPI via Trusted Publishing.
|
|
23
23
|
|
|
24
24
|
## Conventions
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: strictcli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.40.0
|
|
4
4
|
Summary: A strict CLI framework for Python
|
|
5
5
|
Project-URL: Homepage, https://github.com/smm-h/strictcli
|
|
6
6
|
Project-URL: Repository, https://github.com/smm-h/strictcli
|
|
@@ -391,7 +391,19 @@ Auto-registers a `check` command with tag DSL filtering
|
|
|
391
391
|
|
|
392
392
|
```python
|
|
393
393
|
tools = app.as_tools()
|
|
394
|
-
# Each Tool has: name, description, parameters (JSON Schema),
|
|
394
|
+
# Each Tool has: name, description, parameters (JSON Schema), effect,
|
|
395
|
+
# consequential, execute
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
`effect` and `consequential` publish the effects-regime classification beside
|
|
399
|
+
the argument schema, so a caller can see before it calls that a tool changes
|
|
400
|
+
things and that invoking it requires stating consent:
|
|
401
|
+
|
|
402
|
+
```python
|
|
403
|
+
release = next(t for t in tools if t.name == "release")
|
|
404
|
+
release.consequential # True
|
|
405
|
+
await release.execute() # InvokeError: ... the call must carry confirmation
|
|
406
|
+
await release.execute(approve_consequential=True) # proceeds
|
|
395
407
|
```
|
|
396
408
|
|
|
397
409
|
### MCP server
|
|
@@ -372,7 +372,19 @@ Auto-registers a `check` command with tag DSL filtering
|
|
|
372
372
|
|
|
373
373
|
```python
|
|
374
374
|
tools = app.as_tools()
|
|
375
|
-
# Each Tool has: name, description, parameters (JSON Schema),
|
|
375
|
+
# Each Tool has: name, description, parameters (JSON Schema), effect,
|
|
376
|
+
# consequential, execute
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
`effect` and `consequential` publish the effects-regime classification beside
|
|
380
|
+
the argument schema, so a caller can see before it calls that a tool changes
|
|
381
|
+
things and that invoking it requires stating consent:
|
|
382
|
+
|
|
383
|
+
```python
|
|
384
|
+
release = next(t for t in tools if t.name == "release")
|
|
385
|
+
release.consequential # True
|
|
386
|
+
await release.execute() # InvokeError: ... the call must carry confirmation
|
|
387
|
+
await release.execute(approve_consequential=True) # proceeds
|
|
376
388
|
```
|
|
377
389
|
|
|
378
390
|
### MCP server
|