strictcli 0.13.0__tar.gz → 0.14.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.
Files changed (137) hide show
  1. strictcli-0.14.0/.github/workflows/publish.yml +27 -0
  2. strictcli-0.14.0/.npmignore +34 -0
  3. strictcli-0.14.0/.rlsbl/bases/.github/workflows/publish.yml +27 -0
  4. strictcli-0.14.0/.rlsbl/bases/.npmignore +34 -0
  5. strictcli-0.14.0/.rlsbl/changes/.validated +1 -0
  6. strictcli-0.14.0/.rlsbl/changes/0.13.0.md +5 -0
  7. strictcli-0.14.0/.rlsbl/changes/0.14.0.jsonl +3 -0
  8. strictcli-0.14.0/.rlsbl/changes/0.14.0.md +5 -0
  9. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/hashes.json +3 -2
  10. strictcli-0.14.0/.rlsbl/version +1 -0
  11. {strictcli-0.13.0 → strictcli-0.14.0}/CHANGELOG.md +15 -0
  12. {strictcli-0.13.0 → strictcli-0.14.0}/PKG-INFO +1 -1
  13. {strictcli-0.13.0 → strictcli-0.14.0}/package-lock.json +2 -2
  14. {strictcli-0.13.0 → strictcli-0.14.0}/package.json +1 -1
  15. {strictcli-0.13.0 → strictcli-0.14.0}/pyproject.toml +1 -1
  16. {strictcli-0.13.0 → strictcli-0.14.0}/strictcli/__init__.py +35 -16
  17. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_check_discovery.py +51 -0
  18. {strictcli-0.13.0 → strictcli-0.14.0}/uv.lock +1 -1
  19. strictcli-0.13.0/.github/workflows/publish.yml +0 -32
  20. strictcli-0.13.0/.rlsbl/bases/.github/workflows/publish.yml +0 -32
  21. strictcli-0.13.0/.rlsbl/changes/.validated +0 -1
  22. strictcli-0.13.0/.rlsbl/releases/unreleased.toml +0 -0
  23. strictcli-0.13.0/.rlsbl/version +0 -1
  24. {strictcli-0.13.0 → strictcli-0.14.0}/.claude/settings.json +0 -0
  25. {strictcli-0.13.0 → strictcli-0.14.0}/.github/workflows/ci.yml +0 -0
  26. {strictcli-0.13.0 → strictcli-0.14.0}/.gitignore +0 -0
  27. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/.claude/settings.json +0 -0
  28. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/.github/workflows/ci.yml +0 -0
  29. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/.gitignore +0 -0
  30. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/.rlsbl/hooks/post-release.sh +0 -0
  31. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/.rlsbl/hooks/pre-checks.sh +0 -0
  32. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/.rlsbl/hooks/pre-release.sh +0 -0
  33. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/.rlsbl/lint/go.toml +0 -0
  34. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/.rlsbl/lint/npm.toml +0 -0
  35. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/.rlsbl/lint/python.toml +0 -0
  36. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/CHANGELOG.md +0 -0
  37. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/CLAUDE.md +0 -0
  38. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/bases/LICENSE +0 -0
  39. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.10.0.jsonl +0 -0
  40. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.10.0.md +0 -0
  41. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.11.0.jsonl +0 -0
  42. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.11.0.md +0 -0
  43. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.12.0.jsonl +0 -0
  44. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.12.0.md +0 -0
  45. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.13.0.jsonl +0 -0
  46. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.4.0.jsonl +0 -0
  47. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.4.0.md +0 -0
  48. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.4.1.jsonl +0 -0
  49. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.4.1.md +0 -0
  50. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.5.0.jsonl +0 -0
  51. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.5.0.md +0 -0
  52. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.6.0.jsonl +0 -0
  53. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.6.0.md +0 -0
  54. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.6.1.jsonl +0 -0
  55. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.6.1.md +0 -0
  56. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.7.0.jsonl +0 -0
  57. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.7.0.md +0 -0
  58. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.7.1.jsonl +0 -0
  59. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.7.1.md +0 -0
  60. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.0.jsonl +0 -0
  61. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.0.md +0 -0
  62. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.1.jsonl +0 -0
  63. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.1.md +0 -0
  64. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.2.jsonl +0 -0
  65. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.2.md +0 -0
  66. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.3.jsonl +0 -0
  67. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.3.md +0 -0
  68. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.4.jsonl +0 -0
  69. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.4.md +0 -0
  70. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.5.jsonl +0 -0
  71. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.5.md +0 -0
  72. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.6.jsonl +0 -0
  73. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.6.md +0 -0
  74. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.7.jsonl +0 -0
  75. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.8.7.md +0 -0
  76. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.9.0.jsonl +0 -0
  77. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.9.0.md +0 -0
  78. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.9.1.jsonl +0 -0
  79. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/0.9.1.md +0 -0
  80. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/changes/unreleased.jsonl +0 -0
  81. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/config.json +0 -0
  82. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/hooks/post-release.sh +0 -0
  83. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/hooks/pre-checks.sh +0 -0
  84. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/hooks/pre-release.sh +0 -0
  85. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/lint/go.toml +0 -0
  86. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/lint/npm.toml +0 -0
  87. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/lint/python.toml +0 -0
  88. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/releases/v0.10.0.toml +0 -0
  89. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/releases/v0.11.0.toml +0 -0
  90. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/releases/v0.12.0.toml +0 -0
  91. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/releases/v0.13.0.toml +0 -0
  92. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/releases/v0.8.5.toml +0 -0
  93. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/releases/v0.8.6.toml +0 -0
  94. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/releases/v0.8.7.toml +0 -0
  95. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/releases/v0.9.0.toml +0 -0
  96. {strictcli-0.13.0 → strictcli-0.14.0}/.rlsbl/releases/v0.9.1.toml +0 -0
  97. {strictcli-0.13.0 → strictcli-0.14.0}/.strictcli/schema.json +0 -0
  98. {strictcli-0.13.0 → strictcli-0.14.0}/CLAUDE.md +0 -0
  99. {strictcli-0.13.0 → strictcli-0.14.0}/LICENSE +0 -0
  100. {strictcli-0.13.0 → strictcli-0.14.0}/README.md +0 -0
  101. {strictcli-0.13.0 → strictcli-0.14.0}/index.js +0 -0
  102. {strictcli-0.13.0 → strictcli-0.14.0}/postinstall.js +0 -0
  103. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_arg_default.py +0 -0
  104. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_at_prefix.py +0 -0
  105. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_auto_version.py +0 -0
  106. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_check_command.py +0 -0
  107. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_check_runner.py +0 -0
  108. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_check_schema.py +0 -0
  109. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_check_types.py +0 -0
  110. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_choices.py +0 -0
  111. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_command_help_suggestion.py +0 -0
  112. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_config.py +0 -0
  113. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_config_file_path.py +0 -0
  114. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_deep_nesting.py +0 -0
  115. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_dependencies.py +0 -0
  116. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_deprecated.py +0 -0
  117. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_dump_schema.py +0 -0
  118. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_e2e.py +0 -0
  119. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_env.py +0 -0
  120. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_exit_codes.py +0 -0
  121. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_float_type.py +0 -0
  122. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_global_flags.py +0 -0
  123. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_help.py +0 -0
  124. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_int_type.py +0 -0
  125. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_mutex.py +0 -0
  126. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_nesting.py +0 -0
  127. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_parser.py +0 -0
  128. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_passthrough.py +0 -0
  129. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_registration.py +0 -0
  130. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_repeatable.py +0 -0
  131. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_tagdsl.py +0 -0
  132. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_tags.py +0 -0
  133. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_toml_loading.py +0 -0
  134. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_validate.py +0 -0
  135. {strictcli-0.13.0 → strictcli-0.14.0}/tests/test_variadic.py +0 -0
  136. {strictcli-0.13.0 → strictcli-0.14.0}/todo/.defer/deferred.md +0 -0
  137. {strictcli-0.13.0 → strictcli-0.14.0}/todo/.done/original-idea.md +0 -0
@@ -0,0 +1,27 @@
1
+ name: Publish
2
+ on:
3
+ release:
4
+ types: [published]
5
+ workflow_dispatch:
6
+ permissions:
7
+ contents: read
8
+ id-token: write
9
+ jobs:
10
+ pypi:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v6
14
+ - uses: astral-sh/setup-uv@v7
15
+ - run: uv build
16
+ - uses: pypa/gh-action-pypi-publish@release/v1
17
+ npm:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v6
21
+ - uses: actions/setup-node@v6
22
+ with:
23
+ node-version: 24
24
+ registry-url: https://registry.npmjs.org
25
+ - run: npm publish --provenance --access public
26
+ env:
27
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,34 @@
1
+ # Development and CI
2
+ tests/
3
+ test/
4
+ __tests__/
5
+ .github/
6
+ scripts/
7
+ docs/
8
+ todo/
9
+ e2e/
10
+
11
+ # rlsbl metadata
12
+ .rlsbl/
13
+ .rlsbl-monorepo/
14
+
15
+ # Python artifacts (for multi-target projects)
16
+ __pycache__/
17
+ *.pyc
18
+ *.py
19
+ *.toml
20
+ .venv/
21
+
22
+ # Build/cache
23
+ coverage/
24
+ .nyc_output/
25
+
26
+ # Editor/OS
27
+ .DS_Store
28
+ *.log
29
+ .env
30
+ .env.local
31
+
32
+ # Selfdoc
33
+ .selfdoc/
34
+ selfdoc.json
@@ -0,0 +1,27 @@
1
+ name: Publish
2
+ on:
3
+ release:
4
+ types: [published]
5
+ workflow_dispatch:
6
+ permissions:
7
+ contents: read
8
+ id-token: write
9
+ jobs:
10
+ pypi:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v6
14
+ - uses: astral-sh/setup-uv@v7
15
+ - run: uv build
16
+ - uses: pypa/gh-action-pypi-publish@release/v1
17
+ npm:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v6
21
+ - uses: actions/setup-node@v6
22
+ with:
23
+ node-version: 24
24
+ registry-url: https://registry.npmjs.org
25
+ - run: npm publish --provenance --access public
26
+ env:
27
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,34 @@
1
+ # Development and CI
2
+ tests/
3
+ test/
4
+ __tests__/
5
+ .github/
6
+ scripts/
7
+ docs/
8
+ todo/
9
+ e2e/
10
+
11
+ # rlsbl metadata
12
+ .rlsbl/
13
+ .rlsbl-monorepo/
14
+
15
+ # Python artifacts (for multi-target projects)
16
+ __pycache__/
17
+ *.pyc
18
+ *.py
19
+ *.toml
20
+ .venv/
21
+
22
+ # Build/cache
23
+ coverage/
24
+ .nyc_output/
25
+
26
+ # Editor/OS
27
+ .DS_Store
28
+ *.log
29
+ .env
30
+ .env.local
31
+
32
+ # Selfdoc
33
+ .selfdoc/
34
+ selfdoc.json
@@ -0,0 +1 @@
1
+ caba81b23948f3b79c908ccd06ed76596881c075
@@ -0,0 +1,5 @@
1
+ ## 0.13.0
2
+
3
+ ### Features
4
+
5
+ - **New feature.** Schema dump (--dump-schema) now includes a project_id field read from pyproject.toml, providing provenance for schema validation.
@@ -0,0 +1,3 @@
1
+ {"commits":["f2f2de83edc0b7fe24f46744201e8be1407f28a3"],"user_facing":false}
2
+ {"commits":["a2e1d64fb5f695169fafa63e5d1b69fe5c4e043d"],"user_facing":true,"description":"**New feature.** `checks_embed` parameter accepts raw TOML bytes, enabling inline checks configuration without a file on disk.","type":"feature"}
3
+ {"commits":["09799755dc2ef93a088f739a46001102bcb2aa5e"],"user_facing":false}
@@ -0,0 +1,5 @@
1
+ ## 0.14.0
2
+
3
+ ### Features
4
+
5
+ - **New feature.** `checks_embed` parameter accepts raw TOML bytes, enabling inline checks configuration without a file on disk.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  ".github/workflows/ci.yml": "b4e075171b131d25f9cce55a3e3a30732e95a2a794af00f354ee3200626d6a04",
3
- ".github/workflows/publish.yml": "8befe0164321eb68e9465c634aa15d6ccb30d46fa669f7d30bf3ed064ad258ba",
3
+ ".github/workflows/publish.yml": "e77dcd0b5d1c1abae5424e5f3b73862f44f06b5d46209cbe71bc04d6baa6b5be",
4
4
  "CHANGELOG.md": "7a6ec46141007c18090a0ff325e2dd68cd51588c4e0b5af7b580365e5eaaca85",
5
5
  ".gitignore": "c89d76c6c43e7f0897b3472a15b7c0103e0be5b3a04c2b44e585fa48bdcda2bb",
6
6
  "LICENSE": "e958892abc1dd5d991fca6d528e695d335f25773d373d2e0be5f4a9507d8f8d5",
@@ -11,5 +11,6 @@
11
11
  ".rlsbl/hooks/pre-checks.sh": "60c57d4563263124530e6f33aca77550ea2161ad3b33b3ba6ad1c03fea9eb6e2",
12
12
  ".rlsbl/lint/python.toml": "9cfbcef2e010d5fad243437bf2fd8df54a1fae70ee0762f9d11da70fe207501c",
13
13
  ".rlsbl/lint/go.toml": "807d5cf760baad6d571a5bfd43cb163efe356f7462ba9f1918d72de45f62339f",
14
- ".rlsbl/lint/npm.toml": "baa36014e65923d8cc5c8b83c77fa651da79351627570476402da66840027645"
14
+ ".rlsbl/lint/npm.toml": "baa36014e65923d8cc5c8b83c77fa651da79351627570476402da66840027645",
15
+ ".npmignore": "7c0eea9785c0318aeb39bf8b670ce8384f4a5b812fde69ce23d7d018057325a3"
15
16
  }
@@ -0,0 +1 @@
1
+ 0.60.1
@@ -2,6 +2,21 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## 0.14.0
6
+
7
+ checks_embed for inline TOML data
8
+
9
+ <details>
10
+ <summary>Context</summary>
11
+
12
+ Adds checks_embed parameter as an alternative to checks_path, allowing TOML bytes to be passed directly without requiring a file on disk.
13
+
14
+ </details>
15
+
16
+ ### Features
17
+
18
+ - **New feature.** `checks_embed` parameter accepts raw TOML bytes, enabling inline checks configuration without a file on disk.
19
+
5
20
  ## 0.13.0
6
21
 
7
22
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: strictcli
3
- Version: 0.13.0
3
+ Version: 0.14.0
4
4
  Summary: A strict, zero-dependency 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
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "strictcli",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "strictcli",
9
- "version": "0.13.0",
9
+ "version": "0.14.0",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT"
12
12
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strictcli",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "A strict, zero-dependency CLI framework for Python (npm wrapper)",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "strictcli"
7
- version = "0.13.0"
7
+ version = "0.14.0"
8
8
  description = "A strict, zero-dependency CLI framework for Python"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- __version__ = "0.13.0"
5
+ __version__ = "0.14.0"
6
6
 
7
7
  __all__ = [
8
8
  "App", "Flag", "Arg", "Tag", "MutexGroup", "CoRequired", "Requires",
@@ -130,37 +130,32 @@ _CHECK_REQUIRED_FIELDS = {"tags", "severity", "fast", "pure", "needs_network", "
130
130
  _CHECK_VALID_SEVERITIES = {"error", "warn"}
131
131
 
132
132
 
133
- def _load_checks_toml(path: str | Path) -> tuple[str, dict[str, _CheckDef]]:
134
- """Parse and validate a checks.toml file, returning (app_name, check_defs).
133
+ def _parse_checks_toml(data: bytes) -> tuple[str, dict[str, _CheckDef]]:
134
+ """Parse and validate checks TOML data, returning (app_name, check_defs).
135
135
 
136
- Raises ValueError on any schema violation, file error, or invalid TOML.
136
+ Raises ValueError on any schema violation or invalid TOML.
137
137
  """
138
- path = Path(path)
139
- try:
140
- raw = path.read_bytes()
141
- except OSError as exc:
142
- raise ValueError(f"checks.toml: {exc}") from exc
143
138
  try:
144
- data = tomllib.loads(raw.decode())
139
+ parsed = tomllib.loads(data.decode())
145
140
  except (tomllib.TOMLDecodeError, UnicodeDecodeError) as exc:
146
141
  raise ValueError(f"checks.toml: {exc}") from exc
147
142
 
148
143
  # Only "app" and [checks] are allowed at the top level
149
- for key in data:
144
+ for key in parsed:
150
145
  if key not in ("app", "checks"):
151
146
  raise ValueError(f'checks.toml: unknown top-level key "{key}"')
152
147
 
153
148
  # Validate required "app" field
154
- if "app" not in data:
149
+ if "app" not in parsed:
155
150
  raise ValueError('checks.toml: missing required top-level key "app"')
156
- if not isinstance(data["app"], str) or not data["app"]:
151
+ if not isinstance(parsed["app"], str) or not parsed["app"]:
157
152
  raise ValueError('checks.toml: "app" must be a non-empty string')
158
- app_name = data["app"]
153
+ app_name = parsed["app"]
159
154
 
160
- if "checks" not in data:
155
+ if "checks" not in parsed:
161
156
  return (app_name, {})
162
157
 
163
- checks_section = data["checks"]
158
+ checks_section = parsed["checks"]
164
159
  if not isinstance(checks_section, dict):
165
160
  raise ValueError("checks.toml: [checks] must be a table")
166
161
 
@@ -253,6 +248,19 @@ def _load_checks_toml(path: str | Path) -> tuple[str, dict[str, _CheckDef]]:
253
248
  return (app_name, result)
254
249
 
255
250
 
251
+ def _load_checks_toml(path: str | Path) -> tuple[str, dict[str, _CheckDef]]:
252
+ """Read and parse a checks.toml file, returning (app_name, check_defs).
253
+
254
+ Raises ValueError on any file error, schema violation, or invalid TOML.
255
+ """
256
+ path = Path(path)
257
+ try:
258
+ raw = path.read_bytes()
259
+ except OSError as exc:
260
+ raise ValueError(f"checks.toml: {exc}") from exc
261
+ return _parse_checks_toml(raw)
262
+
263
+
256
264
  class _HelpRequested(Exception):
257
265
  """Raised when --help or -h is encountered."""
258
266
 
@@ -675,6 +683,7 @@ class App:
675
683
  config_path: str | None = None
676
684
  config_format: str = "json"
677
685
  checks_path: str | Path | None = None
686
+ checks_embed: bytes | None = None
678
687
  flags: list[Flag] = field(default_factory=list)
679
688
  _commands: dict[str, Command] = field(default_factory=dict)
680
689
  _groups: dict[str, Group] = field(default_factory=dict)
@@ -712,6 +721,8 @@ class App:
712
721
  self._register_config_group()
713
722
  # Discover checks TOML
714
723
  self._check_context_factory: Callable | None = None
724
+ if self.checks_path is not None and self.checks_embed is not None:
725
+ raise ValueError("cannot use both checks_path and checks_embed")
715
726
  if self.checks_path is not None:
716
727
  checks_toml_path = Path(self.checks_path).resolve()
717
728
  if not checks_toml_path.is_file():
@@ -723,6 +734,14 @@ class App:
723
734
  )
724
735
  self._checks_enabled = True
725
736
  self._register_check_command()
737
+ elif self.checks_embed is not None:
738
+ app_name, self._check_defs = _parse_checks_toml(self.checks_embed)
739
+ if app_name != self.name:
740
+ raise ValueError(
741
+ f'checks.toml: app "{app_name}" does not match app name "{self.name}"'
742
+ )
743
+ self._checks_enabled = True
744
+ self._register_check_command()
726
745
  else:
727
746
  self._check_defs: dict[str, _CheckDef] = {}
728
747
  self._checks_enabled = False
@@ -293,3 +293,54 @@ depends_on = []
293
293
  name="testapp", version="1.0.0", help="test app",
294
294
  checks_path=str(toml_file),
295
295
  )
296
+
297
+
298
+ class TestChecksEmbed:
299
+ def test_checks_embed_enables_checks(self, tmp_path, monkeypatch):
300
+ """checks_embed with valid TOML bytes enables checks."""
301
+ monkeypatch.chdir(tmp_path)
302
+
303
+ app = strictcli.App(
304
+ name="testapp", version="1.0.0", help="test app",
305
+ checks_embed=VALID_TOML.encode(),
306
+ )
307
+ assert app._checks_enabled is True
308
+ assert "lint-code" in app._check_defs
309
+ assert "check-deps" in app._check_defs
310
+
311
+ def test_checks_embed_and_checks_path_raises(self, tmp_path, monkeypatch):
312
+ """Using both checks_path and checks_embed raises ValueError."""
313
+ monkeypatch.chdir(tmp_path)
314
+ toml_file = tmp_path / "checks.toml"
315
+ toml_file.write_text(VALID_TOML)
316
+
317
+ with pytest.raises(ValueError, match="cannot use both checks_path and checks_embed"):
318
+ strictcli.App(
319
+ name="testapp", version="1.0.0", help="test app",
320
+ checks_path=str(toml_file),
321
+ checks_embed=VALID_TOML.encode(),
322
+ )
323
+
324
+ def test_checks_embed_invalid_toml(self, tmp_path, monkeypatch):
325
+ """checks_embed with garbage bytes raises ValueError."""
326
+ monkeypatch.chdir(tmp_path)
327
+
328
+ with pytest.raises(ValueError, match="checks.toml:"):
329
+ strictcli.App(
330
+ name="testapp", version="1.0.0", help="test app",
331
+ checks_embed=b"\x80\x81 not valid toml {{{{",
332
+ )
333
+
334
+ def test_checks_embed_wrong_app_name(self, tmp_path, monkeypatch):
335
+ """checks_embed with mismatched app name raises ValueError."""
336
+ monkeypatch.chdir(tmp_path)
337
+ wrong_toml = 'app = "wrong"\n'
338
+
339
+ with pytest.raises(
340
+ ValueError,
341
+ match=r'checks.toml: app "wrong" does not match app name "testapp"',
342
+ ):
343
+ strictcli.App(
344
+ name="testapp", version="1.0.0", help="test app",
345
+ checks_embed=wrong_toml.encode(),
346
+ )
@@ -232,7 +232,7 @@ wheels = [
232
232
 
233
233
  [[package]]
234
234
  name = "strictcli"
235
- version = "0.13.0"
235
+ version = "0.14.0"
236
236
  source = { editable = "." }
237
237
 
238
238
  [package.dev-dependencies]
@@ -1,32 +0,0 @@
1
- name: Publish
2
-
3
- on:
4
- release:
5
- types: [published]
6
- workflow_dispatch:
7
-
8
-
9
- permissions:
10
- contents: read
11
- id-token: write
12
-
13
- jobs:
14
- pypi:
15
- runs-on: ubuntu-latest
16
- steps:
17
- - uses: actions/checkout@v6
18
- - uses: astral-sh/setup-uv@v7
19
- - run: uv build
20
- - uses: pypa/gh-action-pypi-publish@release/v1
21
-
22
- npm:
23
- runs-on: ubuntu-latest
24
- steps:
25
- - uses: actions/checkout@v6
26
- - uses: actions/setup-node@v6
27
- with:
28
- node-version: 24
29
- registry-url: https://registry.npmjs.org
30
- - run: npm publish --provenance --access public
31
- env:
32
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1,32 +0,0 @@
1
- name: Publish
2
-
3
- on:
4
- release:
5
- types: [published]
6
- workflow_dispatch:
7
-
8
-
9
- permissions:
10
- contents: read
11
- id-token: write
12
-
13
- jobs:
14
- pypi:
15
- runs-on: ubuntu-latest
16
- steps:
17
- - uses: actions/checkout@v6
18
- - uses: astral-sh/setup-uv@v7
19
- - run: uv build
20
- - uses: pypa/gh-action-pypi-publish@release/v1
21
-
22
- npm:
23
- runs-on: ubuntu-latest
24
- steps:
25
- - uses: actions/checkout@v6
26
- - uses: actions/setup-node@v6
27
- with:
28
- node-version: 24
29
- registry-url: https://registry.npmjs.org
30
- - run: npm publish --provenance --access public
31
- env:
32
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1 +0,0 @@
1
- 052122abb24b7318d56b1c0d657fbaf740d6f5a5
File without changes
@@ -1 +0,0 @@
1
- 0.45.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes