strictcli 0.24.0__tar.gz → 0.24.2__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.24.2/.github/workflows/ci-pypi.yml +29 -0
- strictcli-0.24.2/.github/workflows/publish.yml +152 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/.gitignore +2 -0
- strictcli-0.24.2/.rlsbl/config.json +18 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/.rlsbl/hashes.json +4 -3
- strictcli-0.24.2/.rlsbl/managed-files.json +11 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/PKG-INFO +1 -1
- {strictcli-0.24.0 → strictcli-0.24.2}/package-lock.json +2 -2
- {strictcli-0.24.0 → strictcli-0.24.2}/package.json +1 -1
- {strictcli-0.24.0 → strictcli-0.24.2}/pyproject.toml +1 -1
- {strictcli-0.24.0 → strictcli-0.24.2}/strictcli/__init__.py +2 -2
- {strictcli-0.24.0 → strictcli-0.24.2}/uv.lock +1 -1
- strictcli-0.24.0/.github/workflows/publish.yml +0 -27
- strictcli-0.24.0/.rlsbl/config.json +0 -12
- strictcli-0.24.0/.rlsbl/version +0 -1
- strictcli-0.24.0/CHANGELOG.md +0 -52
- {strictcli-0.24.0 → strictcli-0.24.2}/.claude/settings.json +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/.github/workflows/ci.yml +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/.npmignore +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/.strictcli/schema.json +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/CLAUDE.md +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/LICENSE +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/README.md +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/index.js +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/postinstall.js +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_arg_default.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_arg_default_validation.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_at_prefix.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_auto_version.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_call.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_check_command.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_check_discovery.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_check_public_api.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_check_runner.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_check_schema.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_check_types.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_choices.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_choices_none.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_command_help_suggestion.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_command_tags.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_compound_types.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_config.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_config_fields.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_config_file_path.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_config_set_bugs.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_context.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_deep_nesting.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_dependencies.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_deprecated.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_dump_schema.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_e2e.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_env.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_exit_codes.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_flag_sets.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_float_type.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_global_flags.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_help.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_int_type.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_invoke.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_keyword_flags.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_mcp.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_mutex.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_nesting.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_parser.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_passthrough.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_registration.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_repeatable.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_tagdsl.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_toml_loading.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_tool_export.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_typed_args.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_unique.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_utilities.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_validate.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_variadic.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/tests/test_visibility.py +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/todo/.defer/deferred.md +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/todo/.done/keyword-collision-in-flag-param-name.md +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/todo/.done/original-idea.md +0 -0
- {strictcli-0.24.0 → strictcli-0.24.2}/todo/.done/public-check-runner-api.md +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
# Per-SHA group: re-runs of the same commit dedupe, but a new commit never
|
|
11
|
+
# cancels an earlier commit's in-flight run (release CI conclusions stay intact).
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow_ref }}-${{ github.sha }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
strategy:
|
|
20
|
+
matrix:
|
|
21
|
+
# requires-python: >= 3.11
|
|
22
|
+
python-version: ["3.12", "3.13", "3.14"]
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v6
|
|
25
|
+
- uses: astral-sh/setup-uv@v7
|
|
26
|
+
- run: uv python install ${{ matrix.python-version }}
|
|
27
|
+
- run: uv sync --locked
|
|
28
|
+
- run: uv run python -c "import strictcli"
|
|
29
|
+
- run: uv run pytest
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
concurrency:
|
|
7
|
+
group: ${{ github.workflow_ref }}-${{ github.ref }}
|
|
8
|
+
cancel-in-progress: false
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
id-token: write
|
|
12
|
+
jobs:
|
|
13
|
+
gate:
|
|
14
|
+
name: Gate on CI
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
permissions:
|
|
17
|
+
checks: read
|
|
18
|
+
env:
|
|
19
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
20
|
+
GATE_TIMEOUT_MINUTES: '20'
|
|
21
|
+
GATE_GRACE_MINUTES: '5'
|
|
22
|
+
GATE_POLL_SECONDS: '15'
|
|
23
|
+
CI_CHECK_REGEX: ^(test)( \(.*\))?$
|
|
24
|
+
steps:
|
|
25
|
+
- name: Wait for CI to succeed on the release commit
|
|
26
|
+
run: |
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
|
|
29
|
+
# Ref-based commit resolution: GITHUB_SHA is the tag's commit for both
|
|
30
|
+
# release-triggered runs and workflow_dispatch retries at the tag ref.
|
|
31
|
+
# Never read the release event payload -- dispatch retries have none.
|
|
32
|
+
sha="$GITHUB_SHA"
|
|
33
|
+
echo "Publish gate: waiting for CI on $GITHUB_REF_NAME (commit $sha)"
|
|
34
|
+
echo "Check-run name filter: $CI_CHECK_REGEX"
|
|
35
|
+
# Timeout, grace window, and poll interval come from the job env above;
|
|
36
|
+
# edit them there if this repository's CI needs different limits.
|
|
37
|
+
|
|
38
|
+
now() { date +%s; }
|
|
39
|
+
start="$(now)"
|
|
40
|
+
deadline=$(( start + GATE_TIMEOUT_MINUTES * 60 ))
|
|
41
|
+
grace_deadline=$(( start + GATE_GRACE_MINUTES * 60 ))
|
|
42
|
+
|
|
43
|
+
while :; do
|
|
44
|
+
if ! resp="$(gh api --paginate "repos/$GITHUB_REPOSITORY/commits/$sha/check-runs?per_page=100")"; then
|
|
45
|
+
echo "Checks API request failed; retrying in ${GATE_POLL_SECONDS}s..."
|
|
46
|
+
sleep "$GATE_POLL_SECONDS"
|
|
47
|
+
continue
|
|
48
|
+
fi
|
|
49
|
+
# Match this project's CI check runs by name; exclude check runs that
|
|
50
|
+
# belong to THIS workflow run (the gate itself and the queued publish
|
|
51
|
+
# jobs would otherwise deadlock the poll loop).
|
|
52
|
+
runs="$(jq -s --arg re "$CI_CHECK_REGEX" --arg run_id "$GITHUB_RUN_ID" '
|
|
53
|
+
[ .[].check_runs[]
|
|
54
|
+
| select(.name | test($re))
|
|
55
|
+
| select((.details_url // "") | contains("/actions/runs/" + $run_id + "/") | not)
|
|
56
|
+
| {name, status, conclusion} ]' <<< "$resp")"
|
|
57
|
+
total="$(jq 'length' <<< "$runs")"
|
|
58
|
+
|
|
59
|
+
if [ "$total" -eq 0 ]; then
|
|
60
|
+
if [ "$(now)" -ge "$grace_deadline" ]; then
|
|
61
|
+
echo "::error::Publish gate: no CI check runs matching $CI_CHECK_REGEX appeared on $sha within $GATE_GRACE_MINUTES minutes."
|
|
62
|
+
echo "A scaffolded repository always has a CI workflow, so the release commit must produce CI check runs."
|
|
63
|
+
echo "If CI jobs were renamed, update CI_CHECK_REGEX in this workflow's gate job to match the new names."
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
echo "No matching CI check runs yet; retrying in ${GATE_POLL_SECONDS}s..."
|
|
67
|
+
sleep "$GATE_POLL_SECONDS"
|
|
68
|
+
continue
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
pending="$(jq '[ .[] | select(.status != "completed") ] | length' <<< "$runs")"
|
|
72
|
+
if [ "$pending" -gt 0 ]; then
|
|
73
|
+
if [ "$(now)" -ge "$deadline" ]; then
|
|
74
|
+
echo "::error::Publish gate: timed out after $GATE_TIMEOUT_MINUTES minutes waiting for CI to complete on $sha."
|
|
75
|
+
jq -r '.[] | " \(.name): status=\(.status) conclusion=\(.conclusion // "none")"' <<< "$runs"
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
78
|
+
echo "$pending of $total matching CI check runs still running; retrying in ${GATE_POLL_SECONDS}s..."
|
|
79
|
+
sleep "$GATE_POLL_SECONDS"
|
|
80
|
+
continue
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
not_success="$(jq '[ .[] | select(.conclusion != "success") ]' <<< "$runs")"
|
|
84
|
+
if [ "$(jq 'length' <<< "$not_success")" -gt 0 ]; then
|
|
85
|
+
echo "::error::Publish gate: CI did not pass on $sha -- refusing to publish."
|
|
86
|
+
jq -r '.[] | " \(.name): \(.conclusion)"' <<< "$not_success"
|
|
87
|
+
while IFS= read -r conclusion; do
|
|
88
|
+
case "$conclusion" in
|
|
89
|
+
failure|timed_out)
|
|
90
|
+
echo "CI concluded '$conclusion' on the release commit. Fix the failure, re-run the CI workflow to green on this exact commit (gh run rerun <run-id>), then re-dispatch this publish workflow at the tag ref: gh workflow run <publish workflow> --ref $GITHUB_REF_NAME"
|
|
91
|
+
;;
|
|
92
|
+
cancelled)
|
|
93
|
+
echo "A CI check run was CANCELLED. A cancelled run proves nothing about the commit, so the gate treats it as a hard failure instead of waiting for a conclusion that will never come. Re-run the cancelled CI workflow (gh run rerun <run-id>), then re-dispatch this publish workflow at the tag ref."
|
|
94
|
+
;;
|
|
95
|
+
skipped)
|
|
96
|
+
echo "A CI check run matching the filter was SKIPPED. The gate cannot treat a skipped check as passing: this project's own CI must actually run on the release commit. Check paths filters and job conditions, re-run CI on this commit, then re-dispatch this publish workflow at the tag ref."
|
|
97
|
+
;;
|
|
98
|
+
*)
|
|
99
|
+
echo "CI check concluded '$conclusion' (not success). The gate only proceeds when every matching check concluded success."
|
|
100
|
+
;;
|
|
101
|
+
esac
|
|
102
|
+
done <<< "$(jq -r '.[].conclusion' <<< "$not_success" | sort -u)"
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
echo "Publish gate: all $total matching CI check runs succeeded."
|
|
107
|
+
jq -r '.[] | " \(.name): \(.conclusion)"' <<< "$runs"
|
|
108
|
+
exit 0
|
|
109
|
+
done
|
|
110
|
+
pypi:
|
|
111
|
+
needs: gate
|
|
112
|
+
runs-on: ubuntu-latest
|
|
113
|
+
steps:
|
|
114
|
+
- uses: actions/checkout@v6
|
|
115
|
+
- uses: astral-sh/setup-uv@v7
|
|
116
|
+
- run: uv build --out-dir dist
|
|
117
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
118
|
+
with:
|
|
119
|
+
skip-existing: true
|
|
120
|
+
npm:
|
|
121
|
+
needs: gate
|
|
122
|
+
runs-on: ubuntu-latest
|
|
123
|
+
steps:
|
|
124
|
+
- uses: actions/checkout@v6
|
|
125
|
+
- uses: actions/setup-node@v6
|
|
126
|
+
with:
|
|
127
|
+
node-version: 24
|
|
128
|
+
registry-url: https://registry.npmjs.org
|
|
129
|
+
- name: Check if already published
|
|
130
|
+
id: check-npm
|
|
131
|
+
run: |
|
|
132
|
+
PKG_NAME=$(node -p "require('./package.json').name")
|
|
133
|
+
PKG_VERSION=$(node -p "require('./package.json').version")
|
|
134
|
+
if npm view "${PKG_NAME}@${PKG_VERSION}" version 2>/dev/null; then
|
|
135
|
+
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
136
|
+
echo "Already published: ${PKG_NAME}@${PKG_VERSION}"
|
|
137
|
+
fi
|
|
138
|
+
- name: Determine dist-tag
|
|
139
|
+
id: dist-tag
|
|
140
|
+
run: |
|
|
141
|
+
PKG_VERSION=$(node -p "require('./package.json').version")
|
|
142
|
+
if echo "$PKG_VERSION" | grep -q '-'; then
|
|
143
|
+
PREID=$(echo "$PKG_VERSION" | sed 's/[^-]*-//' | sed 's/\.[^.]*$//')
|
|
144
|
+
echo "tag=--tag $PREID" >> "$GITHUB_OUTPUT"
|
|
145
|
+
else
|
|
146
|
+
echo "tag=" >> "$GITHUB_OUTPUT"
|
|
147
|
+
fi
|
|
148
|
+
- run: npm publish --provenance --access public ${{
|
|
149
|
+
steps.dist-tag.outputs.tag }}
|
|
150
|
+
if: steps.check-npm.outputs.skip != 'true'
|
|
151
|
+
env:
|
|
152
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
".github/workflows/ci.yml": "b4e075171b131d25f9cce55a3e3a30732e95a2a794af00f354ee3200626d6a04",
|
|
3
|
-
".github/workflows/publish.yml": "
|
|
3
|
+
".github/workflows/publish.yml": "20db711b8a7745c3ab41814b827e946d60e937e82ee3984e86f39567717199b1",
|
|
4
4
|
"CHANGELOG.md": "7a6ec46141007c18090a0ff325e2dd68cd51588c4e0b5af7b580365e5eaaca85",
|
|
5
|
-
".gitignore": "
|
|
5
|
+
".gitignore": "c0582f9b1c640f9f9a8acbbe02cd19fff50e66cc595f25e129b7cc9b6cd357db",
|
|
6
6
|
"LICENSE": "e958892abc1dd5d991fca6d528e695d335f25773d373d2e0be5f4a9507d8f8d5",
|
|
7
7
|
"CLAUDE.md": "7294b791570185dc31020dadb092b5b79681ba8ee932fe9a3974e27eaae56c4f",
|
|
8
8
|
".rlsbl/hooks/pre-release.sh": "b2dc17c243d0b1a2c1e23c1c25db6f94878596df81dc76c41b32d95f740a7d44",
|
|
@@ -12,5 +12,6 @@
|
|
|
12
12
|
".rlsbl/lint/python.toml": "9cfbcef2e010d5fad243437bf2fd8df54a1fae70ee0762f9d11da70fe207501c",
|
|
13
13
|
".rlsbl/lint/go.toml": "807d5cf760baad6d571a5bfd43cb163efe356f7462ba9f1918d72de45f62339f",
|
|
14
14
|
".rlsbl/lint/npm.toml": "baa36014e65923d8cc5c8b83c77fa651da79351627570476402da66840027645",
|
|
15
|
-
".npmignore": "7c0eea9785c0318aeb39bf8b670ce8384f4a5b812fde69ce23d7d018057325a3"
|
|
15
|
+
".npmignore": "7c0eea9785c0318aeb39bf8b670ce8384f4a5b812fde69ce23d7d018057325a3",
|
|
16
|
+
".github/workflows/ci-pypi.yml": "6bde3f6dd33979636f6a8f51721f85519c4d2b6106cb9c9fa78e540df26471c4"
|
|
16
17
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"files": {
|
|
4
|
+
".github/workflows/ci-pypi.yml": "6bde3f6dd33979636f6a8f51721f85519c4d2b6106cb9c9fa78e540df26471c4",
|
|
5
|
+
".npmignore": "7c0eea9785c0318aeb39bf8b670ce8384f4a5b812fde69ce23d7d018057325a3",
|
|
6
|
+
".github/workflows/publish.yml": "20db711b8a7745c3ab41814b827e946d60e937e82ee3984e86f39567717199b1",
|
|
7
|
+
".gitignore": "c0582f9b1c640f9f9a8acbbe02cd19fff50e66cc595f25e129b7cc9b6cd357db",
|
|
8
|
+
".rlsbl/lint/python.toml": "9cfbcef2e010d5fad243437bf2fd8df54a1fae70ee0762f9d11da70fe207501c",
|
|
9
|
+
".rlsbl/lint/npm.toml": "baa36014e65923d8cc5c8b83c77fa651da79351627570476402da66840027645"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strictcli",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "strictcli",
|
|
9
|
-
"version": "0.24.
|
|
9
|
+
"version": "0.24.2",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT"
|
|
12
12
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"""A strict, zero-dependency CLI framework for Python."""
|
|
1
|
+
"""A strict, zero-dependency CLI framework for Python with mandatory help text, type-safe flags, groups, and schema export."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
__version__ = "0.24.
|
|
5
|
+
__version__ = "0.24.2"
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
"App", "Flag", "Arg", "FlagSet", "MutexGroup", "CoRequired", "Requires",
|
|
@@ -1,27 +0,0 @@
|
|
|
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 }}
|
strictcli-0.24.0/.rlsbl/version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.92.0
|
strictcli-0.24.0/CHANGELOG.md
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
<!-- Generated by rlsbl from .rlsbl/changes/ — do not edit -->
|
|
2
|
-
|
|
3
|
-
# Changelog
|
|
4
|
-
|
|
5
|
-
## 0.23.0
|
|
6
|
-
|
|
7
|
-
Registration-time ban on bare --force flag name and --no-* prefix
|
|
8
|
-
|
|
9
|
-
<details>
|
|
10
|
-
<summary>Context</summary>
|
|
11
|
-
|
|
12
|
-
Flag names 'force' (exact) and names starting with 'no-' are now rejected at registration time. Bare --force encourages agents to bypass guardrails without thinking; qualified names like --force-overwrite make the intent explicit. The no- prefix is reserved for strictcli's auto-generated negation system (--no-flag for negatable bools).
|
|
13
|
-
|
|
14
|
-
</details>
|
|
15
|
-
|
|
16
|
-
### Features
|
|
17
|
-
|
|
18
|
-
- **New.** Registration-time ban on bare --force flag name and --no-* prefix. Flag names starting with no- are reserved for the negation system.
|
|
19
|
-
|
|
20
|
-
## 0.22.0
|
|
21
|
-
|
|
22
|
-
### Breaking
|
|
23
|
-
|
|
24
|
-
- **Breaking.** Bool flags no longer auto-default to false. BoolFlag without explicit Default(false) is now required — user must pass --flag or --no-flag.
|
|
25
|
-
|
|
26
|
-
### Features
|
|
27
|
-
|
|
28
|
-
- **New.** Schema dump validates project_id before writing — hard error if existing schema belongs to a different project.
|
|
29
|
-
- **New.** Context type with output methods (Info, Warn, Debug, Error, Emit) for structured handler communication.
|
|
30
|
-
- **New.** Comprehensive sub-project READMEs replacing severely stale documentation.
|
|
31
|
-
|
|
32
|
-
### Fixes
|
|
33
|
-
|
|
34
|
-
- **Fix.** TagContract now checks global flags, not just command-level flags.
|
|
35
|
-
|
|
36
|
-
## 0.21.0
|
|
37
|
-
|
|
38
|
-
### Features
|
|
39
|
-
|
|
40
|
-
- **New feature.** Programmatic invocation via `app.call()` and `app.acall()` with `InvokeError` exception for structured error handling.
|
|
41
|
-
- **New feature.** Schema versioning with `schema_version` field, constraint serialization (mutex, CoRequired, Requires, Implies), tag contracts, and arg defaults in `--dump-schema` output.
|
|
42
|
-
- **New feature.** Typed positional args with `type` (str/int/float/bool) and `choices` support, matching the flag type system.
|
|
43
|
-
- **New feature.** Command visibility: `hidden` and `interactive` declarations with help text filtering and schema serialization.
|
|
44
|
-
- **New feature.** First-class config fields with `config_field()` declarations, per-command binding, startup validation, `config init` template generation, and unknown-key rejection.
|
|
45
|
-
- **New feature.** Compound types `list[T]` and `dict[str, T]` on flags and args with projection-specific CLI parsing.
|
|
46
|
-
- **New feature.** Tool export: `json_schema()`, `as_tools()`, `Tool` dataclass, and router tool for AI agent integration.
|
|
47
|
-
- **New feature.** MCP projection via `serve_mcp()` and `--mcp` flag for Model Context Protocol tool serving.
|
|
48
|
-
- **New feature.** Optional `scope` field on check definitions for declarative pre-check context filtering, and `set_scope_adapter()` method on App for registering scope transformation callbacks.
|
|
49
|
-
|
|
50
|
-
### Fixes
|
|
51
|
-
|
|
52
|
-
- **Fix.** Validate unknown kwargs and enforce required globals in passthrough invoke path.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|