tinybird 3.3.2.dev0__tar.gz → 3.5.1__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 (157) hide show
  1. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/PKG-INFO +21 -1
  2. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/sql_toolset.py +19 -0
  3. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/__cli__.py +2 -2
  4. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/cli.py +52 -2
  5. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/common.py +21 -0
  6. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datasource.py +2 -0
  7. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/deployment_common.py +124 -48
  8. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/login_common.py +1 -1
  9. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird.egg-info/PKG-INFO +21 -1
  10. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/setup.cfg +0 -0
  11. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/__cli__.py +0 -0
  12. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/ch_utils/constants.py +0 -0
  13. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/ch_utils/engine.py +0 -0
  14. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/check_pypi.py +0 -0
  15. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/client.py +0 -0
  16. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/config.py +0 -0
  17. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/context.py +0 -0
  18. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/datafile/common.py +0 -0
  19. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/datafile/exceptions.py +0 -0
  20. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/datafile/parse_connection.py +0 -0
  21. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/datafile/parse_datasource.py +0 -0
  22. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/datafile/parse_pipe.py +0 -0
  23. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/datatypes.py +0 -0
  24. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/feedback_manager.py +0 -0
  25. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/git_settings.py +0 -0
  26. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/prompts.py +0 -0
  27. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/service_datasources.py +0 -0
  28. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/sql.py +0 -0
  29. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/sql_template.py +0 -0
  30. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/sql_template_fmt.py +0 -0
  31. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/syncasync.py +0 -0
  32. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/check_pypi.py +0 -0
  33. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/cli.py +0 -0
  34. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/client.py +0 -0
  35. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/config.py +0 -0
  36. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/__init__.py +0 -0
  37. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/agent.py +0 -0
  38. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/animations.py +0 -0
  39. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/banner.py +0 -0
  40. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/command_agent.py +0 -0
  41. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/compactor.py +0 -0
  42. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/explore_agent.py +0 -0
  43. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/file_agent.py +0 -0
  44. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/memory.py +0 -0
  45. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/mock_agent.py +0 -0
  46. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/models.py +0 -0
  47. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/prompts.py +0 -0
  48. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/testing_agent.py +0 -0
  49. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/__init__.py +0 -0
  50. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/analyze.py +0 -0
  51. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/append.py +0 -0
  52. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/build.py +0 -0
  53. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/datafile.py +0 -0
  54. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/deploy.py +0 -0
  55. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/deploy_check.py +0 -0
  56. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/diff_resource.py +0 -0
  57. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/execute_query.py +0 -0
  58. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/file.py +0 -0
  59. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/get_endpoint_stats.py +0 -0
  60. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/get_openapi_definition.py +0 -0
  61. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/mock.py +0 -0
  62. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/plan.py +0 -0
  63. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/request_endpoint.py +0 -0
  64. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/run_command.py +0 -0
  65. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/secret.py +0 -0
  66. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/tools/test.py +0 -0
  67. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/agent/utils.py +0 -0
  68. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/branch.py +0 -0
  69. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/build.py +0 -0
  70. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/build_common.py +0 -0
  71. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/cicd.py +0 -0
  72. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/config.py +0 -0
  73. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/connection.py +0 -0
  74. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/connection_kafka.py +0 -0
  75. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/connection_s3.py +0 -0
  76. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/copy.py +0 -0
  77. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/create.py +0 -0
  78. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/build.py +0 -0
  79. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/build_common.py +0 -0
  80. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  81. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  82. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/diff.py +0 -0
  83. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/fixture.py +0 -0
  84. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/format_common.py +0 -0
  85. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/format_connection.py +0 -0
  86. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  87. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  88. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  89. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/playground.py +0 -0
  90. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/datafile/pull.py +0 -0
  91. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/deployment.py +0 -0
  92. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/deprecations.py +0 -0
  93. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/dev_server.py +0 -0
  94. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/endpoint.py +0 -0
  95. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/exceptions.py +0 -0
  96. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/feedback_manager.py +0 -0
  97. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/fmt.py +0 -0
  98. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/info.py +0 -0
  99. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/infra.py +0 -0
  100. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/job.py +0 -0
  101. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/job_common.py +0 -0
  102. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/llm.py +0 -0
  103. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/llm_utils.py +0 -0
  104. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/local.py +0 -0
  105. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/local_common.py +0 -0
  106. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/local_logs.py +0 -0
  107. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/login.py +0 -0
  108. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/logout.py +0 -0
  109. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/materialization.py +0 -0
  110. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/mock.py +0 -0
  111. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/mock_common.py +0 -0
  112. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/open.py +0 -0
  113. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/pipe.py +0 -0
  114. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/project.py +0 -0
  115. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/project_commands.py +0 -0
  116. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/regions.py +0 -0
  117. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/secret.py +0 -0
  118. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/secret_common.py +0 -0
  119. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/shell.py +0 -0
  120. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/sink.py +0 -0
  121. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/table.py +0 -0
  122. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/telemetry.py +0 -0
  123. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/test.py +0 -0
  124. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/test_common.py +0 -0
  125. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  126. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  127. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/token.py +0 -0
  128. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/watch.py +0 -0
  129. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/workspace.py +0 -0
  130. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb/modules/workspace_members.py +0 -0
  131. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli.py +0 -0
  132. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/auth.py +0 -0
  133. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/branch.py +0 -0
  134. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/cicd.py +0 -0
  135. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/cli.py +0 -0
  136. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/common.py +0 -0
  137. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/config.py +0 -0
  138. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/connection.py +0 -0
  139. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/datasource.py +0 -0
  140. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/exceptions.py +0 -0
  141. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/fmt.py +0 -0
  142. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/job.py +0 -0
  143. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/pipe.py +0 -0
  144. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/regions.py +0 -0
  145. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/tag.py +0 -0
  146. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/telemetry.py +0 -0
  147. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/test.py +0 -0
  148. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  149. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  150. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/workspace.py +0 -0
  151. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  152. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird/tornado_template.py +0 -0
  153. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird.egg-info/SOURCES.txt +0 -0
  154. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird.egg-info/dependency_links.txt +0 -0
  155. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird.egg-info/entry_points.txt +0 -0
  156. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird.egg-info/requires.txt +0 -0
  157. {tinybird-3.3.2.dev0 → tinybird-3.5.1}/tinybird.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 3.3.2.dev0
3
+ Version: 3.5.1
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -57,6 +57,26 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
57
57
  Changelog
58
58
  ----------
59
59
 
60
+ 3.5.2
61
+ *******
62
+
63
+ - `Changed` `tb deploy --auto/--no-auto` keeps the same CLI behavior (default `--auto`) while using server-side deployment `auto_promote` under the hood when enabled.
64
+
65
+ 3.5.1
66
+ *******
67
+
68
+ - `Fixed` Support special characters in workspace names in the login flow.
69
+
70
+ 3.5.0
71
+ *******
72
+
73
+ - `Changed` AI-assisted CLI commands now show a deprecation warning indicating they will be removed in a future major release and include agent skills guidance (`npx skills add @tinybirdco/tinybird-agent-skills`).
74
+
75
+ 3.4.0
76
+ *******
77
+
78
+ - `Changed` Prompt-based AI flows now print a deprecation warning (`tb --prompt`, `tb create --prompt`, `tb datasource create --prompt`, `tb test create`, `tb mock`) ahead of their removal in a future release.
79
+
60
80
  3.3.1
61
81
  *******
62
82
 
@@ -3,6 +3,7 @@ import logging
3
3
  import re
4
4
  import threading
5
5
  from collections import defaultdict
6
+ from dataclasses import dataclass
6
7
  from datetime import datetime
7
8
  from functools import lru_cache
8
9
  from typing import FrozenSet, List, Optional, Set, Tuple, Union
@@ -74,6 +75,24 @@ def explain_plan(sql: str) -> str:
74
75
  return chquery.explain_ast(sql)
75
76
 
76
77
 
78
+ @dataclass(frozen=True)
79
+ class ColumnInfo:
80
+ name: str
81
+ type: str
82
+ nullable: bool
83
+ default_specifier: str = ""
84
+ default_expression: str | None = None
85
+ codec: str | None = None
86
+ comment: str | None = None
87
+ ttl: str | None = None
88
+ is_primary_key: bool = False
89
+
90
+
91
+ def get_columns_from_create_query(sql_schema: str) -> list[ColumnInfo]:
92
+ columns = chquery.get_columns_from_create_query(sql_schema)
93
+ return [ColumnInfo(**col) for col in columns]
94
+
95
+
77
96
  def has_join(sql: str) -> bool:
78
97
  return any(line.rstrip().startswith("TableJoin") for line in explain_plan(sql).split())
79
98
 
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://www.tinybird.co/docs/forward/commands'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '3.3.2.dev0'
8
- __revision__ = 'f22e1ea'
7
+ __version__ = '3.5.1'
8
+ __revision__ = '296fce5'
@@ -36,6 +36,7 @@ from tinybird.tb.modules.common import (
36
36
  force_echo,
37
37
  getenv_bool,
38
38
  try_update_config_with_remote,
39
+ warn_prompt_ai_deprecation,
39
40
  )
40
41
  from tinybird.tb.modules.config import CURRENT_VERSION, CLIConfig
41
42
  from tinybird.tb.modules.datafile.build import build_graph
@@ -54,6 +55,52 @@ DEFAULT_PATTERNS: List[Tuple[str, Union[str, Callable[[str], str]]]] = [
54
55
  VERSION = f"{__cli__.__version__} (rev {__cli__.__revision__})"
55
56
 
56
57
 
58
+ def _get_raw_cli_args(ctx: Context) -> List[str]:
59
+ root_ctx = ctx.find_root()
60
+ root_obj = root_ctx.obj if isinstance(root_ctx.obj, dict) else {}
61
+ raw_args = root_obj.get("_tb_raw_args")
62
+ if isinstance(raw_args, list):
63
+ return raw_args
64
+ return sys.argv[1:]
65
+
66
+
67
+ def _argv_has_option(args: List[str], flag: str) -> bool:
68
+ return any(arg == flag or arg.startswith(f"{flag}=") for arg in args)
69
+
70
+
71
+ def _argv_has_sequence(args: List[str], command_parts: List[str]) -> bool:
72
+ sequence_len = len(command_parts)
73
+ return any(args[i : i + sequence_len] == command_parts for i in range(len(args) - sequence_len + 1))
74
+
75
+
76
+ def _should_warn_prompt_ai_deprecation(
77
+ ctx: Context,
78
+ is_agent_mode: bool,
79
+ is_prompt_mode: bool,
80
+ ) -> bool:
81
+ raw_args = _get_raw_cli_args(ctx)
82
+
83
+ if is_agent_mode or is_prompt_mode:
84
+ return True
85
+
86
+ if ctx.invoked_subcommand == "mock":
87
+ return True
88
+
89
+ if ctx.invoked_subcommand == "test" and _argv_has_sequence(raw_args, ["test", "create"]):
90
+ return True
91
+
92
+ if ctx.invoked_subcommand == "create" and (
93
+ _argv_has_option(raw_args, "--prompt") or _argv_has_option(raw_args, "-p")
94
+ ):
95
+ return True
96
+
97
+ return (
98
+ ctx.invoked_subcommand == "datasource"
99
+ and _argv_has_sequence(raw_args, ["datasource", "create"])
100
+ and _argv_has_option(raw_args, "--prompt")
101
+ )
102
+
103
+
57
104
  @click.group(
58
105
  cls=CatchAuthExceptions,
59
106
  context_settings={
@@ -129,6 +176,7 @@ def cli(
129
176
  click.echo(FeedbackManager.warning_disabled_ssl_checks())
130
177
 
131
178
  is_agent_mode = ctx.invoked_subcommand is None
179
+ is_prompt_mode = prompt is not None
132
180
  if not environ.get("PYTEST", None) and version_warning and not token and not is_agent_mode:
133
181
  latest_version = CheckPypi().get_latest_version()
134
182
  if latest_version:
@@ -215,6 +263,10 @@ def cli(
215
263
  return
216
264
 
217
265
  ctx.ensure_object(dict)["project"] = project
266
+
267
+ if _should_warn_prompt_ai_deprecation(ctx, is_agent_mode, is_prompt_mode):
268
+ warn_prompt_ai_deprecation()
269
+
218
270
  client = create_ctx_client(
219
271
  ctx,
220
272
  config,
@@ -235,8 +287,6 @@ def cli(
235
287
  # Check if current folder is tracked from previous sessions
236
288
  check_current_folder_in_sessions(ctx)
237
289
 
238
- is_prompt_mode = prompt is not None
239
-
240
290
  if is_agent_mode or is_prompt_mode:
241
291
  if any(arg in sys.argv for arg in ["--cloud", "--local", "--branch"]):
242
292
  raise CLIException(
@@ -74,6 +74,10 @@ _PATTERN_AWS_ARN = re.compile(r"arn:aws:iam::(\d+):root")
74
74
  SUPPORTED_FORMATS = ["csv", "ndjson", "json", "parquet"]
75
75
  OLDEST_ROLLBACK = "oldest_rollback"
76
76
  MAIN_BRANCH = "main"
77
+ PROMPT_AI_DEPRECATION_WARNING = (
78
+ "Tinybird Code and `--prompt` commands are now deprecated and will be removed in the next major release.\n"
79
+ "You can instead bring the best of Tinybird Code to your preferred coding agent with skills. Run: npx skills add @tinybirdco/tinybird-agent-skills\n"
80
+ )
77
81
 
78
82
 
79
83
  def obfuscate_token(value: Optional[str]) -> Optional[str]:
@@ -82,6 +86,17 @@ def obfuscate_token(value: Optional[str]) -> Optional[str]:
82
86
  return f"{value[:4]}...{value[-8:]}"
83
87
 
84
88
 
89
+ def warn_prompt_ai_deprecation() -> None:
90
+ ctx = click.get_current_context(silent=True)
91
+ if ctx:
92
+ root_ctx = ctx.find_root()
93
+ root_obj = root_ctx.ensure_object(dict)
94
+ if root_obj.get("_prompt_ai_deprecation_warned"):
95
+ return
96
+ root_obj["_prompt_ai_deprecation_warned"] = True
97
+ click.echo(FeedbackManager.warning(message=PROMPT_AI_DEPRECATION_WARNING))
98
+
99
+
85
100
  def gather_with_concurrency(n, *tasks):
86
101
  results = []
87
102
  for task in tasks:
@@ -237,6 +252,12 @@ class CatchAuthExceptions(AliasedGroup):
237
252
  add_telemetry_sysinfo_event()
238
253
  super().__init__(*args, **kwargs)
239
254
 
255
+ def parse_args(self, ctx: click.Context, args: List[str]) -> List[str]:
256
+ # Keep original invocation args so root-level handlers can inspect
257
+ # subcommand flags without relying on sys.argv (e.g. in CliRunner tests).
258
+ ctx.ensure_object(dict)["_tb_raw_args"] = list(args)
259
+ return super().parse_args(ctx, args)
260
+
240
261
  def format_epilog(self, ctx: Context, formatter: click.formatting.HelpFormatter) -> None:
241
262
  super().format_epilog(ctx, formatter)
242
263
 
@@ -38,6 +38,7 @@ from tinybird.tb.modules.common import (
38
38
  get_format_from_filename_or_url,
39
39
  normalize_datasource_name,
40
40
  push_data,
41
+ warn_prompt_ai_deprecation,
41
42
  )
42
43
  from tinybird.tb.modules.config import CLIConfig
43
44
  from tinybird.tb.modules.connection_kafka import (
@@ -975,6 +976,7 @@ ENGINE "MergeTree"
975
976
  return
976
977
 
977
978
  if datasource_type == "prompt":
979
+ warn_prompt_ai_deprecation()
978
980
  if not config.get("user_token"):
979
981
  raise Exception("This action requires authentication. Run 'tb login' first.")
980
982
 
@@ -87,6 +87,63 @@ def api_post(
87
87
  return {}
88
88
 
89
89
 
90
+ def _is_first_deployment_with_seed_live(host: Optional[str], headers: dict) -> bool:
91
+ """Best-effort check for first real deployment when seed deployment (id=0) is still live."""
92
+ try:
93
+ response = requests.get(f"{host}/v1/deployments", headers=headers)
94
+ if response.status_code >= 300:
95
+ return False
96
+
97
+ result = response.json()
98
+ logging.debug(json.dumps(result, indent=2))
99
+ deployments = result.get("deployments") or []
100
+ if not deployments:
101
+ return False
102
+
103
+ live_deployment = next((deployment for deployment in deployments if deployment.get("live")), deployments[0])
104
+ return str(live_deployment.get("id")) == "0"
105
+ except Exception:
106
+ # Hint calculation must never break deployment flow.
107
+ return False
108
+
109
+
110
+ def _get_deployment_job(client: TinyB, deployment_id: Optional[Union[str, int]]) -> Optional[Dict[str, Any]]:
111
+ if deployment_id is None:
112
+ return None
113
+
114
+ try:
115
+ deployment_id = str(deployment_id)
116
+ jobs = client.jobs()
117
+ return next(
118
+ (job for job in jobs if job.get("kind") == "deployment" and str(job.get("deployment_id")) == deployment_id),
119
+ None,
120
+ )
121
+ except Exception:
122
+ return None
123
+
124
+
125
+ def _cancel_deployment_job(client: TinyB, deployment_job: Optional[Dict[str, Any]]) -> None:
126
+ if not deployment_job:
127
+ return
128
+
129
+ job_id = str(deployment_job.get("id") or deployment_job.get("job_id") or "")
130
+ if not job_id:
131
+ return
132
+
133
+ try:
134
+ result = client.job_cancel(job_id)
135
+ except Exception:
136
+ return
137
+
138
+ current_job_status = result.get("status")
139
+ if current_job_status == "cancelling":
140
+ click.echo(FeedbackManager.success_job_cancellation_cancelling(job_id=job_id))
141
+ elif current_job_status == "cancelled":
142
+ click.echo(FeedbackManager.success_job_cancellation_cancelled(job_id=job_id))
143
+ else:
144
+ click.echo(FeedbackManager.error_job_cancelled_but_status_unknown(job_id=job_id))
145
+
146
+
90
147
  # TODO(eclbg): This logic should be in the server, and there should be a dedicated endpoint for promoting a deployment
91
148
  # potato
92
149
  def promote_deployment(host: Optional[str], headers: dict, wait: bool, ingest_hint: Optional[bool] = True) -> None:
@@ -272,12 +329,15 @@ def create_deployment(
272
329
  )
273
330
 
274
331
  deployment = None
332
+ deployment_job: Optional[Dict[str, Any]] = None
275
333
  try:
276
334
  HEADERS = {"Authorization": f"Bearer {TINYBIRD_API_KEY}"}
277
335
  params = {}
278
336
  if check:
279
337
  click.echo(FeedbackManager.highlight(message="\n» Validating deployment...\n"))
280
338
  params["check"] = "true"
339
+ elif auto:
340
+ params["auto_promote"] = "true"
281
341
  if allow_destructive_operations:
282
342
  params["allow_destructive_operations"] = "true"
283
343
 
@@ -338,15 +398,7 @@ def create_deployment(
338
398
  FeedbackManager.gray(message="Deployment URL: ")
339
399
  + f"{bcolors.UNDERLINE}{host}/{config.get('name')}/deployments/{deployment.get('id')}{bcolors.ENDC}"
340
400
  )
341
- jobs = client.jobs()
342
- deployment_job = next(
343
- (
344
- job
345
- for job in jobs
346
- if job.get("kind") == "deployment" and job.get("deployment_id") == deployment.get("id")
347
- ),
348
- None,
349
- )
401
+ deployment_job = _get_deployment_job(client, deployment.get("id"))
350
402
  if deployment_job:
351
403
  echo_job_url(
352
404
  token=client.token,
@@ -379,52 +431,76 @@ def create_deployment(
379
431
 
380
432
  if deployment and wait and not check:
381
433
  click.echo(FeedbackManager.highlight(message="» Waiting for deployment to be ready..."))
382
- while True:
383
- url = f"{client.host}/v1/deployments/{deployment.get('id')}"
384
- res = api_fetch(url, HEADERS)
385
- deployment = res.get("deployment")
386
- if not deployment:
387
- click.echo(FeedbackManager.error(message="Error parsing deployment from response"))
388
- sys_exit("deployment_error", "Error parsing deployment from response")
389
- return
390
-
391
- status = deployment.get("status")
392
- errors = deployment.get("errors")
393
- feedback = deployment.get("feedback")
394
-
395
- if status == "failed":
396
- # Just wait until we poll again and see deleting or deleted to report errors
397
- pass
398
-
399
- if status == "data_ready":
400
- break
434
+ waiting_auto_promote = False
435
+ is_first_deployment = str(deployment.get("id")) == "1"
436
+ try:
437
+ while True:
438
+ url = f"{client.host}/v1/deployments/{deployment.get('id')}"
439
+ res = api_fetch(url, HEADERS)
440
+ deployment = res.get("deployment")
441
+ if not deployment:
442
+ click.echo(FeedbackManager.error(message="Error parsing deployment from response"))
443
+ sys_exit("deployment_error", "Error parsing deployment from response")
444
+ return
401
445
 
402
- if status in ["deleting", "deleted"]:
446
+ status = deployment.get("status")
403
447
  errors = deployment.get("errors")
404
- if errors:
405
- verb = "is being" if status == "deleting" else "was"
406
- click.echo(
407
- FeedbackManager.error(
408
- message=f"Deployment failed and {verb} deleted automatically. Deployment errors:"
448
+ feedback = deployment.get("feedback")
449
+
450
+ if status == "failed":
451
+ # Just wait until we poll again and see deleting or deleted to report errors
452
+ pass
453
+
454
+ if status == "data_ready":
455
+ if auto and not deployment.get("live"):
456
+ if not waiting_auto_promote:
457
+ click.echo(FeedbackManager.info(message="✓ Deployment is ready"))
458
+ click.echo(FeedbackManager.highlight(message="» Waiting for deployment to be promoted..."))
459
+ if not is_first_deployment:
460
+ is_first_deployment = _is_first_deployment_with_seed_live(client.host, HEADERS)
461
+ waiting_auto_promote = True
462
+ time.sleep(5)
463
+ continue
464
+ break
465
+
466
+ if status in ["deleting", "deleted"]:
467
+ errors = deployment.get("errors")
468
+ if errors:
469
+ verb = "is being" if status == "deleting" else "was"
470
+ click.echo(
471
+ FeedbackManager.error(
472
+ message=f"Deployment failed and {verb} deleted automatically. Deployment errors:"
473
+ )
409
474
  )
475
+ for error in errors:
476
+ click.echo(FeedbackManager.error(message=f"* {error}"))
477
+ sys_exit(
478
+ "deployment_error",
479
+ f"Deployment deleted after failure. Errors: {str(errors + (feedback or []))}",
410
480
  )
411
- for error in errors:
412
- click.echo(FeedbackManager.error(message=f"* {error}"))
413
- sys_exit(
414
- "deployment_error", f"Deployment deleted after failure. Errors: {str(errors + (feedback or []))}"
415
- )
416
-
417
- time.sleep(5)
418
481
 
419
- click.echo(FeedbackManager.info(message="✓ Deployment is ready"))
482
+ time.sleep(5)
483
+ except KeyboardInterrupt:
484
+ if auto:
485
+ if not deployment_job:
486
+ deployment_job = _get_deployment_job(client, deployment.get("id") if deployment else None)
487
+ _cancel_deployment_job(client, deployment_job)
488
+ raise click.Abort()
420
489
 
421
490
  if auto:
422
- promote_deployment(client.host, HEADERS, wait=wait, ingest_hint=ingest_hint)
423
- # Fetch the final deployment state after promotion for JSON output
424
- if output == "json":
425
- url = f"{client.host}/v1/deployments/{deployment.get('id')}"
426
- res = api_fetch(url, HEADERS)
427
- deployment = res.get("deployment")
491
+ if not waiting_auto_promote:
492
+ click.echo(FeedbackManager.info(message="✓ Deployment is ready"))
493
+ click.echo(FeedbackManager.highlight(message="» Waiting for deployment to be promoted..."))
494
+ click.echo(FeedbackManager.info(message="✓ Deployment promoted"))
495
+ click.echo(FeedbackManager.success(message=f"✓ Deployment #{deployment.get('id')} is live!"))
496
+ if ingest_hint and len(deployment.get("new_data_connector_ids", [])) == 0 and is_first_deployment:
497
+ click.echo(
498
+ FeedbackManager.info(
499
+ message="Need help ingesting your data? Learn how at https://www.tinybird.co/docs/forward/get-data-in"
500
+ )
501
+ )
502
+ else:
503
+ click.echo(FeedbackManager.info(message="✓ Deployment is ready"))
428
504
 
429
505
  # Output JSON at the appropriate time based on the execution path
430
506
  if output == "json" and deployment:
@@ -63,7 +63,7 @@ class AuthHandler(http.server.SimpleHTTPRequestHandler):
63
63
  const host = "{auth_host}";
64
64
  fetch('/?code=' + code, {{method: 'POST'}})
65
65
  .then(() => {{
66
- window.location.href = host + "/" + provider + "/" + region + "/cli-login?workspace=" + workspace;
66
+ window.location.href = host + "/" + provider + "/" + region + "/cli-login?workspace=" + encodeURIComponent(workspace);
67
67
  }});
68
68
  </script>
69
69
  </body>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 3.3.2.dev0
3
+ Version: 3.5.1
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -57,6 +57,26 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
57
57
  Changelog
58
58
  ----------
59
59
 
60
+ 3.5.2
61
+ *******
62
+
63
+ - `Changed` `tb deploy --auto/--no-auto` keeps the same CLI behavior (default `--auto`) while using server-side deployment `auto_promote` under the hood when enabled.
64
+
65
+ 3.5.1
66
+ *******
67
+
68
+ - `Fixed` Support special characters in workspace names in the login flow.
69
+
70
+ 3.5.0
71
+ *******
72
+
73
+ - `Changed` AI-assisted CLI commands now show a deprecation warning indicating they will be removed in a future major release and include agent skills guidance (`npx skills add @tinybirdco/tinybird-agent-skills`).
74
+
75
+ 3.4.0
76
+ *******
77
+
78
+ - `Changed` Prompt-based AI flows now print a deprecation warning (`tb --prompt`, `tb create --prompt`, `tb datasource create --prompt`, `tb test create`, `tb mock`) ahead of their removal in a future release.
79
+
60
80
  3.3.1
61
81
  *******
62
82
 
File without changes
File without changes