querysource 4.1.9__tar.gz → 4.1.10__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 (397) hide show
  1. querysource-4.1.10/.claude/commands/pr-review.md +480 -0
  2. {querysource-4.1.9 → querysource-4.1.10}/.claude/commands/sdd-brainstorm.md +4 -0
  3. {querysource-4.1.9 → querysource-4.1.10}/.claude/commands/sdd-done.md +118 -5
  4. querysource-4.1.10/.claude/commands/sdd-fromjira.md +335 -0
  5. querysource-4.1.10/.claude/commands/sdd-tojira.md +423 -0
  6. {querysource-4.1.9 → querysource-4.1.10}/PKG-INFO +2 -2
  7. {querysource-4.1.9 → querysource-4.1.10}/pyproject.toml +1 -1
  8. {querysource-4.1.9 → querysource-4.1.10}/querysource/_version.py +3 -3
  9. {querysource-4.1.9 → querysource-4.1.10}/querysource/version.py +1 -1
  10. {querysource-4.1.9 → querysource-4.1.10}/querysource.egg-info/PKG-INFO +2 -2
  11. {querysource-4.1.9 → querysource-4.1.10}/querysource.egg-info/SOURCES.txt +3 -0
  12. {querysource-4.1.9 → querysource-4.1.10}/querysource.egg-info/requires.txt +1 -1
  13. {querysource-4.1.9 → querysource-4.1.10}/.bumpversion.cfg +0 -0
  14. {querysource-4.1.9 → querysource-4.1.10}/.claude/agents/code-reviewer.md +0 -0
  15. {querysource-4.1.9 → querysource-4.1.10}/.claude/agents/sdd-worker.md +0 -0
  16. {querysource-4.1.9 → querysource-4.1.10}/.claude/commands/sdd-codereview.md +0 -0
  17. {querysource-4.1.9 → querysource-4.1.10}/.claude/commands/sdd-next.md +0 -0
  18. {querysource-4.1.9 → querysource-4.1.10}/.claude/commands/sdd-proposal.md +0 -0
  19. {querysource-4.1.9 → querysource-4.1.10}/.claude/commands/sdd-spec.md +0 -0
  20. {querysource-4.1.9 → querysource-4.1.10}/.claude/commands/sdd-start.md +0 -0
  21. {querysource-4.1.9 → querysource-4.1.10}/.claude/commands/sdd-status.md +0 -0
  22. {querysource-4.1.9 → querysource-4.1.10}/.claude/commands/sdd-task.md +0 -0
  23. {querysource-4.1.9 → querysource-4.1.10}/.claude/rules/aws-cost-optimization.md +0 -0
  24. {querysource-4.1.9 → querysource-4.1.10}/.claude/rules/code-reviewer.md +0 -0
  25. {querysource-4.1.9 → querysource-4.1.10}/.claude/rules/cython-development.md +0 -0
  26. {querysource-4.1.9 → querysource-4.1.10}/.claude/rules/python-development.md +0 -0
  27. {querysource-4.1.9 → querysource-4.1.10}/.claude/rules/rust-development.md +0 -0
  28. {querysource-4.1.9 → querysource-4.1.10}/.claude/rules/using-git-worktrees.md +0 -0
  29. {querysource-4.1.9 → querysource-4.1.10}/.claude/rules/worktree-pr-and-clean.md +0 -0
  30. {querysource-4.1.9 → querysource-4.1.10}/.claude/rules/worktree-start-feature.md +0 -0
  31. {querysource-4.1.9 → querysource-4.1.10}/.claude/rules/worktree-status.md +0 -0
  32. {querysource-4.1.9 → querysource-4.1.10}/.github/dependabot.yml +0 -0
  33. {querysource-4.1.9 → querysource-4.1.10}/.github/workflows/codeql-analysis.yml +0 -0
  34. {querysource-4.1.9 → querysource-4.1.10}/.github/workflows/release.yml +0 -0
  35. {querysource-4.1.9 → querysource-4.1.10}/.isort.cfg +0 -0
  36. {querysource-4.1.9 → querysource-4.1.10}/.jupyter/jupyter_notebook_config.py +0 -0
  37. {querysource-4.1.9 → querysource-4.1.10}/.pylintrc +0 -0
  38. {querysource-4.1.9 → querysource-4.1.10}/CHANGES.rst +0 -0
  39. {querysource-4.1.9 → querysource-4.1.10}/CODE_OF_CONDUCT.md +0 -0
  40. {querysource-4.1.9 → querysource-4.1.10}/CONTRIBUTING.md +0 -0
  41. {querysource-4.1.9 → querysource-4.1.10}/INSTALL +0 -0
  42. {querysource-4.1.9 → querysource-4.1.10}/LICENSE +0 -0
  43. {querysource-4.1.9 → querysource-4.1.10}/MANIFEST.in +0 -0
  44. {querysource-4.1.9 → querysource-4.1.10}/Makefile +0 -0
  45. {querysource-4.1.9 → querysource-4.1.10}/README.md +0 -0
  46. {querysource-4.1.9 → querysource-4.1.10}/app.py +0 -0
  47. {querysource-4.1.9 → querysource-4.1.10}/bin/README.md +0 -0
  48. {querysource-4.1.9 → querysource-4.1.10}/gunicorn_config.py +0 -0
  49. {querysource-4.1.9 → querysource-4.1.10}/mypy.ini +0 -0
  50. {querysource-4.1.9 → querysource-4.1.10}/nav.py +0 -0
  51. {querysource-4.1.9 → querysource-4.1.10}/pytest.ini +0 -0
  52. {querysource-4.1.9 → querysource-4.1.10}/querysource/__cli__.py +0 -0
  53. {querysource-4.1.9 → querysource-4.1.10}/querysource/__init__.py +0 -0
  54. {querysource-4.1.9 → querysource-4.1.10}/querysource/cache/__init__.py +0 -0
  55. {querysource-4.1.9 → querysource-4.1.10}/querysource/cache/backends/__init__.py +0 -0
  56. {querysource-4.1.9 → querysource-4.1.10}/querysource/cache/backends/abstract.py +0 -0
  57. {querysource-4.1.9 → querysource-4.1.10}/querysource/cache/backends/memcache.py +0 -0
  58. {querysource-4.1.9 → querysource-4.1.10}/querysource/cache/backends/redis.py +0 -0
  59. {querysource-4.1.9 → querysource-4.1.10}/querysource/cache/base.py +0 -0
  60. {querysource-4.1.9 → querysource-4.1.10}/querysource/conf.py +0 -0
  61. {querysource-4.1.9 → querysource-4.1.10}/querysource/connections.py +0 -0
  62. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/__init__.py +0 -0
  63. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/__init__.py +0 -0
  64. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/abstract.py +0 -0
  65. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/arangodb.py +0 -0
  66. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/athena.py +0 -0
  67. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/bigquery.py +0 -0
  68. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/cassandra.py +0 -0
  69. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/clickhouse.py +0 -0
  70. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/cockroachdb.py +0 -0
  71. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/couchbase.py +0 -0
  72. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/couchdb.py +0 -0
  73. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/countries.py +0 -0
  74. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/delta.py +0 -0
  75. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/documentdb.py +0 -0
  76. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/dynamodb.py +0 -0
  77. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/elastic.py +0 -0
  78. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/ga.py +0 -0
  79. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/gcalc.py +0 -0
  80. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/hazel.py +0 -0
  81. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/iceberg.py +0 -0
  82. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/influx.py +0 -0
  83. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/jdbc.py +0 -0
  84. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/jira.py +0 -0
  85. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/mariadb.py +0 -0
  86. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/memcached.py +0 -0
  87. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/mongo.py +0 -0
  88. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/mysql.py +0 -0
  89. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/odbc.py +0 -0
  90. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/openweather.py +0 -0
  91. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/oracle.py +0 -0
  92. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/pg.py +0 -0
  93. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/postgres.py +0 -0
  94. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/py.typed +0 -0
  95. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/qs.py +0 -0
  96. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/redis.py +0 -0
  97. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/rest.py +0 -0
  98. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/rethink.py +0 -0
  99. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/sa.py +0 -0
  100. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/salesforce.py +0 -0
  101. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/scylladb.py +0 -0
  102. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/sqlalchemy.py +0 -0
  103. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/sqlite.py +0 -0
  104. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/sqlserver.py +0 -0
  105. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/upc.py +0 -0
  106. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/drivers/zipcodeapi.py +0 -0
  107. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/handlers/__init__.py +0 -0
  108. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/handlers/datasource.py +0 -0
  109. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/handlers/utils.py +0 -0
  110. {querysource-4.1.9 → querysource-4.1.10}/querysource/datasources/models.py +0 -0
  111. {querysource-4.1.9 → querysource-4.1.10}/querysource/events/__init__.py +0 -0
  112. {querysource-4.1.9 → querysource-4.1.10}/querysource/exceptions.py +0 -0
  113. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/__init__.py +0 -0
  114. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/abstract.py +0 -0
  115. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/executor.py +0 -0
  116. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/log.py +0 -0
  117. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/manager.py +0 -0
  118. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/multi.py +0 -0
  119. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/outputs/__init__.py +0 -0
  120. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/outputs/tableOutput/__init__.py +0 -0
  121. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/outputs/tableOutput/postgres.py +0 -0
  122. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/outputs/tableOutput/table.py +0 -0
  123. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/service.py +0 -0
  124. {querysource-4.1.9 → querysource-4.1.10}/querysource/handlers/variables.py +0 -0
  125. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/__init__.py +0 -0
  126. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/connections.py +0 -0
  127. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/credentials.py +0 -0
  128. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/databases/__init__.py +0 -0
  129. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/databases/abstract.py +0 -0
  130. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/databases/bigquery.py +0 -0
  131. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/databases/db.py +0 -0
  132. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/databases/mongo.py +0 -0
  133. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/databases/rethink.py +0 -0
  134. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/http.py +0 -0
  135. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/playwright_service.py +0 -0
  136. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/queries.py +0 -0
  137. {querysource-4.1.9 → querysource-4.1.10}/querysource/interfaces/selenium_service.py +0 -0
  138. {querysource-4.1.9 → querysource-4.1.10}/querysource/libs/__init__.py +0 -0
  139. {querysource-4.1.9 → querysource-4.1.10}/querysource/libs/encoders.py +0 -0
  140. {querysource-4.1.9 → querysource-4.1.10}/querysource/libs/functions/__init__.py +0 -0
  141. {querysource-4.1.9 → querysource-4.1.10}/querysource/libs/py.typed +0 -0
  142. {querysource-4.1.9 → querysource-4.1.10}/querysource/models.py +0 -0
  143. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/__init__.py +0 -0
  144. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/dt/__init__.py +0 -0
  145. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/dt/abstract.py +0 -0
  146. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/dt/arrow.py +0 -0
  147. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/dt/dt.py +0 -0
  148. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/dt/factory.py +0 -0
  149. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/dt/iter.py +0 -0
  150. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/dt/modin.py +0 -0
  151. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/dt/pandas.py +0 -0
  152. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/dt/polars.py +0 -0
  153. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/output.py +0 -0
  154. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/__init__.py +0 -0
  155. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/abstract.py +0 -0
  156. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/bigquery.py +0 -0
  157. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/documentdb.py +0 -0
  158. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/mongodb.py +0 -0
  159. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/mysql.py +0 -0
  160. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/postgres.py +0 -0
  161. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/rethink.py +0 -0
  162. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/sa.py +0 -0
  163. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/TableOutput/table.py +0 -0
  164. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/tables/__init__.py +0 -0
  165. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/__init__.py +0 -0
  166. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/abstract.py +0 -0
  167. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/bokeh.py +0 -0
  168. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/clustering.py +0 -0
  169. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/csv.py +0 -0
  170. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/describe.py +0 -0
  171. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/eda.py +0 -0
  172. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/excel.py +0 -0
  173. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/html.py +0 -0
  174. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/json.py +0 -0
  175. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/pdf.py +0 -0
  176. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/pickle.py +0 -0
  177. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/plotly.py +0 -0
  178. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/profiling.py +0 -0
  179. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/report.py +0 -0
  180. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/table.py +0 -0
  181. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/tsv.py +0 -0
  182. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/txt.py +0 -0
  183. {querysource-4.1.9 → querysource-4.1.10}/querysource/outputs/writers/xml.py +0 -0
  184. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/__init__.py +0 -0
  185. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/abstract.c +0 -0
  186. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/abstract.pxd +0 -0
  187. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/abstract.pyx +0 -0
  188. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/arangodb.c +0 -0
  189. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/arangodb.pxd +0 -0
  190. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/arangodb.pyx +0 -0
  191. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/bigquery.c +0 -0
  192. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/bigquery.pxd +0 -0
  193. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/bigquery.pyx +0 -0
  194. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/cql.c +0 -0
  195. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/cql.pxd +0 -0
  196. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/cql.pyx +0 -0
  197. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/deltatbl.c +0 -0
  198. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/deltatbl.pxd +0 -0
  199. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/deltatbl.pyx +0 -0
  200. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/elastic.cpp +0 -0
  201. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/elastic.pxd +0 -0
  202. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/elastic.pyx +0 -0
  203. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/iceberg.c +0 -0
  204. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/iceberg.pxd +0 -0
  205. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/iceberg.pyx +0 -0
  206. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/influx.c +0 -0
  207. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/influx.pxd +0 -0
  208. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/influx.pyx +0 -0
  209. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/mongo.cpp +0 -0
  210. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/mongo.pxd +0 -0
  211. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/mongo.pyx +0 -0
  212. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/parser.c +0 -0
  213. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/parser.pxd +0 -0
  214. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/parser.pyx +0 -0
  215. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/pgsql.c +0 -0
  216. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/pgsql.pxd +0 -0
  217. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/pgsql.pyx +0 -0
  218. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/rethink.c +0 -0
  219. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/rethink.pxd +0 -0
  220. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/rethink.pyx +0 -0
  221. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/sosql.c +0 -0
  222. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/sosql.pxd +0 -0
  223. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/sosql.pyx +0 -0
  224. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/sql.c +0 -0
  225. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/sql.pxd +0 -0
  226. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/sql.pyx +0 -0
  227. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/sqlserver.c +0 -0
  228. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/sqlserver.pxd +0 -0
  229. {querysource-4.1.9 → querysource-4.1.10}/querysource/parsers/sqlserver.pyx +0 -0
  230. {querysource-4.1.9 → querysource-4.1.10}/querysource/plugins/__init__.py +0 -0
  231. {querysource-4.1.9 → querysource-4.1.10}/querysource/plugins/importer.py +0 -0
  232. {querysource-4.1.9 → querysource-4.1.10}/querysource/plugins/sources/__init__.py +0 -0
  233. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/__init__.py +0 -0
  234. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/abstract.py +0 -0
  235. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/arangodb.py +0 -0
  236. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/bigquery.py +0 -0
  237. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/cassandra.py +0 -0
  238. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/db.py +0 -0
  239. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/default.py +0 -0
  240. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/deltatbl.py +0 -0
  241. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/documentdb.py +0 -0
  242. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/dummy.py +0 -0
  243. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/elastic.py +0 -0
  244. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/external.py +0 -0
  245. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/http.py +0 -0
  246. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/iceberg.py +0 -0
  247. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/influx.py +0 -0
  248. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/mysql.py +0 -0
  249. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/pg.py +0 -0
  250. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/py.typed +0 -0
  251. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/rest.py +0 -0
  252. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/rethink.py +0 -0
  253. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/salesforce.py +0 -0
  254. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/scylladb.py +0 -0
  255. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/__init__.py +0 -0
  256. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/abstract.py +0 -0
  257. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/amazon.py +0 -0
  258. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/countries.py +0 -0
  259. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/ga.py +0 -0
  260. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/geofcc.py +0 -0
  261. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/gmaps.py +0 -0
  262. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/graphcountries.py +0 -0
  263. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/graphql.py +0 -0
  264. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/http.py +0 -0
  265. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/hubspot.py +0 -0
  266. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/openweather.py +0 -0
  267. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/parsers/__init__.py +0 -0
  268. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/parsers/amproduct.py +0 -0
  269. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/parsers/xpath.py +0 -0
  270. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/pokemon.py +0 -0
  271. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/populartimes.py +0 -0
  272. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/py.typed +0 -0
  273. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/rest.py +0 -0
  274. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/retailnext.py +0 -0
  275. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/rssapp.py +0 -0
  276. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/salesforce.py +0 -0
  277. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/scrapper.py +0 -0
  278. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/shoppertrack.py +0 -0
  279. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/swop.py +0 -0
  280. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/uap.py +0 -0
  281. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/upc.py +0 -0
  282. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/wm_stores.py +0 -0
  283. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/zammad.py +0 -0
  284. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sources/zipcodeapi.py +0 -0
  285. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sql.py +0 -0
  286. {querysource-4.1.9 → querysource-4.1.10}/querysource/providers/sqlserver.py +0 -0
  287. {querysource-4.1.9 → querysource-4.1.10}/querysource/py.typed +0 -0
  288. {querysource-4.1.9 → querysource-4.1.10}/querysource/qs_parsers/__init__.py +0 -0
  289. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/__init__.py +0 -0
  290. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/base.py +0 -0
  291. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/executor.py +0 -0
  292. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/models.py +0 -0
  293. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/__init__.py +0 -0
  294. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/components/__init__.py +0 -0
  295. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/Concat.py +0 -0
  296. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/GroupBy.py +0 -0
  297. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/Info.py +0 -0
  298. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/Join.py +0 -0
  299. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/Melt.py +0 -0
  300. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/Merge.py +0 -0
  301. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/__init__.py +0 -0
  302. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/abstract.py +0 -0
  303. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/filter/__init__.py +0 -0
  304. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/operators/filter/flt.py +0 -0
  305. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/sources/__init__.py +0 -0
  306. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/sources/file.py +0 -0
  307. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/sources/query.py +0 -0
  308. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/Forecast.py +0 -0
  309. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/Map.py +0 -0
  310. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/__init__.py +0 -0
  311. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/abstract.py +0 -0
  312. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/correlation.py +0 -0
  313. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/crosstab.py +0 -0
  314. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/google/__init__.py +0 -0
  315. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/google/maps.py +0 -0
  316. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/pivot.py +0 -0
  317. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/tOrder.py +0 -0
  318. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/multi/transformations/tPandas.py +0 -0
  319. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/obj.py +0 -0
  320. {querysource-4.1.9 → querysource-4.1.10}/querysource/queries/qs.py +0 -0
  321. {querysource-4.1.9 → querysource-4.1.10}/querysource/scheduler/__init__.py +0 -0
  322. {querysource-4.1.9 → querysource-4.1.10}/querysource/scheduler/jobs.py +0 -0
  323. {querysource-4.1.9 → querysource-4.1.10}/querysource/scheduler/notifications.py +0 -0
  324. {querysource-4.1.9 → querysource-4.1.10}/querysource/scheduler/scheduler.py +0 -0
  325. {querysource-4.1.9 → querysource-4.1.10}/querysource/services.py +0 -0
  326. {querysource-4.1.9 → querysource-4.1.10}/querysource/template/__init__.py +0 -0
  327. {querysource-4.1.9 → querysource-4.1.10}/querysource/template/parser.py +0 -0
  328. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/__init__.py +0 -0
  329. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/converters.cpp +0 -0
  330. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/converters.pyx +0 -0
  331. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/dt/__init__.py +0 -0
  332. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/dt/filters.py +0 -0
  333. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/dt/transforms.py +0 -0
  334. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/py.typed +0 -0
  335. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/typedefs.c +0 -0
  336. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/typedefs.pyx +0 -0
  337. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/validators.cpp +0 -0
  338. {querysource-4.1.9 → querysource-4.1.10}/querysource/types/validators.pyx +0 -0
  339. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/__init__.py +0 -0
  340. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/cache_serialization.py +0 -0
  341. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/events.py +0 -0
  342. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/fn.py +0 -0
  343. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/functions.cpp +0 -0
  344. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/functions.pyx +0 -0
  345. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/getfunc.py +0 -0
  346. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/handlers.py +0 -0
  347. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/parseqs.cpp +0 -0
  348. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/parseqs.pyx +0 -0
  349. {querysource-4.1.9 → querysource-4.1.10}/querysource/utils/validators.py +0 -0
  350. {querysource-4.1.9 → querysource-4.1.10}/querysource.egg-info/dependency_links.txt +0 -0
  351. {querysource-4.1.9 → querysource-4.1.10}/querysource.egg-info/entry_points.txt +0 -0
  352. {querysource-4.1.9 → querysource-4.1.10}/querysource.egg-info/not-zip-safe +0 -0
  353. {querysource-4.1.9 → querysource-4.1.10}/querysource.egg-info/top_level.txt +0 -0
  354. {querysource-4.1.9 → querysource-4.1.10}/run.py +0 -0
  355. {querysource-4.1.9 → querysource-4.1.10}/rust/Cargo.lock +0 -0
  356. {querysource-4.1.9 → querysource-4.1.10}/rust/Cargo.toml +0 -0
  357. {querysource-4.1.9 → querysource-4.1.10}/rust/pyproject.toml +0 -0
  358. {querysource-4.1.9 → querysource-4.1.10}/rust/src/arangodb_parser.rs +0 -0
  359. {querysource-4.1.9 → querysource-4.1.10}/rust/src/bigquery_parser.rs +0 -0
  360. {querysource-4.1.9 → querysource-4.1.10}/rust/src/cql_parser.rs +0 -0
  361. {querysource-4.1.9 → querysource-4.1.10}/rust/src/elastic_parser.rs +0 -0
  362. {querysource-4.1.9 → querysource-4.1.10}/rust/src/filter_common.rs +0 -0
  363. {querysource-4.1.9 → querysource-4.1.10}/rust/src/flux_parser.rs +0 -0
  364. {querysource-4.1.9 → querysource-4.1.10}/rust/src/lib.rs +0 -0
  365. {querysource-4.1.9 → querysource-4.1.10}/rust/src/mongo_parser.rs +0 -0
  366. {querysource-4.1.9 → querysource-4.1.10}/rust/src/mssql_parser.rs +0 -0
  367. {querysource-4.1.9 → querysource-4.1.10}/rust/src/parseqs.rs +0 -0
  368. {querysource-4.1.9 → querysource-4.1.10}/rust/src/pgsql_parser.rs +0 -0
  369. {querysource-4.1.9 → querysource-4.1.10}/rust/src/rethink_parser.rs +0 -0
  370. {querysource-4.1.9 → querysource-4.1.10}/rust/src/safe_dict.rs +0 -0
  371. {querysource-4.1.9 → querysource-4.1.10}/rust/src/soql_parser.rs +0 -0
  372. {querysource-4.1.9 → querysource-4.1.10}/rust/src/sql_parser.rs +0 -0
  373. {querysource-4.1.9 → querysource-4.1.10}/rust/src/validators.rs +0 -0
  374. {querysource-4.1.9 → querysource-4.1.10}/setup.cfg +0 -0
  375. {querysource-4.1.9 → querysource-4.1.10}/setup.py +0 -0
  376. {querysource-4.1.9 → querysource-4.1.10}/static/notebook/bundle.js +0 -0
  377. {querysource-4.1.9 → querysource-4.1.10}/templates/__init__.py +0 -0
  378. {querysource-4.1.9 → querysource-4.1.10}/templates/base.html +0 -0
  379. {querysource-4.1.9 → querysource-4.1.10}/templates/default.html +0 -0
  380. {querysource-4.1.9 → querysource-4.1.10}/templates/default_table.html +0 -0
  381. {querysource-4.1.9 → querysource-4.1.10}/templates/fontlist-v330.json +0 -0
  382. {querysource-4.1.9 → querysource-4.1.10}/templates/fontlist-v390.json +0 -0
  383. {querysource-4.1.9 → querysource-4.1.10}/templates/table_charts.html +0 -0
  384. {querysource-4.1.9 → querysource-4.1.10}/tests/test_api.py +0 -0
  385. {querysource-4.1.9 → querysource-4.1.10}/tests/test_arangodb_parser.py +0 -0
  386. {querysource-4.1.9 → querysource-4.1.10}/tests/test_column_filters.py +0 -0
  387. {querysource-4.1.9 → querysource-4.1.10}/tests/test_elastic_parser.py +0 -0
  388. {querysource-4.1.9 → querysource-4.1.10}/tests/test_eval.py +0 -0
  389. {querysource-4.1.9 → querysource-4.1.10}/tests/test_join_conditions.py +0 -0
  390. {querysource-4.1.9 → querysource-4.1.10}/tests/test_join_with_column_filter.py +0 -0
  391. {querysource-4.1.9 → querysource-4.1.10}/tests/test_rss.py +0 -0
  392. {querysource-4.1.9 → querysource-4.1.10}/tests/test_rust_parsers.py +0 -0
  393. {querysource-4.1.9 → querysource-4.1.10}/tests/test_scheduler_core.py +0 -0
  394. {querysource-4.1.9 → querysource-4.1.10}/tests/test_scheduler_integration.py +0 -0
  395. {querysource-4.1.9 → querysource-4.1.10}/tests/test_scheduler_jobs.py +0 -0
  396. {querysource-4.1.9 → querysource-4.1.10}/tests/test_scheduler_notifications.py +0 -0
  397. {querysource-4.1.9 → querysource-4.1.10}/tox.ini +0 -0
@@ -0,0 +1,480 @@
1
+ # /pr-review — Review a PR Against Jira Acceptance Criteria
2
+
3
+ Fetches a GitHub Pull Request and its associated Jira ticket, then reviews
4
+ whether the code changes satisfy the ticket's description and acceptance criteria.
5
+ Optionally converts the PR to draft if criteria are not met.
6
+
7
+ ## Usage
8
+
9
+ ```
10
+ /pr-review <PR_URL> <JIRA_KEY> [--auto-draft]
11
+ ```
12
+
13
+ ### Examples
14
+
15
+ ```
16
+ /pr-review https://github.com/Trocdigital/navigator-dataintegrator-tasks/pull/4028 NAV-8036
17
+ /pr-review https://github.com/Trocdigital/navigator-dataintegrator-tasks/pull/4028 NAV-8036 --auto-draft
18
+ ```
19
+
20
+ ### Arguments
21
+
22
+ | Argument | Required | Description |
23
+ |----------------|----------|-------------|
24
+ | `<PR_URL>` | yes | Full GitHub PR URL (e.g., `https://github.com/org/repo/pull/123`) |
25
+ | `<JIRA_KEY>` | yes | Jira issue key (e.g., `NAV-8036`) |
26
+ | `--auto-draft` | no | If present AND criteria fail, convert PR to draft automatically |
27
+
28
+ ## Prerequisites
29
+
30
+ - `gh` CLI installed and authenticated (`gh auth status`)
31
+ - `jq` installed (for JSON parsing)
32
+ - Jira credentials configured in `env/.env` (loaded at runtime via `navconfig`):
33
+ - `JIRA_INSTANCE` — e.g., `https://trocglobal.atlassian.net/`
34
+ - `JIRA_USERNAME` — email for Jira Cloud
35
+ - `JIRA_API_TOKEN` — API token (Personal Access Token)
36
+
37
+ To load these variables into the current shell for bash commands, run:
38
+ ```bash
39
+ # Quick one-liner to export Jira vars from env/.env
40
+ eval "$(python -c "from navconfig import config; import os; [print(f'export {k}={v}') for k,v in os.environ.items() if k.startswith('JIRA_')]")"
41
+ ```
42
+
43
+ ## Steps
44
+
45
+ ### 1. Parse Input & Validate Prerequisites
46
+
47
+ Extract org, repo, and PR number from the URL:
48
+
49
+ ```bash
50
+ # Parse: https://github.com/Trocdigital/navigator-dataintegrator-tasks/pull/4028
51
+ PR_URL="$1"
52
+ JIRA_KEY="$2"
53
+ AUTO_DRAFT=false
54
+ if [[ "$3" == "--auto-draft" ]]; then AUTO_DRAFT=true; fi
55
+
56
+ # Extract components
57
+ REPO=$(echo "$PR_URL" | sed -E 's|https://github.com/([^/]+/[^/]+)/pull/.*|\1|')
58
+ PR_NUMBER=$(echo "$PR_URL" | sed -E 's|.*/pull/([0-9]+).*|\1|')
59
+
60
+ # Validate
61
+ gh auth status 2>/dev/null || echo "⚠️ gh CLI not authenticated. Run: gh auth login"
62
+ ```
63
+
64
+ Load Jira credentials from `env/.env` via navconfig:
65
+ ```bash
66
+ # Load Jira env vars using navconfig (reads env/.env)
67
+ eval "$(python -c "
68
+ from navconfig import config
69
+ import os
70
+ for k in ('JIRA_INSTANCE', 'JIRA_USERNAME', 'JIRA_API_TOKEN'):
71
+ v = os.environ.get(k, '')
72
+ if v:
73
+ print(f'export {k}={v}')
74
+ ")"
75
+
76
+ # Strip trailing slash from JIRA_INSTANCE to avoid double-slash in URLs
77
+ JIRA_INSTANCE="${JIRA_INSTANCE%/}"
78
+ ```
79
+
80
+ Verify Jira env vars are set:
81
+ ```bash
82
+ [[ -z "$JIRA_INSTANCE" ]] && echo "⚠️ JIRA_INSTANCE not set" && exit 1
83
+ [[ -z "$JIRA_API_TOKEN" ]] && echo "⚠️ JIRA_API_TOKEN not set" && exit 1
84
+ [[ -z "$JIRA_USERNAME" ]] && echo "⚠️ JIRA_USERNAME not set" && exit 1
85
+ ```
86
+
87
+ ### 2. Fetch GitHub PR Data
88
+
89
+ Collect three things from the PR: metadata, description, and the diff.
90
+
91
+ ```bash
92
+ # PR metadata (title, state, author, base/head branches, labels, reviewers)
93
+ gh pr view "$PR_NUMBER" --repo "$REPO" --json title,state,author,baseRefName,headRefName,labels,reviewRequests,isDraft
94
+
95
+ # PR description (body)
96
+ gh pr view "$PR_NUMBER" --repo "$REPO" --json body --jq '.body'
97
+
98
+ # Full diff (the actual code changes)
99
+ gh pr diff "$PR_NUMBER" --repo "$REPO"
100
+
101
+ # List of changed files (for summary context)
102
+ gh pr diff "$PR_NUMBER" --repo "$REPO" --name-only
103
+ ```
104
+
105
+ **Diff size guard**: If the diff exceeds ~8000 lines, switch to a summarized
106
+ approach — fetch only filenames + stats, then selectively read the most relevant
107
+ files based on the Jira ticket context:
108
+
109
+ ```bash
110
+ DIFF_LINES=$(gh pr diff "$PR_NUMBER" --repo "$REPO" | wc -l)
111
+ if [[ "$DIFF_LINES" -gt 8000 ]]; then
112
+ echo "⚠️ Large PR ($DIFF_LINES lines). Fetching file-level stats and sampling key files."
113
+ gh pr diff "$PR_NUMBER" --repo "$REPO" --stat
114
+ # Then selectively: gh api repos/$REPO/pulls/$PR_NUMBER/files --paginate
115
+ # and read only files matching patterns from the Jira ticket
116
+ fi
117
+ ```
118
+
119
+ ### 3. Fetch PR Comments & AI Bot Reviews
120
+
121
+ Collect PR comments, review comments, and reviews to surface findings from
122
+ automated reviewers (Gemini Code Assist, GitHub Copilot, CodeRabbit, etc.).
123
+
124
+ ```bash
125
+ # PR issue-level comments (general discussion)
126
+ gh api repos/$REPO/issues/$PR_NUMBER/comments --paginate \
127
+ --jq '.[] | {author: .user.login, authorType: .author_association, body: .body, created: .created_at}' \
128
+ | head -200
129
+
130
+ # PR review comments (inline on specific lines of code)
131
+ gh api repos/$REPO/pulls/$PR_NUMBER/comments --paginate \
132
+ --jq '.[] | {author: .user.login, path: .path, line: .line, body: .body, created: .created_at}' \
133
+ | head -200
134
+
135
+ # PR reviews (approve/request-changes/comment with body)
136
+ gh api repos/$REPO/pulls/$PR_NUMBER/reviews --paginate \
137
+ --jq '.[] | {author: .user.login, state: .state, body: .body, submitted: .submitted_at}' \
138
+ | head -200
139
+ ```
140
+
141
+ **AI bot detection**: Identify comments from known automated reviewers by
142
+ matching author login patterns:
143
+
144
+ | Bot | Login Pattern |
145
+ |-----|---------------|
146
+ | Gemini Code Assist | `gemini-code-assist[bot]` |
147
+ | GitHub Copilot | `copilot-pull-request-review[bot]`, `github-copilot[bot]` |
148
+ | CodeRabbit | `coderabbitai[bot]` |
149
+ | SonarCloud | `sonarcloud[bot]` |
150
+ | Codacy | `codacy-production[bot]` |
151
+ | Deepsource | `deepsource-autofix[bot]`, `deepsource-io[bot]` |
152
+
153
+ ```bash
154
+ # Filter for known bot authors
155
+ KNOWN_BOTS="gemini-code-assist|copilot-pull-request-review|github-copilot|coderabbitai|sonarcloud|codacy-production|deepsource"
156
+
157
+ # Bot issue comments
158
+ gh api repos/$REPO/issues/$PR_NUMBER/comments --paginate \
159
+ --jq "[.[] | select(.user.login | test(\"$KNOWN_BOTS\"))]"
160
+
161
+ # Bot review comments (inline)
162
+ gh api repos/$REPO/pulls/$PR_NUMBER/comments --paginate \
163
+ --jq "[.[] | select(.user.login | test(\"$KNOWN_BOTS\"))]"
164
+
165
+ # Bot reviews
166
+ gh api repos/$REPO/pulls/$PR_NUMBER/reviews --paginate \
167
+ --jq "[.[] | select(.user.login | test(\"$KNOWN_BOTS\"))]"
168
+ ```
169
+
170
+ **How to use bot findings in the review:**
171
+
172
+ - **Agree/Disagree**: For each substantive bot finding, state whether you agree
173
+ or disagree and why. Bot tools can produce false positives.
174
+ - **Incorporate valid findings**: If a bot found a real issue (bug, security
175
+ concern, missing edge case), include it in the Code Observations section
176
+ and credit the source (e.g., "Gemini Code Assist flagged...").
177
+ - **Dismiss false positives**: If a bot finding is incorrect or irrelevant,
178
+ note it briefly with reasoning so the PR author can ignore it confidently.
179
+ - **Resolved vs unresolved**: Check if the bot's comment was addressed in a
180
+ subsequent commit. If resolved, note it as such.
181
+
182
+ Add a dedicated section to the review report:
183
+
184
+ ```markdown
185
+ ## AI Bot Review Findings
186
+
187
+ ### {Bot Name} ({N} comments)
188
+
189
+ | # | File | Finding | Our Assessment |
190
+ |---|------|---------|----------------|
191
+ | 1 | {path:line} | {summary of bot finding} | ✅ Agree / ❌ Disagree — {reason} / ✔️ Resolved |
192
+
193
+ {If no bot comments found: "No automated reviewer comments found on this PR."}
194
+ ```
195
+
196
+ ### 4. Fetch Jira Ticket Data
197
+
198
+ Use the Jira REST API to get the ticket description and acceptance criteria.
199
+
200
+ ```bash
201
+ # Fetch issue with relevant fields
202
+ curl -s -u "$JIRA_USERNAME:$JIRA_API_TOKEN" \
203
+ -H "Content-Type: application/json" \
204
+ "$JIRA_INSTANCE/rest/api/3/issue/$JIRA_KEY?fields=summary,description,status,priority,issuetype,labels,components,customfield_10021,customfield_10022,customfield_10035" \
205
+ | jq '.'
206
+ ```
207
+
208
+ **Acceptance criteria extraction**: The AC field varies per Jira instance.
209
+ Try the common custom fields in order:
210
+
211
+ ```bash
212
+ # Try customfield_10021, then 10022, then 10035
213
+ for FIELD in customfield_10021 customfield_10022 customfield_10035; do
214
+ AC=$(echo "$JIRA_RESPONSE" | jq -r ".fields.$FIELD // empty")
215
+ if [[ -n "$AC" ]]; then
216
+ echo "✅ Acceptance criteria found in $FIELD"
217
+ break
218
+ fi
219
+ done
220
+
221
+ # Fallback: check if AC is embedded in the description itself
222
+ if [[ -z "$AC" ]]; then
223
+ echo "⚠️ No dedicated AC field found. Will extract from description."
224
+ fi
225
+ ```
226
+
227
+ Also fetch the ticket's **subtasks** and **linked issues** for additional context:
228
+ ```bash
229
+ curl -s -u "$JIRA_USERNAME:$JIRA_API_TOKEN" \
230
+ "$JIRA_INSTANCE/rest/api/3/issue/$JIRA_KEY?fields=subtasks,issuelinks" \
231
+ | jq '.fields.subtasks, .fields.issuelinks'
232
+ ```
233
+
234
+ ### 5. Build the Review Context
235
+
236
+ Assemble all gathered data into a structured prompt for Claude to reason over.
237
+ This is not a prompt you write — Claude Code IS the LLM. Present the data
238
+ in a structured format so Claude can analyze it directly:
239
+
240
+ ```markdown
241
+ ## PR Review Context
242
+
243
+ ### Jira Ticket: {JIRA_KEY}
244
+ **Summary**: {ticket.summary}
245
+ **Status**: {ticket.status}
246
+ **Type**: {ticket.issuetype}
247
+ **Priority**: {ticket.priority}
248
+
249
+ #### Description
250
+ {ticket.description — rendered from ADF to markdown}
251
+
252
+ #### Acceptance Criteria
253
+ {acceptance_criteria — numbered list}
254
+
255
+ ---
256
+
257
+ ### Pull Request: {REPO}#{PR_NUMBER}
258
+ **Title**: {pr.title}
259
+ **Author**: {pr.author}
260
+ **Branch**: {pr.headRefName} → {pr.baseRefName}
261
+ **State**: {pr.state} | Draft: {pr.isDraft}
262
+
263
+ #### PR Description
264
+ {pr.body}
265
+
266
+ #### Changed Files
267
+ {file list with +/- stats}
268
+
269
+ #### Full Diff
270
+ {diff content — or sampled files for large PRs}
271
+
272
+ #### AI Bot Comments
273
+ {bot_name: [{path, line, finding}...] — or "None found"}
274
+
275
+ #### Human Review Comments
276
+ {reviewer: [{path, line, comment}...] — or "None found"}
277
+ ```
278
+
279
+ ### 6. Perform the Review
280
+
281
+ Analyze the PR against the Jira ticket using these review dimensions:
282
+
283
+ #### 5a. Acceptance Criteria Compliance
284
+
285
+ For EACH acceptance criterion, determine:
286
+ - **✅ Met**: The diff clearly implements the criterion.
287
+ - **⚠️ Partially Met**: Some aspects are present but incomplete or unclear.
288
+ - **❌ Not Met**: No evidence in the diff that this criterion is addressed.
289
+ - **🔍 Unable to Verify**: Requires runtime testing, external system, or
290
+ context not available in the diff (e.g., "works on mobile").
291
+
292
+ #### 5b. Description Alignment
293
+
294
+ Check if the PR's changes match the ticket description:
295
+ - Does the PR address the core problem/feature described?
296
+ - Are there changes in the PR that are NOT related to the ticket? (scope creep)
297
+ - Are there aspects of the description NOT addressed by the PR? (gaps)
298
+
299
+ #### 5c. Code Quality Observations (lightweight)
300
+
301
+ Not a full code review — focus on red flags:
302
+ - Obviously missing error handling in new code
303
+ - Hardcoded values that should be configurable
304
+ - Missing tests for new functionality
305
+ - Potential breaking changes
306
+
307
+ ### 7. Generate the Review Report
308
+
309
+ Output a structured report:
310
+
311
+ ```markdown
312
+ # PR Review: {REPO}#{PR_NUMBER} ↔ {JIRA_KEY}
313
+
314
+ **Date**: {today}
315
+ **Reviewer**: Claude Code (automated)
316
+ **Overall Verdict**: ✅ Approved | ⚠️ Needs Attention | ❌ Does Not Meet Criteria
317
+
318
+ ---
319
+
320
+ ## Acceptance Criteria Compliance
321
+
322
+ | # | Criterion | Status | Evidence |
323
+ |---|-----------|--------|----------|
324
+ | 1 | {criterion_1} | ✅/⚠️/❌/🔍 | {file:line or explanation} |
325
+ | 2 | {criterion_2} | ✅/⚠️/❌/🔍 | {file:line or explanation} |
326
+ | ... | | | |
327
+
328
+ **Score**: {met}/{total} criteria met ({percentage}%)
329
+
330
+ ## Description Alignment
331
+
332
+ ### ✅ Addressed
333
+ - {aspect 1 from description that IS covered}
334
+
335
+ ### ❌ Gaps
336
+ - {aspect from description NOT covered by the PR}
337
+
338
+ ### ⚠️ Out of Scope
339
+ - {changes in PR not related to the ticket}
340
+
341
+ ## Code Observations
342
+ - {any red flags, brief}
343
+
344
+ ## AI Bot Review Findings
345
+
346
+ {If bot comments were found, add a subsection per bot:}
347
+
348
+ ### {Bot Name} ({N} comments)
349
+
350
+ | # | File | Finding | Our Assessment |
351
+ |---|------|---------|----------------|
352
+ | 1 | {path:line} | {summary of bot finding} | ✅ Agree / ❌ Disagree — {reason} / ✔️ Resolved |
353
+
354
+ {If no bot comments found: "No automated reviewer comments found on this PR."}
355
+
356
+ ## Verdict & Recommendation
357
+
358
+ {Summary paragraph explaining the overall assessment}
359
+
360
+ **Action**: {APPROVE | REQUEST_CHANGES | CONVERT_TO_DRAFT}
361
+ ```
362
+
363
+ ### 8. Take Action (Optional)
364
+
365
+ Based on the verdict and flags:
366
+
367
+ #### If `--auto-draft` AND verdict is ❌:
368
+
369
+ ```bash
370
+ # Convert PR to draft using GitHub GraphQL API
371
+ PR_NODE_ID=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json id --jq '.id')
372
+ gh api graphql -f query='
373
+ mutation {
374
+ convertPullRequestToDraft(input: {pullRequestId: "'"$PR_NODE_ID"'"}) {
375
+ pullRequest { isDraft }
376
+ }
377
+ }
378
+ '
379
+ echo "🔒 PR #$PR_NUMBER converted to draft — criteria not met."
380
+ ```
381
+
382
+ #### Always: Post review as PR comment
383
+
384
+ ```bash
385
+ # Post the review report as a PR comment
386
+ gh pr comment "$PR_NUMBER" --repo "$REPO" --body "$REVIEW_REPORT"
387
+ ```
388
+
389
+ #### Optionally: Add labels
390
+
391
+ ```bash
392
+ # Tag the PR with review status
393
+ if [[ "$VERDICT" == "approved" ]]; then
394
+ gh pr edit "$PR_NUMBER" --repo "$REPO" --add-label "review:passed"
395
+ elif [[ "$VERDICT" == "needs-attention" ]]; then
396
+ gh pr edit "$PR_NUMBER" --repo "$REPO" --add-label "review:needs-attention"
397
+ else
398
+ gh pr edit "$PR_NUMBER" --repo "$REPO" --add-label "review:blocked"
399
+ fi
400
+ ```
401
+
402
+ ### 9. Save Report (Optional)
403
+
404
+ If the user confirms, persist the review:
405
+
406
+ ```bash
407
+ mkdir -p artifacts/reviews/
408
+ REPORT_FILE="artifacts/reviews/PR-${PR_NUMBER}-${JIRA_KEY}-review.md"
409
+ # Save report to file
410
+ git add "$REPORT_FILE"
411
+ git commit -m "review: PR #${PR_NUMBER} against ${JIRA_KEY}"
412
+ ```
413
+
414
+ ### 10. Output Summary
415
+
416
+ ```
417
+ ✅ PR Review Complete: {REPO}#{PR_NUMBER} ↔ {JIRA_KEY}
418
+
419
+ Verdict: {verdict_emoji} {verdict_text}
420
+ Criteria: {met}/{total} met ({percentage}%)
421
+
422
+ {if auto-draft triggered}
423
+ 🔒 PR converted to draft — criteria not met.
424
+ {end if}
425
+
426
+ Comment posted: {pr_comment_url}
427
+ Report saved: artifacts/reviews/PR-{PR_NUMBER}-{JIRA_KEY}-review.md
428
+
429
+ To approve the PR:
430
+ gh pr review {PR_NUMBER} --repo {REPO} --approve
431
+
432
+ To request changes:
433
+ gh pr review {PR_NUMBER} --repo {REPO} --request-changes --body "..."
434
+ ```
435
+
436
+ ## Edge Cases
437
+
438
+ - **No acceptance criteria found**: Use the ticket description as the evaluation
439
+ baseline. Warn that the review is based on description only.
440
+ - **PR already merged**: Warn and still produce the review (useful for auditing).
441
+ - **PR is already draft**: Skip the convert-to-draft step, note it in the report.
442
+ - **Private repo**: `gh` handles auth; Jira token handles Jira. No extra steps.
443
+ - **Jira ticket not found**: Error with clear message suggesting to verify the key
444
+ and server URL.
445
+ - **Large PR (>8000 lines)**: Use file-level stats + selective file reading.
446
+ Note in the report which files were fully reviewed vs. summarized.
447
+ - **Bot comments with outdated suggestions**: If a bot comment references code
448
+ that was changed in a subsequent commit, mark the finding as "Resolved" rather
449
+ than evaluating the stale suggestion.
450
+ - **Conflicting bot opinions**: If two bots disagree (e.g., Gemini says X is fine,
451
+ Copilot flags X), evaluate the code independently and state which bot is correct.
452
+ - **ADF (Atlassian Document Format)**: Jira Cloud v3 returns description as ADF JSON.
453
+ Parse it to extract text content, or use `renderedFields` expand:
454
+ ```bash
455
+ curl ... "$JIRA_INSTANCE/rest/api/3/issue/$JIRA_KEY?expand=renderedFields" \
456
+ | jq '.renderedFields.description'
457
+ ```
458
+
459
+ ## Jira Description Rendering
460
+
461
+ Jira Cloud v3 API returns descriptions in ADF (Atlassian Document Format).
462
+ To get readable text, use the `renderedFields` expansion which returns HTML,
463
+ then convert to markdown-ish text:
464
+
465
+ ```bash
466
+ # Get rendered (HTML) description
467
+ RENDERED=$(curl -s -u "$JIRA_USERNAME:$JIRA_API_TOKEN" \
468
+ "$JIRA_INSTANCE/rest/api/3/issue/$JIRA_KEY?expand=renderedFields" \
469
+ | jq -r '.renderedFields.description')
470
+
471
+ # Strip HTML tags for plain text (basic)
472
+ DESCRIPTION=$(echo "$RENDERED" | sed 's/<[^>]*>//g' | sed '/^$/d')
473
+ ```
474
+
475
+ ## Reference
476
+
477
+ - Existing code review: `.claude/commands/sdd-codereview.md`
478
+ - Code reviewer agent: `.claude/agents/code-reviewer.md`
479
+ - GitHub CLI docs: `gh pr --help`
480
+ - Jira REST API v3: `https://developer.atlassian.com/cloud/jira/platform/rest/v3/`
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Explore a feature idea by generating multiple approaches with library and code references, then produce a brainstorm document that feeds into /sdd-spec.
3
+ ---
4
+
1
5
  # /sdd-brainstorm — Structured Idea Exploration
2
6
 
3
7
  Explore a feature idea by generating multiple approaches with library and code references,
@@ -1,11 +1,13 @@
1
1
  ---
2
2
  model: haiku
3
+ description: Verify that a feature's tasks were implemented, push the branch, optionally resolve the linked Jira ticket, and clean up the worktree.
3
4
  ---
4
5
 
5
6
  # /sdd-done — Verify, Push, and Cleanup a Feature
6
7
 
7
8
  Verify that a feature's tasks were implemented in its worktree, ensure the branch is
8
- pushed, and clean up the worktree.
9
+ pushed, and clean up the worktree. Optionally transitions the linked Jira ticket to
10
+ "Done" / "Resolved".
9
11
 
10
12
  **This command runs on `dev` (or the main repo), NOT inside a worktree.**
11
13
  It looks INTO the worktree to verify work, but modifies state only on `dev`.
@@ -14,8 +16,9 @@ It looks INTO the worktree to verify work, but modifies state only on `dev`.
14
16
  ```
15
17
  /sdd-done FEAT-014
16
18
  /sdd-done videoreel-visual-changes
17
- /sdd-done FEAT-014 --dry-run # show what would change, don't change anything
18
- /sdd-done FEAT-014 --force # mark done even if some checks fail
19
+ /sdd-done FEAT-014 --dry-run # show what would change, don't change anything
20
+ /sdd-done FEAT-014 --force # mark done even if some checks fail
21
+ /sdd-done FEAT-014 --resolve-jira # also transition the Jira ticket to Done
19
22
  ```
20
23
 
21
24
  ## Guardrails
@@ -185,7 +188,110 @@ After a successful merge, push `dev`:
185
188
  git push origin dev
186
189
  ```
187
190
 
188
- ### 10. Cleanup the Worktree
191
+ ### 10. Transition Jira Ticket (if --resolve-jira)
192
+
193
+ If `--resolve-jira` is passed AND the spec has a Jira key (set by `/sdd-tojira`):
194
+
195
+ **a) Extract the Jira key from the spec:**
196
+ ```bash
197
+ # Look for "**Jira**: [NAV-8036](...)" or a "jira:" metadata field in the spec
198
+ JIRA_KEY=$(grep -oP '(?<=\*\*Jira\*\*: \[)[A-Z]+-\d+' sdd/specs/<feature>.spec.md)
199
+ # Or from the brainstorm "## Jira Source" table
200
+ if [[ -z "$JIRA_KEY" ]]; then
201
+ JIRA_KEY=$(grep -oP '(?<=\| Key \| )[A-Z]+-\d+' sdd/proposals/<key>-*.brainstorm.md)
202
+ fi
203
+ ```
204
+
205
+ If no Jira key is found, skip this step with a note:
206
+ ```
207
+ ℹ️ No Jira key found in spec — skipping Jira transition.
208
+ To link a spec to Jira: /sdd-tojira <spec-path>
209
+ ```
210
+
211
+ **b) Load Jira credentials:**
212
+ ```bash
213
+ eval "$(python -c "from navconfig import config; import os; [print(f'export {k}={v}') for k,v in os.environ.items() if k.startswith('JIRA_')]")"
214
+ JIRA_INSTANCE="${JIRA_INSTANCE%/}"
215
+ ```
216
+
217
+ If `JIRA_INSTANCE` or `JIRA_API_TOKEN` are not set, warn and skip.
218
+
219
+ **c) Get available transitions for the ticket:**
220
+
221
+ Jira transitions are workflow-dependent — you cannot set a status directly.
222
+ First, fetch the available transitions:
223
+
224
+ **MCP path:**
225
+ ```
226
+ jira_transition_issue(issue_key="<JIRA_KEY>") # list available transitions
227
+ ```
228
+
229
+ **curl fallback:**
230
+ ```bash
231
+ TRANSITIONS=$(curl -s -u "$JIRA_USERNAME:$JIRA_API_TOKEN" \
232
+ "$JIRA_INSTANCE/rest/api/3/issue/$JIRA_KEY/transitions")
233
+ echo "$TRANSITIONS" | jq '.transitions[] | {id, name}'
234
+ ```
235
+
236
+ **d) Find and execute the "Done" / "Resolved" transition:**
237
+
238
+ Look for a transition whose name matches (case-insensitive):
239
+ `Done`, `Resolved`, `Close`, `Ready for UAT`, `Complete`.
240
+
241
+ ```bash
242
+ # Find the transition ID
243
+ TRANSITION_ID=$(echo "$TRANSITIONS" | jq -r '
244
+ .transitions[] |
245
+ select(.name | test("(?i)done|resolved|close|complete|ready for uat")) |
246
+ .id' | head -1)
247
+ ```
248
+
249
+ If found, execute it:
250
+
251
+ **MCP path:**
252
+ ```
253
+ jira_transition_issue(issue_key="<JIRA_KEY>", transition_id="<TRANSITION_ID>")
254
+ ```
255
+
256
+ **curl fallback:**
257
+ ```bash
258
+ curl -s -u "$JIRA_USERNAME:$JIRA_API_TOKEN" \
259
+ -H "Content-Type: application/json" \
260
+ -X POST "$JIRA_INSTANCE/rest/api/3/issue/$JIRA_KEY/transitions" \
261
+ -d "{\"transition\": {\"id\": \"$TRANSITION_ID\"}}"
262
+ ```
263
+
264
+ If multiple matching transitions exist, prefer in this order:
265
+ 1. "Done"
266
+ 2. "Resolved"
267
+ 3. "Ready for UAT"
268
+ 4. "Complete"
269
+ 5. "Close"
270
+
271
+ If no matching transition is found:
272
+ ```
273
+ ⚠️ No "Done" or "Resolved" transition available for <JIRA_KEY>.
274
+ Current status: <current_status>
275
+ Available transitions: <list>
276
+ You may need to transition it manually in Jira.
277
+ ```
278
+
279
+ **e) Optionally resolve subtasks too:**
280
+
281
+ If the ticket has subtasks (created by `--with-subtasks` in `/sdd-tojira`),
282
+ transition each one that is still open:
283
+ ```bash
284
+ SUBTASKS=$(curl -s -u "$JIRA_USERNAME:$JIRA_API_TOKEN" \
285
+ "$JIRA_INSTANCE/rest/api/3/issue/$JIRA_KEY?fields=subtasks" \
286
+ | jq -r '.fields.subtasks[].key')
287
+
288
+ for SUBTASK in $SUBTASKS; do
289
+ # Get transitions for this subtask, find "Done", execute
290
+ # Same logic as above
291
+ done
292
+ ```
293
+
294
+ ### 11. Cleanup the Worktree
189
295
  ```bash
190
296
  git worktree remove .claude/worktrees/feat-<FEAT-ID>-<slug>
191
297
  ```
@@ -204,7 +310,7 @@ Optionally delete the local feature branch (it's been merged):
204
310
  git branch -d feat-<FEAT-ID>-<slug>
205
311
  ```
206
312
 
207
- ### 11. Output
313
+ ### 12. Output
208
314
  ```
209
315
  ✅ FEAT-<ID> — <title>: <N>/<total> tasks closed.
210
316
 
@@ -219,12 +325,19 @@ Worktree removed: .claude/worktrees/feat-<ID>-<slug>
219
325
  Local branch deleted: feat-<ID>-<slug>
220
326
  ```
221
327
 
328
+ If `--resolve-jira` was used and succeeded:
329
+ ```
330
+ Jira: NAV-8036 → Done ✅
331
+ Subtasks transitioned: 4/4
332
+ ```
333
+
222
334
  If ALL tasks were closed:
223
335
  ```
224
336
  ✅ FEAT-<ID> — <title>: all <N> tasks closed and merged into dev.
225
337
 
226
338
  Worktree cleaned up.
227
339
  Feature branch merged and deleted.
340
+ {if --resolve-jira} Jira NAV-8036 → Done ✅ {end if}
228
341
  ```
229
342
 
230
343
  ## Reference