qurl-python 0.3.0__tar.gz → 0.5.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 (60) hide show
  1. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/ci.yml +1 -2
  2. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/claude-code-review.yml +39 -40
  3. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/claude.yml +39 -41
  4. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/codeql.yml +2 -2
  5. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/dependency-age-check-actions.yml +2 -1
  6. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/dependency-age-check-pip.yml +2 -1
  7. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/issue-priority.yml +1 -1
  8. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/pr-title.yml +1 -0
  9. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/secrets-scan.yml +1 -1
  10. qurl_python-0.5.0/.release-please-manifest.json +1 -0
  11. {qurl_python-0.3.0 → qurl_python-0.5.0}/CHANGELOG.md +43 -0
  12. qurl_python-0.5.0/PKG-INFO +618 -0
  13. qurl_python-0.5.0/README.md +581 -0
  14. {qurl_python-0.3.0 → qurl_python-0.5.0}/pyproject.toml +7 -3
  15. {qurl_python-0.3.0 → qurl_python-0.5.0}/src/layerv_qurl/__init__.py +6 -0
  16. qurl_python-0.5.0/src/layerv_qurl/_pagination.py +54 -0
  17. {qurl_python-0.3.0 → qurl_python-0.5.0}/src/layerv_qurl/_utils.py +277 -48
  18. {qurl_python-0.3.0 → qurl_python-0.5.0}/src/layerv_qurl/async_client.py +247 -63
  19. {qurl_python-0.3.0 → qurl_python-0.5.0}/src/layerv_qurl/client.py +258 -79
  20. qurl_python-0.5.0/src/layerv_qurl/crid.py +56 -0
  21. {qurl_python-0.3.0 → qurl_python-0.5.0}/src/layerv_qurl/errors.py +6 -1
  22. {qurl_python-0.3.0 → qurl_python-0.5.0}/src/layerv_qurl/langchain.py +7 -2
  23. {qurl_python-0.3.0 → qurl_python-0.5.0}/src/layerv_qurl/types.py +86 -9
  24. qurl_python-0.5.0/tests/client_support.py +41 -0
  25. qurl_python-0.5.0/tests/conftest.py +33 -0
  26. qurl_python-0.5.0/tests/fixtures/README.md +9 -0
  27. qurl_python-0.5.0/tests/fixtures/crid_v1_vectors.json +264 -0
  28. qurl_python-0.5.0/tests/test_access_code_listing.py +93 -0
  29. qurl_python-0.5.0/tests/test_batch_client.py +767 -0
  30. qurl_python-0.5.0/tests/test_client.py +1298 -0
  31. qurl_python-0.5.0/tests/test_contract_client.py +1733 -0
  32. {qurl_python-0.3.0 → qurl_python-0.5.0}/tests/test_langchain.py +22 -2
  33. qurl_python-0.5.0/tests/test_pagination.py +171 -0
  34. {qurl_python-0.3.0 → qurl_python-0.5.0}/tests/test_portal.py +85 -8
  35. qurl_python-0.5.0/tests/test_post_retry.py +189 -0
  36. qurl_python-0.5.0/tests/test_qurl_mutations.py +1257 -0
  37. qurl_python-0.5.0/tests/test_qurl_reads.py +642 -0
  38. qurl_python-0.5.0/tests/test_resource_name.py +257 -0
  39. qurl_python-0.5.0/tests/test_sdk_alignment.py +398 -0
  40. qurl_python-0.3.0/.release-please-manifest.json +0 -1
  41. qurl_python-0.3.0/PKG-INFO +0 -391
  42. qurl_python-0.3.0/README.md +0 -357
  43. qurl_python-0.3.0/tests/test_client.py +0 -5393
  44. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  45. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  46. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  47. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  48. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/dependabot.yml +0 -0
  49. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/dependency-review.yml +0 -0
  50. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/release-please.yml +0 -0
  51. {qurl_python-0.3.0 → qurl_python-0.5.0}/.github/workflows/validate-issue-templates.yml +0 -0
  52. {qurl_python-0.3.0 → qurl_python-0.5.0}/.gitignore +0 -0
  53. {qurl_python-0.3.0 → qurl_python-0.5.0}/CLAUDE.md +0 -0
  54. {qurl_python-0.3.0 → qurl_python-0.5.0}/CONTRIBUTING.md +0 -0
  55. {qurl_python-0.3.0 → qurl_python-0.5.0}/LICENSE +0 -0
  56. {qurl_python-0.3.0 → qurl_python-0.5.0}/SECURITY.md +0 -0
  57. {qurl_python-0.3.0 → qurl_python-0.5.0}/release-please-config.json +0 -0
  58. {qurl_python-0.3.0 → qurl_python-0.5.0}/src/layerv_qurl/py.typed +0 -0
  59. {qurl_python-0.3.0 → qurl_python-0.5.0}/tests/__init__.py +0 -0
  60. {qurl_python-0.3.0 → qurl_python-0.5.0}/tests/test_conformance.py +0 -0
@@ -14,7 +14,7 @@ jobs:
14
14
  # visibility into which Python versions broke.
15
15
  fail-fast: false
16
16
  matrix:
17
- python-version: ["3.10", "3.12", "3.13"]
17
+ python-version: ["3.10", "3.12", "3.13", "3.14"]
18
18
  steps:
19
19
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
20
20
  - name: Set up Python ${{ matrix.python-version }}
@@ -93,6 +93,5 @@ jobs:
93
93
  with:
94
94
  header: "qURL Python SDK Build"
95
95
  gates: '{"Tests": "${{ needs.test.result }}", "Conformance schema 1": "${{ needs.test-schema1.result }}", "Type check": "${{ needs.type-check.result }}"}'
96
- extra_fields: '{"Python": "3.10, 3.12, 3.13"}'
97
96
  secrets:
98
97
  SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
@@ -161,7 +161,7 @@ jobs:
161
161
  # step, so the verify step never runs and the PR gets a bare
162
162
  # `cancelled` check with no comment and nothing saying why.
163
163
  timeout-minutes: 10
164
- uses: anthropics/claude-code-action@e5ad3c7725bc2459721893f88879fef9dbcf97b0 # v1.0.202
164
+ uses: anthropics/claude-code-action@6c690188da61cf16ee7debb28383ba67f02abb4c # v1.0.242
165
165
  with:
166
166
  anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
167
167
  github_token: ${{ github.token }}
@@ -223,7 +223,9 @@ jobs:
223
223
  # Use only the action's GitHub MCP subprocess for reads and the final
224
224
  # comment. It receives the repository token but not the Anthropic key.
225
225
  # Local, network, delegation, and GitHub file-write tools stay denied.
226
- claude_args: '--model claude-opus-5 --disallowed-tools "Bash,Read,Glob,Grep,LS,Task,Edit,Write,MultiEdit,NotebookEdit,WebFetch,WebSearch,mcp__github_file_ops__commit_files,mcp__github_file_ops__delete_files,mcp__github__create_or_update_file,mcp__github__push_files,mcp__github__delete_file" --allowed-tools "mcp__github__get_pull_request,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_file_contents,mcp__github__search_code,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__search_issues,mcp__github__search_pull_requests,mcp__github__list_issues,mcp__github__list_pull_requests,mcp__github__add_issue_comment"'
226
+ # Review model setting: Opus 5.5 at medium effort. Keep the model and
227
+ # effort identical in claude.yml; change both together.
228
+ claude_args: '--model claude-opus-5-5 --effort medium --disallowed-tools "Bash,Read,Glob,Grep,LS,Task,Edit,Write,MultiEdit,NotebookEdit,WebFetch,WebSearch,mcp__github_file_ops__commit_files,mcp__github_file_ops__delete_files,mcp__github__create_or_update_file,mcp__github__push_files,mcp__github__delete_file" --allowed-tools "mcp__github__get_pull_request,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_file_contents,mcp__github__search_code,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__search_issues,mcp__github__search_pull_requests,mcp__github__list_issues,mcp__github__list_pull_requests,mcp__github__add_issue_comment"'
227
229
 
228
230
  - name: Verify terminal Claude review
229
231
  if: success() && steps.claude-review.outcome == 'success'
@@ -270,7 +272,7 @@ jobs:
270
272
  # restoreConfigFromBase() fetches the base branch through it. Asserting the
271
273
  # LOCAL_ORIGIN pin survived therefore tested the action's version, not
272
274
  # Claude's behavior, and failed closed on every real PR. Still
273
- # present at v1.0.210, so bumping does not fix it.
275
+ # present at v1.0.238, so bumping does not fix it.
274
276
  #
275
277
  # The property that pin bought still has to hold: origin may only ever
276
278
  # address THIS repository, so no credential-bearing remote can point
@@ -286,20 +288,30 @@ jobs:
286
288
  # matters on GHES. A future action version that drops the ".git" suffix,
287
289
  # adds a port, or normalizes the path differently fails CLOSED here - safe,
288
290
  # but it breaks every run until the action_origin construction below is
289
- # updated. The failure prints the observed and expected destinations, so
290
- # start there.
291
+ # updated. The failure prints the observed host and the expected
292
+ # destination, so start there. An origin outside the allowlists prints
293
+ # neither.
294
+ # The authority is everything up to the first "/", and userinfo is everything
295
+ # in it before the LAST "@". Host and userinfo are then held to allowlists,
296
+ # because a URL client ends the host at "#", "?" or "\" as well: without that,
297
+ # https://evil.example#@github.com/o/r.git parses here as host github.com
298
+ # while git connects to evil.example. A shape outside the allowlists (an IPv6
299
+ # literal host, userinfo with other punctuation, no scheme at all) makes the
300
+ # function fail, and the caller fails closed.
291
301
  origin_destination() {
292
- local url="$1" scheme rest authority path
293
- if [[ "${url}" == *://* ]]; then
294
- scheme="${url%%://*}"
295
- rest="${url#*://}"
296
- authority="${rest%%/*}"
297
- path="${rest#"${authority}"}"
298
- authority="${authority##*@}"
299
- printf '%s://%s%s' "${scheme}" "${authority}" "${path}"
300
- return
302
+ local url="$1" scheme rest authority host userinfo
303
+ [[ "${url}" == *://* ]] || return 1
304
+ scheme="${url%%://*}"
305
+ rest="${url#*://}"
306
+ authority="${rest%%/*}"
307
+ host="${authority##*@}"
308
+ if [[ "${authority}" == *@* ]]; then
309
+ userinfo="${authority%@*}"
310
+ [[ "${userinfo}" =~ ^[A-Za-z0-9._~%:_-]+$ ]] || return 1
301
311
  fi
302
- printf '%s' "${url}"
312
+ [[ "${scheme}" =~ ^[A-Za-z][A-Za-z0-9+.-]*$ &&
313
+ "${host}" =~ ^[A-Za-z0-9.-]+(:[0-9]+)?$ ]] || return 1
314
+ printf '%s://%s%s' "${scheme}" "${host}" "${rest#"${authority}"}"
303
315
  }
304
316
 
305
317
  if [[ -z "${GITHUB_SERVER_URL:-}" || -z "${GITHUB_REPOSITORY:-}" ||
@@ -332,33 +344,20 @@ jobs:
332
344
  exit 1
333
345
  fi
334
346
  for origin_candidate in "${origin_urls[0]}" "${origin_push_urls[0]}"; do
335
- # Never echo origin_candidate itself - it carries the token. Only the
336
- # userinfo-stripped destination is safe to print.
337
- origin_dest="$(origin_destination "${origin_candidate}")"
338
- # After a correct strip the authority holds no "@", so a userinfo-position
339
- # credential can only survive in the PATH: that is the mis-split signal -
340
- # userinfo holding an unencoded "/" leaves the "@" past the first path
341
- # separator, where "${authority##*@}" never reaches it. Test the path
342
- # specifically rather than the whole string, so scp-style remotes
343
- # (git@host:o/r.git, no scheme, credential is a key not userinfo) still
344
- # print their real destination. This only redacts userinfo-position
345
- # credentials; a secret elsewhere in the URL would still print, which
346
- # needs the secret to be known already. A schemeless remote
347
- # (tok@host:o/r.git) also prints verbatim: that is deliberate, so
348
- # scp-style remotes keep their diagnostic value, and Actions secret
349
- # masking covers registered secrets.
350
- safe_dest="${origin_dest}"
351
- if [[ "${origin_dest}" == *://* ]]; then
352
- dest_rest="${origin_dest#*://}"
353
- dest_authority="${dest_rest%%/*}"
354
- if [[ "${dest_rest#"${dest_authority}"}" == *@* ]]; then
355
- safe_dest='<redacted: destination path retained userinfo>'
356
- fi
347
+ # Never echo origin_candidate itself - it may carry the token.
348
+ if [[ "${origin_candidate}" == "${LOCAL_ORIGIN}" ]]; then
349
+ continue
357
350
  fi
358
- if [[ "${origin_candidate}" != "${LOCAL_ORIGIN}" ]] &&
359
- [[ "${origin_dest,,}" != "${action_origin,,}" ]] &&
351
+ if ! origin_dest="$(origin_destination "${origin_candidate}")"; then
352
+ echo "::error::The review origin is neither '${LOCAL_ORIGIN}' nor a recognizable URL of this repository; failing closed."
353
+ exit 1
354
+ fi
355
+ if [[ "${origin_dest,,}" != "${action_origin,,}" ]] &&
360
356
  [[ "${origin_dest,,}" != "${action_origin_bare,,}" ]]; then
361
- echo "::error::The review origin moved off this repository; failing closed. Got '${safe_dest}', expected '${action_origin}' (with or without .git) or '${LOCAL_ORIGIN}'."
357
+ # Print only scheme and host: the path of a hostile URL can carry anything,
358
+ # including the token.
359
+ origin_host="${origin_dest#*://}"
360
+ echo "::error::The review origin moved off this repository; failing closed. Got host '${origin_dest%%://*}://${origin_host%%/*}', expected '${action_origin}' (with or without .git) or '${LOCAL_ORIGIN}'."
362
361
  exit 1
363
362
  fi
364
363
  done
@@ -328,7 +328,7 @@ jobs:
328
328
  if: success()
329
329
  # v1.0.180 keeps interactive commands on the same fail-closed runner as
330
330
  # automatic review and avoids the v1.0.140/141 issue-comment crash.
331
- uses: anthropics/claude-code-action@e5ad3c7725bc2459721893f88879fef9dbcf97b0 # v1.0.202
331
+ uses: anthropics/claude-code-action@6c690188da61cf16ee7debb28383ba67f02abb4c # v1.0.242
332
332
  with:
333
333
  anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
334
334
  # Omit github_token so the action uses its OIDC/GitHub App token path.
@@ -341,12 +341,13 @@ jobs:
341
341
  # Keep comment-triggered analysis on the same proven model as the
342
342
  # automatic PR review. The action's implicit default may select the
343
343
  # 1M-context variant, which this repository credential cannot start.
344
- # scripts/check-claude-model-lockstep.py enforces this coupling.
344
+ # Nothing in this repository enforces this coupling: change the model and
345
+ # effort here and in claude-code-review.yml together.
345
346
  # Do not add extra allowed tools by default: the action's base GitHub
346
347
  # tools are sufficient here. The automatic review workflow uses a
347
348
  # narrow GitHub MCP allowlist because its explicit prompt needs PR
348
349
  # inspection.
349
- claude_args: '--model claude-opus-5'
350
+ claude_args: '--model claude-opus-5-5 --effort medium'
350
351
 
351
352
  - name: Verify reviewed pull request head
352
353
  if: success() && steps.claude.outcome == 'success'
@@ -394,7 +395,7 @@ jobs:
394
395
  # restoreConfigFromBase() fetches the base branch through it. Asserting the
395
396
  # LOCAL_ORIGIN pin survived therefore tested the action's version, not
396
397
  # Claude's behavior, and failed closed on every real PR (#268). Still
397
- # present at v1.0.210, so bumping does not fix it.
398
+ # present at v1.0.238, so bumping does not fix it.
398
399
  #
399
400
  # The property that pin bought still has to hold: origin may only ever
400
401
  # address THIS repository, so no credential-bearing remote can point
@@ -410,20 +411,30 @@ jobs:
410
411
  # matters on GHES. A future action version that drops the ".git" suffix,
411
412
  # adds a port, or normalizes the path differently fails CLOSED here - safe,
412
413
  # but it breaks every run until the action_origin construction below is
413
- # updated. The failure prints the observed and expected destinations, so
414
- # start there.
414
+ # updated. The failure prints the observed host and the expected
415
+ # destination, so start there. An origin outside the allowlists prints
416
+ # neither.
417
+ # The authority is everything up to the first "/", and userinfo is everything
418
+ # in it before the LAST "@". Host and userinfo are then held to allowlists,
419
+ # because a URL client ends the host at "#", "?" or "\" as well: without that,
420
+ # https://evil.example#@github.com/o/r.git parses here as host github.com
421
+ # while git connects to evil.example. A shape outside the allowlists (an IPv6
422
+ # literal host, userinfo with other punctuation, no scheme at all) makes the
423
+ # function fail, and the caller fails closed.
415
424
  origin_destination() {
416
- local url="$1" scheme rest authority path
417
- if [[ "${url}" == *://* ]]; then
418
- scheme="${url%%://*}"
419
- rest="${url#*://}"
420
- authority="${rest%%/*}"
421
- path="${rest#"${authority}"}"
422
- authority="${authority##*@}"
423
- printf '%s://%s%s' "${scheme}" "${authority}" "${path}"
424
- return
425
+ local url="$1" scheme rest authority host userinfo
426
+ [[ "${url}" == *://* ]] || return 1
427
+ scheme="${url%%://*}"
428
+ rest="${url#*://}"
429
+ authority="${rest%%/*}"
430
+ host="${authority##*@}"
431
+ if [[ "${authority}" == *@* ]]; then
432
+ userinfo="${authority%@*}"
433
+ [[ "${userinfo}" =~ ^[A-Za-z0-9._~%:_-]+$ ]] || return 1
425
434
  fi
426
- printf '%s' "${url}"
435
+ [[ "${scheme}" =~ ^[A-Za-z][A-Za-z0-9+.-]*$ &&
436
+ "${host}" =~ ^[A-Za-z0-9.-]+(:[0-9]+)?$ ]] || return 1
437
+ printf '%s://%s%s' "${scheme}" "${host}" "${rest#"${authority}"}"
427
438
  }
428
439
 
429
440
  if [[ -z "${GITHUB_SERVER_URL:-}" || -z "${GITHUB_REPOSITORY:-}" ||
@@ -456,33 +467,20 @@ jobs:
456
467
  exit 1
457
468
  fi
458
469
  for origin_candidate in "${origin_urls[0]}" "${origin_push_urls[0]}"; do
459
- # Never echo origin_candidate itself - it carries the token. Only the
460
- # userinfo-stripped destination is safe to print.
461
- origin_dest="$(origin_destination "${origin_candidate}")"
462
- # After a correct strip the authority holds no "@", so a userinfo-position
463
- # credential can only survive in the PATH: that is the mis-split signal -
464
- # userinfo holding an unencoded "/" leaves the "@" past the first path
465
- # separator, where "${authority##*@}" never reaches it. Test the path
466
- # specifically rather than the whole string, so scp-style remotes
467
- # (git@host:o/r.git, no scheme, credential is a key not userinfo) still
468
- # print their real destination. This only redacts userinfo-position
469
- # credentials; a secret elsewhere in the URL would still print, which
470
- # needs the secret to be known already. A schemeless remote
471
- # (tok@host:o/r.git) also prints verbatim: that is deliberate, so
472
- # scp-style remotes keep their diagnostic value, and Actions secret
473
- # masking covers registered secrets.
474
- safe_dest="${origin_dest}"
475
- if [[ "${origin_dest}" == *://* ]]; then
476
- dest_rest="${origin_dest#*://}"
477
- dest_authority="${dest_rest%%/*}"
478
- if [[ "${dest_rest#"${dest_authority}"}" == *@* ]]; then
479
- safe_dest='<redacted: destination path retained userinfo>'
480
- fi
470
+ # Never echo origin_candidate itself - it may carry the token.
471
+ if [[ "${origin_candidate}" == "${LOCAL_ORIGIN}" ]]; then
472
+ continue
481
473
  fi
482
- if [[ "${origin_candidate}" != "${LOCAL_ORIGIN}" ]] &&
483
- [[ "${origin_dest,,}" != "${action_origin,,}" ]] &&
474
+ if ! origin_dest="$(origin_destination "${origin_candidate}")"; then
475
+ echo "::error::The local origin is neither '${LOCAL_ORIGIN}' nor a recognizable URL of this repository; failing closed."
476
+ exit 1
477
+ fi
478
+ if [[ "${origin_dest,,}" != "${action_origin,,}" ]] &&
484
479
  [[ "${origin_dest,,}" != "${action_origin_bare,,}" ]]; then
485
- echo "::error::The local origin moved off this repository; failing closed. Got '${safe_dest}', expected '${action_origin}' (with or without .git) or '${LOCAL_ORIGIN}'."
480
+ # Print only scheme and host: the path of a hostile URL can carry anything,
481
+ # including the token.
482
+ origin_host="${origin_dest#*://}"
483
+ echo "::error::The local origin moved off this repository; failing closed. Got host '${origin_dest%%://*}://${origin_host%%/*}', expected '${action_origin}' (with or without .git) or '${LOCAL_ORIGIN}'."
486
484
  exit 1
487
485
  fi
488
486
  done
@@ -33,13 +33,13 @@ jobs:
33
33
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
34
34
 
35
35
  - name: Initialize CodeQL
36
- uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4
36
+ uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
37
37
  with:
38
38
  languages: ${{ matrix.language }}
39
39
  build-mode: ${{ matrix.build-mode }}
40
40
  queries: security-and-quality
41
41
 
42
42
  - name: Perform CodeQL Analysis
43
- uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4
43
+ uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
44
44
  with:
45
45
  category: "/language:${{ matrix.language }}"
@@ -10,6 +10,7 @@ name: Dependency Age Check (Actions)
10
10
  # no workflow/composite-action changes are in the diff.
11
11
  on:
12
12
  pull_request:
13
+ types: [opened, synchronize, reopened, labeled, unlabeled]
13
14
  workflow_dispatch:
14
15
 
15
16
  # Cancel superseded runs on the same PR branch — the reusable workflow
@@ -35,7 +36,7 @@ jobs:
35
36
  # only if/name/needs/permissions/secrets/strategy/uses/with/concurrency
36
37
  # are valid on a job that calls a reusable workflow. The reusable
37
38
  # workflow itself sets `timeout-minutes: 5` internally.
38
- uses: layervai/ops-routines-workflows/.github/workflows/age-check-actions.yml@d07fa2fe3a103907ff2b1a1a71509a6dcd8e9d32 # v0.13.0
39
+ uses: layervai/ops-routines-workflows/.github/workflows/age-check-actions.yml@414821a809395384de83d853a4bfd5b46e6bfc55 # v0.15.0
39
40
  with:
40
41
  min_age_days: 7
41
42
  # Post a sticky PR comment when an age-check fails, listing each
@@ -10,6 +10,7 @@ name: Dependency Age Check (pip)
10
10
  # no requirements/poetry.lock/pyproject.toml changes are in the diff.
11
11
  on:
12
12
  pull_request:
13
+ types: [opened, synchronize, reopened, labeled, unlabeled]
13
14
  workflow_dispatch:
14
15
 
15
16
  # Cancel superseded runs on the same PR branch — pypi.org calls are
@@ -34,7 +35,7 @@ jobs:
34
35
  # only if/name/needs/permissions/secrets/strategy/uses/with/concurrency
35
36
  # are valid on a job that calls a reusable workflow. The reusable
36
37
  # workflow itself sets `timeout-minutes: 5` internally.
37
- uses: layervai/ops-routines-workflows/.github/workflows/age-check-pip.yml@d07fa2fe3a103907ff2b1a1a71509a6dcd8e9d32 # v0.13.0
38
+ uses: layervai/ops-routines-workflows/.github/workflows/age-check-pip.yml@414821a809395384de83d853a4bfd5b46e6bfc55 # v0.15.0
38
39
  with:
39
40
  min_age_days: 7
40
41
  # Post a sticky PR comment when an age-check fails, listing each
@@ -48,6 +48,6 @@ jobs:
48
48
  # reusable's own `sender.type != 'Bot'` check short-circuits them
49
49
  # before setFailed — net effect is a near-instant no-op run.
50
50
  if: ${{ github.actor != 'github-actions[bot]' }}
51
- uses: layervai/ops-routines-workflows/.github/workflows/issue-priority.yml@d07fa2fe3a103907ff2b1a1a71509a6dcd8e9d32 # v0.13.0
51
+ uses: layervai/ops-routines-workflows/.github/workflows/issue-priority.yml@88b48c5ab3e1262018f44bbe5f4a03b94a3e39aa # v0.14.0
52
52
  permissions:
53
53
  issues: write
@@ -28,6 +28,7 @@ jobs:
28
28
  chore
29
29
  revert
30
30
  scopes: |
31
+ main
31
32
  client
32
33
  api
33
34
  ci
@@ -16,6 +16,6 @@ jobs:
16
16
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
17
17
  with:
18
18
  fetch-depth: 0
19
- - uses: trufflesecurity/trufflehog@bcfcf73aaf4759d4dadc2783177c245a02792318 # v3.97.0
19
+ - uses: trufflesecurity/trufflehog@363923b901c911a9164f50b6c423f47c15372b1c # v3.97.4
20
20
  with:
21
21
  extra_args: --only-verified
@@ -0,0 +1 @@
1
+ {".":"0.5.0"}
@@ -1,5 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.0](https://github.com/layervai/qurl-python/compare/v0.4.0...v0.5.0) (2026-11-07)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * send the required public resource name ([#185](https://github.com/layervai/qurl-python/issues/185))
9
+ * list_access_codes no longer accepts limit or cursor, and list_access_codes_all no longer accepts page_size. The API does not support these parameters. Remove them from calls.
10
+ * **client:** adopt the kind-first credential API ([#133](https://github.com/layervai/qurl-python/issues/133))
11
+
12
+ ### Features
13
+
14
+ * align resource identity and sharing with Go SDK ([#169](https://github.com/layervai/qurl-python/issues/169)) ([91018dd](https://github.com/layervai/qurl-python/commit/91018dd645613e4a5d506eab620597f29a4bff6e))
15
+ * **client:** adopt the kind-first credential API ([#133](https://github.com/layervai/qurl-python/issues/133)) ([b5c579b](https://github.com/layervai/qurl-python/commit/b5c579b67fbad0d2c9989a404cf3c9c4dd0d3101))
16
+ * paginate the contract list APIs in both clients ([#174](https://github.com/layervai/qurl-python/issues/174)) ([0a8f7e4](https://github.com/layervai/qurl-python/commit/0a8f7e43f13a3a90776d48e9715a75959cee083f))
17
+ * send the required public resource name ([#185](https://github.com/layervai/qurl-python/issues/185)) ([0ea8726](https://github.com/layervai/qurl-python/commit/0ea8726d9f5c8f2eb9c6604fe8a66e79aa8f9206))
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * avoid replaying uncertain POST and PATCH operations ([#177](https://github.com/layervai/qurl-python/issues/177)) ([717f8ec](https://github.com/layervai/qurl-python/commit/717f8ecd61ae8a8b7bd1b9dd1780436debd8405d)), closes [#71](https://github.com/layervai/qurl-python/issues/71) [#20](https://github.com/layervai/qurl-python/issues/20)
23
+ * **ci:** allow generated release PR titles ([#189](https://github.com/layervai/qurl-python/issues/189)) ([ebfe45d](https://github.com/layervai/qurl-python/commit/ebfe45d469cdafeaa7f753b2cf7ffefa38a278e2))
24
+ * match the unpaginated access-code list contract ([#178](https://github.com/layervai/qurl-python/issues/178)) ([8254f75](https://github.com/layervai/qurl-python/commit/8254f75ff5d7efd7978e9e258dfc1f1d8e5bdf54))
25
+ * redact invalid resolve tokens before transport ([#171](https://github.com/layervai/qurl-python/issues/171)) ([b7f3546](https://github.com/layervai/qurl-python/commit/b7f3546978b5a40fc603211731158bac739346ed))
26
+ * require the LangChain Python 3.14 import fix ([#175](https://github.com/layervai/qurl-python/issues/175)) ([9a7f274](https://github.com/layervai/qurl-python/commit/9a7f2745b43261b64fee943907ad8ae1753ddd47))
27
+ * validate connector lookups by immutable slug ([#168](https://github.com/layervai/qurl-python/issues/168)) ([2b68486](https://github.com/layervai/qurl-python/commit/2b68486b32a8b24ff2486640f0cd8541ff962350))
28
+ * validate single-token management IDs before transport ([#172](https://github.com/layervai/qurl-python/issues/172)) ([2b40d5d](https://github.com/layervai/qurl-python/commit/2b40d5dd3826cb8c42a556e11b103660872a07aa))
29
+
30
+
31
+ ### Documentation
32
+
33
+ * explain qURL sharing workflows in Python ([#167](https://github.com/layervai/qurl-python/issues/167)) ([4770030](https://github.com/layervai/qurl-python/commit/47700308e531bb9e7507a45c6d68038d663a4a85))
34
+
35
+ ## [0.4.0](https://github.com/layervai/qurl-python/compare/v0.3.0...v0.4.0) (2026-10-08)
36
+
37
+
38
+ ### ⚠ BREAKING CHANGES
39
+
40
+ * preserve canonical resource quotas and monthly usage ([#157](https://github.com/layervai/qurl-python/issues/157))
41
+
42
+ ### Bug Fixes
43
+
44
+ * preserve canonical resource quotas and monthly usage ([#157](https://github.com/layervai/qurl-python/issues/157)) ([e017e78](https://github.com/layervai/qurl-python/commit/e017e7807c5012a93de387ec73a57043d1028806))
45
+
3
46
  ## [0.3.0](https://github.com/layervai/qurl-python/compare/v0.2.2...v0.3.0) (2026-09-08)
4
47
 
5
48