conjira-cli 0.2.5__tar.gz → 0.2.6__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 (32) hide show
  1. {conjira_cli-0.2.5/src/conjira_cli.egg-info → conjira_cli-0.2.6}/PKG-INFO +48 -3
  2. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/README.md +47 -2
  3. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/pyproject.toml +1 -1
  4. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/__init__.py +1 -1
  5. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/cli.py +48 -12
  6. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/client.py +336 -39
  7. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/config.py +67 -0
  8. conjira_cli-0.2.6/src/conjira_cli/footer_comments.py +97 -0
  9. {conjira_cli-0.2.5 → conjira_cli-0.2.6/src/conjira_cli.egg-info}/PKG-INFO +48 -3
  10. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli.egg-info/SOURCES.txt +1 -0
  11. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/tests/test_cli.py +84 -0
  12. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/tests/test_client.py +148 -1
  13. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/tests/test_config.py +11 -1
  14. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/LICENSE +0 -0
  15. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/setup.cfg +0 -0
  16. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/setup.py +0 -0
  17. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/__main__.py +0 -0
  18. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/inline_comments.py +0 -0
  19. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/markdown_export.py +0 -0
  20. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/markdown_import.py +0 -0
  21. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/section_edit.py +0 -0
  22. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/setup_macos.py +0 -0
  23. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli/tree_export.py +0 -0
  24. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli.egg-info/dependency_links.txt +0 -0
  25. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli.egg-info/entry_points.txt +0 -0
  26. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/src/conjira_cli.egg-info/top_level.txt +0 -0
  27. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/tests/test_inline_comments.py +0 -0
  28. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/tests/test_markdown_export.py +0 -0
  29. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/tests/test_markdown_import.py +0 -0
  30. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/tests/test_section_edit.py +0 -0
  31. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/tests/test_setup_macos.py +0 -0
  32. {conjira_cli-0.2.5 → conjira_cli-0.2.6}/tests/test_tree_export.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conjira-cli
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: Unofficial agent-friendly CLI for self-hosted Confluence and Jira
5
5
  Author: quanttraderkim
6
6
  License-Expression: MIT
@@ -56,6 +56,7 @@ For report-style pages, it can also preserve a small set of Confluence-native pr
56
56
  - create or update Confluence pages from either storage HTML or Markdown
57
57
  - detect stale Markdown exports and refresh them from the live page
58
58
  - fetch and export grouped Confluence inline comment threads
59
+ - fetch Confluence page footer comments and replies
59
60
  - upload attachments to Confluence pages
60
61
  - read Jira issues, search with JQL, inspect create metadata, create issues, and add comments
61
62
  - preview writes with `--dry-run`, then enforce them with `--allow-write` plus optional allowlists
@@ -260,7 +261,33 @@ security add-generic-password -U -s conjira-cli -a jira-prod -w "$PAT"
260
261
  unset PAT
261
262
  ```
262
263
 
263
- On Linux or Windows, use environment variables or token files instead of Keychain. For example:
264
+ On Windows, use Windows Credential Manager as the closest Keychain-style path. Keep `local/agent.env` non-secret, remove or comment out `CONFLUENCE_PAT_KEYCHAIN_*` and `JIRA_PAT_KEYCHAIN_*`, then load PATs into the current PowerShell session right before running `conjira`.
265
+
266
+ Set up the PowerShell `CredentialManager` module and store the PATs once:
267
+
268
+ ```powershell
269
+ Install-Module CredentialManager -Scope CurrentUser
270
+
271
+ $cred = Get-Credential -UserName confluence-prod -Message "Enter Confluence PAT as password"
272
+ New-StoredCredential -Target "conjira-cli/confluence-prod" -UserName $cred.UserName -Password $cred.GetNetworkCredential().Password -Persist LocalMachine
273
+ Remove-Variable cred
274
+
275
+ $cred = Get-Credential -UserName jira-prod -Message "Enter Jira PAT as password"
276
+ New-StoredCredential -Target "conjira-cli/jira-prod" -UserName $cred.UserName -Password $cred.GetNetworkCredential().Password -Persist LocalMachine
277
+ Remove-Variable cred
278
+ ```
279
+
280
+ Before running the CLI in a new PowerShell session, read those credentials into environment variables. The values only live in that session:
281
+
282
+ ```powershell
283
+ $env:CONFLUENCE_PAT = (Get-StoredCredential -Target "conjira-cli/confluence-prod").GetNetworkCredential().Password
284
+ $env:JIRA_PAT = (Get-StoredCredential -Target "conjira-cli/jira-prod").GetNetworkCredential().Password
285
+
286
+ conjira --env-file .\local\agent.env auth-check
287
+ conjira --env-file .\local\agent.env jira-auth-check
288
+ ```
289
+
290
+ If Windows Credential Manager is unavailable, or on Linux, use environment variables or token files instead. For example:
264
291
 
265
292
  ```dotenv
266
293
  CONFLUENCE_BASE_URL=https://confluence.example.com
@@ -318,6 +345,12 @@ Export grouped inline comment threads:
318
345
  conjira --env-file ./local/agent.env export-inline-comments-md --page-id 123456 --status open --output-dir "/path/to/work-folder"
319
346
  ```
320
347
 
348
+ Read page footer comments and replies:
349
+
350
+ ```bash
351
+ conjira --env-file ./local/agent.env get-footer-comments --page-id 123456
352
+ ```
353
+
321
354
  Create or update a Confluence page:
322
355
 
323
356
  ```bash
@@ -413,6 +446,17 @@ Jira settings:
413
446
  - `JIRA_ALLOWED_PROJECT_KEYS`
414
447
  - `JIRA_ALLOWED_ISSUE_KEYS`
415
448
 
449
+ Shared rate-limit settings:
450
+
451
+ - `CONJIRA_RATE_LIMIT_ENABLED`: set to `false` to disable client-side throttling
452
+ - `CONJIRA_RATE_LIMIT_RPS`: default `4.0`
453
+ - `CONJIRA_RATE_LIMIT_BURST`: default `8`
454
+ - `CONJIRA_MAX_RETRIES`: default `5` retries after the first failed request
455
+ - `CONJIRA_RETRY_BASE_SECONDS`: default `1.0`
456
+ - `CONJIRA_RETRY_MAX_SECONDS`: default `30.0`
457
+
458
+ Product-specific overrides such as `CONFLUENCE_RATE_LIMIT_RPS` and `JIRA_RATE_LIMIT_RPS` take precedence over the shared `CONJIRA_*` values. The throttle state is shared across local CLI processes for the same product, base URL, and token, so separate agent calls are paced together.
459
+
416
460
  ## Safety model
417
461
 
418
462
  This CLI intentionally does not implement delete commands for Confluence pages or Jira issues.
@@ -429,7 +473,8 @@ When the CLI hits a common API failure, it now returns a `guidance` field alongs
429
473
  - `403`: check product permissions and any configured allowlists
430
474
  - `404`: check the page ID, issue key, or target path and confirm the PAT owner can see it in the web UI
431
475
  - `409`: refresh live content and retry, especially for Confluence updates after concurrent edits
432
- - `429` and `5xx`: retry after a short delay and reduce request volume if you are looping
476
+ - `429`: the CLI automatically retries with backoff and honors `Retry-After` when the server sends it
477
+ - `5xx`: retry after a short delay and reduce request volume if you are looping
433
478
 
434
479
  ## Export strategy
435
480
 
@@ -27,6 +27,7 @@ For report-style pages, it can also preserve a small set of Confluence-native pr
27
27
  - create or update Confluence pages from either storage HTML or Markdown
28
28
  - detect stale Markdown exports and refresh them from the live page
29
29
  - fetch and export grouped Confluence inline comment threads
30
+ - fetch Confluence page footer comments and replies
30
31
  - upload attachments to Confluence pages
31
32
  - read Jira issues, search with JQL, inspect create metadata, create issues, and add comments
32
33
  - preview writes with `--dry-run`, then enforce them with `--allow-write` plus optional allowlists
@@ -231,7 +232,33 @@ security add-generic-password -U -s conjira-cli -a jira-prod -w "$PAT"
231
232
  unset PAT
232
233
  ```
233
234
 
234
- On Linux or Windows, use environment variables or token files instead of Keychain. For example:
235
+ On Windows, use Windows Credential Manager as the closest Keychain-style path. Keep `local/agent.env` non-secret, remove or comment out `CONFLUENCE_PAT_KEYCHAIN_*` and `JIRA_PAT_KEYCHAIN_*`, then load PATs into the current PowerShell session right before running `conjira`.
236
+
237
+ Set up the PowerShell `CredentialManager` module and store the PATs once:
238
+
239
+ ```powershell
240
+ Install-Module CredentialManager -Scope CurrentUser
241
+
242
+ $cred = Get-Credential -UserName confluence-prod -Message "Enter Confluence PAT as password"
243
+ New-StoredCredential -Target "conjira-cli/confluence-prod" -UserName $cred.UserName -Password $cred.GetNetworkCredential().Password -Persist LocalMachine
244
+ Remove-Variable cred
245
+
246
+ $cred = Get-Credential -UserName jira-prod -Message "Enter Jira PAT as password"
247
+ New-StoredCredential -Target "conjira-cli/jira-prod" -UserName $cred.UserName -Password $cred.GetNetworkCredential().Password -Persist LocalMachine
248
+ Remove-Variable cred
249
+ ```
250
+
251
+ Before running the CLI in a new PowerShell session, read those credentials into environment variables. The values only live in that session:
252
+
253
+ ```powershell
254
+ $env:CONFLUENCE_PAT = (Get-StoredCredential -Target "conjira-cli/confluence-prod").GetNetworkCredential().Password
255
+ $env:JIRA_PAT = (Get-StoredCredential -Target "conjira-cli/jira-prod").GetNetworkCredential().Password
256
+
257
+ conjira --env-file .\local\agent.env auth-check
258
+ conjira --env-file .\local\agent.env jira-auth-check
259
+ ```
260
+
261
+ If Windows Credential Manager is unavailable, or on Linux, use environment variables or token files instead. For example:
235
262
 
236
263
  ```dotenv
237
264
  CONFLUENCE_BASE_URL=https://confluence.example.com
@@ -289,6 +316,12 @@ Export grouped inline comment threads:
289
316
  conjira --env-file ./local/agent.env export-inline-comments-md --page-id 123456 --status open --output-dir "/path/to/work-folder"
290
317
  ```
291
318
 
319
+ Read page footer comments and replies:
320
+
321
+ ```bash
322
+ conjira --env-file ./local/agent.env get-footer-comments --page-id 123456
323
+ ```
324
+
292
325
  Create or update a Confluence page:
293
326
 
294
327
  ```bash
@@ -384,6 +417,17 @@ Jira settings:
384
417
  - `JIRA_ALLOWED_PROJECT_KEYS`
385
418
  - `JIRA_ALLOWED_ISSUE_KEYS`
386
419
 
420
+ Shared rate-limit settings:
421
+
422
+ - `CONJIRA_RATE_LIMIT_ENABLED`: set to `false` to disable client-side throttling
423
+ - `CONJIRA_RATE_LIMIT_RPS`: default `4.0`
424
+ - `CONJIRA_RATE_LIMIT_BURST`: default `8`
425
+ - `CONJIRA_MAX_RETRIES`: default `5` retries after the first failed request
426
+ - `CONJIRA_RETRY_BASE_SECONDS`: default `1.0`
427
+ - `CONJIRA_RETRY_MAX_SECONDS`: default `30.0`
428
+
429
+ Product-specific overrides such as `CONFLUENCE_RATE_LIMIT_RPS` and `JIRA_RATE_LIMIT_RPS` take precedence over the shared `CONJIRA_*` values. The throttle state is shared across local CLI processes for the same product, base URL, and token, so separate agent calls are paced together.
430
+
387
431
  ## Safety model
388
432
 
389
433
  This CLI intentionally does not implement delete commands for Confluence pages or Jira issues.
@@ -400,7 +444,8 @@ When the CLI hits a common API failure, it now returns a `guidance` field alongs
400
444
  - `403`: check product permissions and any configured allowlists
401
445
  - `404`: check the page ID, issue key, or target path and confirm the PAT owner can see it in the web UI
402
446
  - `409`: refresh live content and retry, especially for Confluence updates after concurrent edits
403
- - `429` and `5xx`: retry after a short delay and reduce request volume if you are looping
447
+ - `429`: the CLI automatically retries with backoff and honors `Retry-After` when the server sends it
448
+ - `5xx`: retry after a short delay and reduce request volume if you are looping
404
449
 
405
450
  ## Export strategy
406
451
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "conjira-cli"
7
- version = "0.2.5"
7
+ version = "0.2.6"
8
8
  description = "Unofficial agent-friendly CLI for self-hosted Confluence and Jira"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,3 +1,3 @@
1
1
  __all__ = ["__version__"]
2
2
 
3
- __version__ = "0.2.4"
3
+ __version__ = "0.2.6"
@@ -49,6 +49,12 @@ def _read_text_arg(raw_text: Optional[str], file_path: Optional[str]) -> str:
49
49
  return ""
50
50
 
51
51
 
52
+ def _normalize_id(value: str) -> str:
53
+ # Strip whitespace and trailing slashes so URL-derived IDs like
54
+ # "1025003939/" (from a pasted Confluence URL) don't break path joins.
55
+ return value.strip().strip("/")
56
+
57
+
52
58
  def _read_json_arg(raw_json: Optional[str], file_path: Optional[str]) -> Dict[str, Any]:
53
59
  if raw_json is not None:
54
60
  return json.loads(raw_json)
@@ -303,14 +309,14 @@ def _build_parser() -> argparse.ArgumentParser:
303
309
  subparsers.add_parser("auth-check", help="Validate Confluence base URL and PAT")
304
310
 
305
311
  get_page = subparsers.add_parser("get-page", help="Fetch a Confluence page by ID")
306
- get_page.add_argument("--page-id", required=True)
312
+ get_page.add_argument("--page-id", required=True, type=_normalize_id)
307
313
  get_page.add_argument("--expand")
308
314
 
309
315
  export_page_md = subparsers.add_parser(
310
316
  "export-page-md",
311
317
  help="Export a Confluence page to a Markdown file",
312
318
  )
313
- export_page_md.add_argument("--page-id", required=True)
319
+ export_page_md.add_argument("--page-id", required=True, type=_normalize_id)
314
320
  export_page_md.add_argument("--output-file")
315
321
  export_page_md.add_argument("--output-dir")
316
322
  export_page_md.add_argument("--filename")
@@ -320,7 +326,7 @@ def _build_parser() -> argparse.ArgumentParser:
320
326
  "export-tree-md",
321
327
  help="Export a Confluence page tree to nested Markdown folders",
322
328
  )
323
- export_tree_md.add_argument("--page-id", required=True)
329
+ export_tree_md.add_argument("--page-id", required=True, type=_normalize_id)
324
330
  export_tree_md.add_argument("--output-dir")
325
331
  export_tree_md.add_argument("--staging-local", action="store_true")
326
332
 
@@ -340,7 +346,7 @@ def _build_parser() -> argparse.ArgumentParser:
340
346
  "get-inline-comments",
341
347
  help="Fetch Confluence inline comments and group them into threads",
342
348
  )
343
- get_inline_comments.add_argument("--page-id", required=True)
349
+ get_inline_comments.add_argument("--page-id", required=True, type=_normalize_id)
344
350
  get_inline_comments.add_argument("--limit", type=int, default=200)
345
351
  get_inline_comments.add_argument(
346
352
  "--status",
@@ -348,11 +354,19 @@ def _build_parser() -> argparse.ArgumentParser:
348
354
  default="all",
349
355
  )
350
356
 
357
+ get_footer_comments = subparsers.add_parser(
358
+ "get-footer-comments",
359
+ aliases=["get-page-comments"],
360
+ help="Fetch Confluence page footer comments, including replies",
361
+ )
362
+ get_footer_comments.add_argument("--page-id", required=True)
363
+ get_footer_comments.add_argument("--limit", type=int, default=200)
364
+
351
365
  export_inline_comments_md = subparsers.add_parser(
352
366
  "export-inline-comments-md",
353
367
  help="Export grouped Confluence inline comments to a Markdown file",
354
368
  )
355
- export_inline_comments_md.add_argument("--page-id", required=True)
369
+ export_inline_comments_md.add_argument("--page-id", required=True, type=_normalize_id)
356
370
  export_inline_comments_md.add_argument("--limit", type=int, default=200)
357
371
  export_inline_comments_md.add_argument(
358
372
  "--status",
@@ -377,7 +391,7 @@ def _build_parser() -> argparse.ArgumentParser:
377
391
  create_page_body_group.add_argument("--body-markdown-file")
378
392
 
379
393
  update_page = subparsers.add_parser("update-page", help="Update an existing Confluence page")
380
- update_page.add_argument("--page-id", required=True)
394
+ update_page.add_argument("--page-id", required=True, type=_normalize_id)
381
395
  update_page.add_argument("--allow-write", action="store_true")
382
396
  update_page.add_argument("--dry-run", action="store_true")
383
397
  update_page.add_argument("--title")
@@ -396,7 +410,7 @@ def _build_parser() -> argparse.ArgumentParser:
396
410
  "replace-section",
397
411
  help="Replace the content under a specific Confluence heading",
398
412
  )
399
- replace_section.add_argument("--page-id", required=True)
413
+ replace_section.add_argument("--page-id", required=True, type=_normalize_id)
400
414
  replace_section.add_argument("--heading", required=True)
401
415
  replace_section.add_argument("--allow-write", action="store_true")
402
416
  replace_section.add_argument("--dry-run", action="store_true")
@@ -410,7 +424,7 @@ def _build_parser() -> argparse.ArgumentParser:
410
424
  "insert-after-heading",
411
425
  help="Insert content immediately after a specific Confluence heading",
412
426
  )
413
- insert_after_heading.add_argument("--page-id", required=True)
427
+ insert_after_heading.add_argument("--page-id", required=True, type=_normalize_id)
414
428
  insert_after_heading.add_argument("--heading", required=True)
415
429
  insert_after_heading.add_argument("--allow-write", action="store_true")
416
430
  insert_after_heading.add_argument("--dry-run", action="store_true")
@@ -426,7 +440,7 @@ def _build_parser() -> argparse.ArgumentParser:
426
440
  "move-page",
427
441
  help="Move an existing Confluence page under a different parent page",
428
442
  )
429
- move_page.add_argument("--page-id", required=True)
443
+ move_page.add_argument("--page-id", required=True, type=_normalize_id)
430
444
  move_page.add_argument("--new-parent-id", required=True)
431
445
  move_page.add_argument("--allow-write", action="store_true")
432
446
  move_page.add_argument("--dry-run", action="store_true")
@@ -435,7 +449,7 @@ def _build_parser() -> argparse.ArgumentParser:
435
449
  "upload-attachment",
436
450
  help="Upload or update a Confluence attachment on a page",
437
451
  )
438
- upload_attachment.add_argument("--page-id", required=True)
452
+ upload_attachment.add_argument("--page-id", required=True, type=_normalize_id)
439
453
  upload_attachment.add_argument("--file", required=True)
440
454
  upload_attachment.add_argument("--comment")
441
455
  upload_attachment.add_argument("--allow-write", action="store_true")
@@ -451,7 +465,7 @@ def _build_parser() -> argparse.ArgumentParser:
451
465
  subparsers.add_parser("jira-auth-check", help="Validate Jira base URL and PAT")
452
466
 
453
467
  jira_get_issue = subparsers.add_parser("jira-get-issue", help="Fetch a Jira issue by key")
454
- jira_get_issue.add_argument("--issue-key", required=True)
468
+ jira_get_issue.add_argument("--issue-key", required=True, type=_normalize_id)
455
469
  jira_get_issue.add_argument("--fields")
456
470
  jira_get_issue.add_argument("--expand")
457
471
  jira_get_issue.add_argument("--include-comments", action="store_true")
@@ -488,7 +502,7 @@ def _build_parser() -> argparse.ArgumentParser:
488
502
  jira_create_issue_fields_group.add_argument("--fields-file")
489
503
 
490
504
  jira_add_comment = subparsers.add_parser("jira-add-comment", help="Add a Jira issue comment")
491
- jira_add_comment.add_argument("--issue-key", required=True)
505
+ jira_add_comment.add_argument("--issue-key", required=True, type=_normalize_id)
492
506
  jira_add_comment.add_argument("--allow-write", action="store_true")
493
507
  jira_add_comment.add_argument("--dry-run", action="store_true")
494
508
  jira_comment_group = jira_add_comment.add_mutually_exclusive_group(required=True)
@@ -923,6 +937,12 @@ def _handle_confluence(args: argparse.Namespace) -> Dict[str, Any]:
923
937
  base_url=settings.base_url,
924
938
  token=settings.token,
925
939
  timeout_seconds=settings.timeout_seconds,
940
+ rate_limit_enabled=settings.rate_limit_enabled,
941
+ rate_limit_rps=settings.rate_limit_rps,
942
+ rate_limit_burst=settings.rate_limit_burst,
943
+ max_retries=settings.max_retries,
944
+ retry_base_seconds=settings.retry_base_seconds,
945
+ retry_max_seconds=settings.retry_max_seconds,
926
946
  )
927
947
 
928
948
  if args.command == "auth-check":
@@ -1074,6 +1094,16 @@ def _handle_confluence(args: argparse.Namespace) -> Dict[str, Any]:
1074
1094
  comments=comments,
1075
1095
  status_filter=args.status,
1076
1096
  )
1097
+ if args.command in {"get-footer-comments", "get-page-comments"}:
1098
+ page = client.get_page(args.page_id, expand="version,space")
1099
+ comments = client.list_footer_comments(
1100
+ args.page_id,
1101
+ limit=args.limit,
1102
+ )
1103
+ return client.summarize_footer_comments(
1104
+ page=page,
1105
+ comments=comments,
1106
+ )
1077
1107
  if args.command == "export-inline-comments-md":
1078
1108
  page = client.get_page(args.page_id, expand="version,space")
1079
1109
  comments = client.list_inline_comments(
@@ -1376,6 +1406,12 @@ def _handle_jira(args: argparse.Namespace) -> Dict[str, Any]:
1376
1406
  base_url=settings.base_url,
1377
1407
  token=settings.token,
1378
1408
  timeout_seconds=settings.timeout_seconds,
1409
+ rate_limit_enabled=settings.rate_limit_enabled,
1410
+ rate_limit_rps=settings.rate_limit_rps,
1411
+ rate_limit_burst=settings.rate_limit_burst,
1412
+ max_retries=settings.max_retries,
1413
+ retry_base_seconds=settings.retry_base_seconds,
1414
+ retry_max_seconds=settings.retry_max_seconds,
1379
1415
  )
1380
1416
 
1381
1417
  if args.command == "jira-auth-check":