gibson-cli 0.7.2__py3-none-any.whl → 0.7.4__py3-none-any.whl

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.
gibson/bin/gibson.py CHANGED
@@ -5,11 +5,14 @@ from gibson.core.Configuration import Configuration
5
5
 
6
6
 
7
7
  def main():
8
- configuration = Configuration()
9
- if configuration.settings is None:
10
- configuration.initialize()
11
- else:
12
- router = CommandRouter(configuration).run()
8
+ try:
9
+ configuration = Configuration()
10
+ if configuration.settings is None:
11
+ configuration.initialize()
12
+ else:
13
+ CommandRouter(configuration).run()
14
+ except KeyboardInterrupt:
15
+ exit(1)
13
16
 
14
17
 
15
18
  if __name__ == "__main__":
gibson/command/Help.py CHANGED
@@ -21,7 +21,7 @@ class Help(BaseCommand):
21
21
  "description": "create the entities in the datastore",
22
22
  "memory": "stored",
23
23
  },
24
- "code": {"description": "pair program", "memory": None},
24
+ "code": {"description": "pair program with gibson", "memory": None},
25
25
  "conf": {"description": "set a configuration variable", "memory": None},
26
26
  "count": {
27
27
  "description": "show the number of entities stored",
@@ -62,7 +62,7 @@ class Help(BaseCommand):
62
62
  "memory": "last > stored",
63
63
  },
64
64
  "rewrite": {
65
- "description": "rewrite code",
65
+ "description": "rewrite all code",
66
66
  "memory": "stored",
67
67
  },
68
68
  "show": {"description": "display an entity", "memory": "last > stored"},
gibson/command/Version.py CHANGED
@@ -15,15 +15,15 @@ class Version(BaseCommand):
15
15
 
16
16
  if latest_version != VersionConf.num:
17
17
  self.conversation.type(
18
- f"A new version of {Colors.command(self.configuration.command)} is available: {Colors.colorize(latest_version, Colors.Color.CYAN)}\n"
18
+ f"A new version of {Colors.command(self.configuration.command)} is available: {Colors.cyan(latest_version)}\n"
19
19
  )
20
20
  self.conversation.type(
21
- f"You are currently using version: {Colors.colorize(VersionConf.num, Colors.Color.VIOLET)}\n"
21
+ f"You are currently using version: {Colors.violet(VersionConf.num)}\n"
22
22
  )
23
23
  self.conversation.type(
24
24
  f"Please update to the latest version by running: {Colors.command('pip3')} {Colors.subcommand('install')} {Colors.option('--upgrade')} gibson-cli\n"
25
25
  )
26
26
  else:
27
27
  self.conversation.type(
28
- f"Nice! 🎉 You are using the latest version of {Colors.command(self.configuration.command)}: {Colors.colorize(VersionConf.num, Colors.Color.CYAN)}\n"
28
+ f"Nice! 🎉 You are using the latest version of {Colors.command(self.configuration.command)}: {Colors.cyan(VersionConf.num)}\n"
29
29
  )
@@ -10,6 +10,7 @@ from gibson.command.code.Schema import Schema
10
10
  from gibson.command.code.Test import Test
11
11
  from gibson.command.Merge import Merge
12
12
  from gibson.core.Configuration import Configuration
13
+ from gibson.core.Spinner import ComputingSpinner, Spinner
13
14
  from gibson.display.Header import Header
14
15
  from gibson.display.WorkspaceFooter import WorkspaceFooter
15
16
  from gibson.display.WorkspaceHeader import WorkspaceHeader
@@ -88,79 +89,85 @@ class Entity(BaseCommand):
88
89
  self.configuration.require_project()
89
90
  definition = self.configure_definition()
90
91
 
91
- self.__context = CodeContextSchemaManager().from_code_writer_schema_context(
92
- cli.code_writer_schema_context()
93
- )
94
-
95
- data = cli.code_writer_entity_modifier(
96
- self.__context.json,
97
- sys.argv[3],
98
- definition,
99
- self.CODE_WRITER_ENTITY_MODIFIER_NOOP,
100
- )
101
- entity = (
102
- StructureEntity()
103
- .instantiate(self.configuration.project.datastore.type)
104
- .import_from_struct(data)
105
- )
92
+ with ComputingSpinner():
93
+ self.__context = CodeContextSchemaManager().from_code_writer_schema_context(
94
+ cli.code_writer_schema_context()
95
+ )
96
+ data = cli.code_writer_entity_modifier(
97
+ self.__context.json,
98
+ sys.argv[3],
99
+ definition,
100
+ self.CODE_WRITER_ENTITY_MODIFIER_NOOP,
101
+ )
102
+ entity = (
103
+ StructureEntity()
104
+ .instantiate(self.configuration.project.datastore.type)
105
+ .import_from_struct(data)
106
+ )
106
107
 
107
108
  while True:
108
- self.__render_workspace(entity, data["code"][0]["definition"])
109
-
110
- input_ = input("> ")
111
- if input_ in [":q", ":q!", ":wq"]:
112
- self.conversation.newline()
113
-
114
- if input_ == ":q":
115
- self.conversation.type("Exiting without saving.\n")
116
-
117
- if input_ in [":q", ":q!"]:
118
- exit(1)
119
-
120
- self.memory.remember_last({"entities": [data["entity"]]})
121
- self.conversation.mute()
122
- Merge(self.configuration).execute()
123
- self.conversation.unmute()
124
-
125
- self.conversation.type("Entity saved! ✅\n\n")
126
- self.conversation.type("Gibson is writing the code...\n\n")
127
-
128
- Model(self.configuration).execute(entity.name)
129
- Schema(self.configuration).execute(entity.name)
130
- Test(self.configuration).execute(entity.name)
131
-
132
- self.conversation.type(
133
- f"All code for the {Colors.violet(entity.name)} entity has been written 🎉\n\n"
134
- )
135
-
136
- exit()
137
- elif input_ == "":
138
- continue
139
-
140
- talk_to_gibsonai = True
141
-
142
- parts = input_.split(" ")
143
- if parts[0] == "fk":
144
- input_ = self.CODE_WRITER_ENTITY_MODIFIER_NOOP
145
- if not self.__add_foreign_key(entity, parts[1]):
146
- # If the entity was not modified, likely because the table
147
- # referenced does not exist or does not contain indexes which
148
- # can be used for a foreign key, do not waste the network call
149
- # to GibsonAI since there is nothing to do.
150
- talk_to_gibsonai = False
151
-
152
- if talk_to_gibsonai is True:
153
- data = cli.code_writer_entity_modifier(
154
- self.__context.json,
155
- data["entity"]["name"],
156
- entity.create_statement(),
157
- input_,
158
- )
159
- entity = (
160
- StructureEntity()
161
- .instantiate(self.configuration.project.datastore.type)
162
- .import_from_struct(data)
163
- )
109
+ try:
110
+ self.__render_workspace(entity, data["code"][0]["definition"])
111
+ input_ = input("> ")
112
+ if input_.lower() in [":q", ":q!", ":wq"]:
113
+ self.conversation.newline()
114
+
115
+ if input_.lower() == ":q":
116
+ self.conversation.type("Exiting without saving.\n")
117
+
118
+ if input_.lower() in [":q", ":q!"]:
119
+ exit(1)
120
+
121
+ # Mute output from individual merge + rewrite operations
122
+ self.conversation.mute()
123
+
124
+ with Spinner(
125
+ "Gibson is saving your changes to the entity...",
126
+ "Entity saved",
127
+ ):
128
+ self.memory.remember_last({"entities": [data["entity"]]})
129
+ Merge(self.configuration).execute()
130
+
131
+ # Rewrite each category of code with the new entity definition
132
+ Model(self.configuration).execute(entity_name=entity.name)
133
+ Schema(self.configuration).execute(entity_name=entity.name)
134
+ Test(self.configuration).execute(entity_name=entity.name)
135
+
136
+ self.conversation.unmute()
137
+ self.conversation.type(
138
+ f"\nAll code for the {Colors.violet(entity.name)} entity has been written 🎉\n\n"
139
+ )
140
+ exit()
141
+ elif input_ == "":
142
+ continue
143
+
144
+ with ComputingSpinner():
145
+ talk_to_gibsonai = True
146
+ parts = input_.split(" ")
147
+ if parts[0] == "fk":
148
+ input_ = self.CODE_WRITER_ENTITY_MODIFIER_NOOP
149
+ if not self.__add_foreign_key(entity, parts[1]):
150
+ # If the entity was not modified, likely because the table
151
+ # referenced does not exist or does not contain indexes which
152
+ # can be used for a foreign key, do not waste the network call
153
+ # to GibsonAI since there is nothing to do.
154
+ talk_to_gibsonai = False
155
+
156
+ if talk_to_gibsonai is True:
157
+ data = cli.code_writer_entity_modifier(
158
+ self.__context.json,
159
+ data["entity"]["name"],
160
+ entity.create_statement(),
161
+ input_,
162
+ )
163
+ entity = (
164
+ StructureEntity()
165
+ .instantiate(self.configuration.project.datastore.type)
166
+ .import_from_struct(data)
167
+ )
168
+ except KeyboardInterrupt:
169
+ self.conversation.type("\nExiting without saving.\n")
170
+ exit(1)
164
171
 
165
172
  def get_default_ref_table_template_path(self):
166
173
  return (
@@ -185,12 +192,12 @@ class Entity(BaseCommand):
185
192
  print(WorkspaceHeader().render(self.configuration.project.name))
186
193
 
187
194
  print("")
188
- print(Header().render("SQL", Colors.Color.CYAN))
195
+ print(Header().render("SQL", Colors.cyan))
189
196
  print("")
190
197
  print(Colors.table(entity.create_statement(), entity.name))
191
198
 
192
199
  print("")
193
- print(Header().render("Model", Colors.Color.YELLOW))
200
+ print(Header().render("Model", Colors.yellow))
194
201
  print("")
195
202
  print(Colors.model(model, entity.name))
196
203
 
@@ -3,12 +3,14 @@ import sys
3
3
  import gibson.core.Colors as Colors
4
4
  from gibson.api.Cli import Cli
5
5
  from gibson.command.BaseCommand import BaseCommand
6
+ from gibson.core.Spinner import Spinner
6
7
  from gibson.core.TimeKeeper import TimeKeeper
7
8
  from gibson.dev.Dev import Dev
8
9
 
9
10
 
10
11
  class Model(BaseCommand):
11
- def execute(self, entity_name=sys.argv[3]):
12
+ def execute(self, entity_name=None):
13
+ entity_name = entity_name or sys.argv[3]
12
14
  self.configuration.require_project()
13
15
  entity = self.memory.recall_stored_entity(entity_name)
14
16
  if entity is None:
@@ -19,17 +21,18 @@ class Model(BaseCommand):
19
21
 
20
22
  time_keeper = TimeKeeper()
21
23
 
22
- cli = Cli(self.configuration)
23
- response = cli.code_models([entity["name"]])
24
-
25
- Dev(self.configuration).model(
26
- response["code"][0]["entity"]["name"], response["code"][0]["definition"]
27
- )
24
+ with Spinner("Gibson is writing the models...", "Models written"):
25
+ cli = Cli(self.configuration)
26
+ response = cli.code_models([entity["name"]])
27
+ Dev(self.configuration).model(
28
+ response["code"][0]["entity"]["name"], response["code"][0]["definition"]
29
+ )
28
30
 
29
31
  if self.configuration.project.dev.active is True:
30
32
  self.conversation.type(
31
- f"Gibson wrote the following {Colors.argument('model')} code to your project:\n"
33
+ f"\nGibson wrote the following {Colors.argument('model')} code to your project:\n"
32
34
  )
33
35
 
34
- print(response["code"][0]["definition"])
35
- time_keeper.display()
36
+ if not self.conversation.muted():
37
+ print(response["code"][0]["definition"])
38
+ time_keeper.display()
@@ -3,12 +3,14 @@ import sys
3
3
  import gibson.core.Colors as Colors
4
4
  from gibson.api.Cli import Cli
5
5
  from gibson.command.BaseCommand import BaseCommand
6
+ from gibson.core.Spinner import Spinner
6
7
  from gibson.core.TimeKeeper import TimeKeeper
7
8
  from gibson.dev.Dev import Dev
8
9
 
9
10
 
10
11
  class Schema(BaseCommand):
11
- def execute(self, entity_name=sys.argv[3]):
12
+ def execute(self, entity_name=None):
13
+ entity_name = entity_name or sys.argv[3]
12
14
  self.configuration.require_project()
13
15
  entity = self.memory.recall_stored_entity(entity_name)
14
16
  if entity is None:
@@ -19,17 +21,18 @@ class Schema(BaseCommand):
19
21
 
20
22
  time_keeper = TimeKeeper()
21
23
 
22
- cli = Cli(self.configuration)
23
- response = cli.code_schemas([entity["name"]])
24
-
25
- Dev(self.configuration).schema(
26
- response["code"][0]["entity"]["name"], response["code"][0]["definition"]
27
- )
24
+ with Spinner("Gibson is writing the schemas...", "Schemas written"):
25
+ cli = Cli(self.configuration)
26
+ response = cli.code_schemas([entity["name"]])
27
+ Dev(self.configuration).schema(
28
+ response["code"][0]["entity"]["name"], response["code"][0]["definition"]
29
+ )
28
30
 
29
31
  if self.configuration.project.dev.active is True:
30
32
  self.conversation.type(
31
- f"Gibson wrote the following {Colors.argument('schema')} code to your project:\n"
33
+ f"\nGibson wrote the following {Colors.argument('schema')} code to your project:\n"
32
34
  )
33
35
 
34
- print(response["code"][0]["definition"])
35
- time_keeper.display()
36
+ if not self.conversation.muted():
37
+ print(response["code"][0]["definition"])
38
+ time_keeper.display()
@@ -3,12 +3,14 @@ import sys
3
3
  import gibson.core.Colors as Colors
4
4
  from gibson.api.Cli import Cli
5
5
  from gibson.command.BaseCommand import BaseCommand
6
+ from gibson.core.Spinner import Spinner
6
7
  from gibson.core.TimeKeeper import TimeKeeper
7
8
  from gibson.dev.Dev import Dev
8
9
 
9
10
 
10
11
  class Test(BaseCommand):
11
- def execute(self, entity_name=sys.argv[3]):
12
+ def execute(self, entity_name=None):
13
+ entity_name = entity_name or sys.argv[3]
12
14
  self.configuration.require_project()
13
15
  entity = self.memory.recall_stored_entity(entity_name)
14
16
  if entity is None:
@@ -19,17 +21,18 @@ class Test(BaseCommand):
19
21
 
20
22
  time_keeper = TimeKeeper()
21
23
 
22
- cli = Cli(self.configuration)
23
- response = cli.code_testing([entity["name"]])
24
-
25
- Dev(self.configuration).tests(
26
- response["code"][0]["entity"]["name"], response["code"][0]["definition"]
27
- )
24
+ with Spinner("Gibson is writing the tests...", "Tests written"):
25
+ cli = Cli(self.configuration)
26
+ response = cli.code_testing([entity["name"]])
27
+ Dev(self.configuration).tests(
28
+ response["code"][0]["entity"]["name"], response["code"][0]["definition"]
29
+ )
28
30
 
29
31
  if self.configuration.project.dev.active is True:
30
32
  self.conversation.type(
31
- f"Gibson wrote the following {Colors.argument('tests')} to your project:\n"
33
+ f"\nGibson wrote the following {Colors.argument('tests')} to your project:\n"
32
34
  )
33
35
 
34
- print(response["code"][0]["definition"])
35
- time_keeper.display()
36
+ if not self.conversation.muted():
37
+ print(response["code"][0]["definition"])
38
+ time_keeper.display()
@@ -25,7 +25,6 @@ class Rewrite(BaseCommand):
25
25
  super().__init__(configuration)
26
26
  self.wipe = wipe
27
27
  self.with_header = with_header
28
- self.arguments = ["api", "base", "models", "schemas", "tests"]
29
28
 
30
29
  def execute(self):
31
30
  if len(sys.argv) == 2:
gibson/core/Colors.py CHANGED
@@ -1,4 +1,4 @@
1
- class Color:
1
+ class Constants:
2
2
  BLACK = "\033[30m"
3
3
  BLACK_BG = "\033[40m"
4
4
  BLINK = "\033[5m"
@@ -42,17 +42,17 @@ class Color:
42
42
 
43
43
  # Colorize text with a given color
44
44
  def colorize(text, color):
45
- return f"{color}{text}{Color.END}"
45
+ return f"{color}{text}{Constants.END}"
46
46
 
47
47
 
48
48
  # Colorize a command
49
49
  def command(text):
50
- return colorize(text, Color.GREEN)
50
+ return green(text)
51
51
 
52
52
 
53
53
  # Colorize a subcommand
54
54
  def subcommand(text):
55
- return colorize(text, Color.YELLOW)
55
+ return yellow(text)
56
56
 
57
57
 
58
58
  # Colorize an argument
@@ -67,27 +67,27 @@ def arguments(list):
67
67
 
68
68
  # Colorize user input
69
69
  def input(text):
70
- return colorize(text, Color.WHITE2)
70
+ return white(text)
71
71
 
72
72
 
73
73
  # Colorize a command option
74
74
  def option(text):
75
- return colorize(text, Color.CYAN)
75
+ return cyan(text)
76
76
 
77
77
 
78
78
  # Colorize a hint
79
79
  def hint(text):
80
- return colorize(text, Color.GREY)
80
+ return grey(text)
81
81
 
82
82
 
83
83
  # Colorize a project name
84
84
  def project(text):
85
- return colorize(text, Color.BOLD)
85
+ return bold(text)
86
86
 
87
87
 
88
88
  # Colorize a URL to appear as a link
89
89
  def link(text):
90
- return colorize(colorize(text, Color.BLUE), Color.UNDERLINE)
90
+ return underline(blue(text))
91
91
 
92
92
 
93
93
  # Colorize the table name in a SQL statement
@@ -104,24 +104,44 @@ def model(code, name):
104
104
 
105
105
  # Colorize a time/duration output
106
106
  def time(text):
107
- return colorize(text, Color.GREEN)
107
+ return green(text)
108
+
109
+
110
+ def bold(text):
111
+ return colorize(text, Constants.BOLD)
112
+
113
+
114
+ def underline(text):
115
+ return colorize(text, Constants.UNDERLINE)
116
+
117
+
118
+ def blue(text):
119
+ return colorize(text, Constants.BLUE)
108
120
 
109
121
 
110
122
  def cyan(text):
111
- return colorize(text, Color.CYAN)
123
+ return colorize(text, Constants.CYAN)
112
124
 
113
125
 
114
126
  def green(text):
115
- return colorize(text, Color.GREEN)
127
+ return colorize(text, Constants.GREEN)
128
+
129
+
130
+ def grey(text):
131
+ return colorize(text, Constants.GREY)
116
132
 
117
133
 
118
134
  def red(text):
119
- return colorize(text, Color.RED)
135
+ return colorize(text, Constants.RED)
120
136
 
121
137
 
122
138
  def violet(text):
123
- return colorize(text, Color.VIOLET)
139
+ return colorize(text, Constants.VIOLET)
140
+
141
+
142
+ def white(text):
143
+ return colorize(text, Constants.WHITE2)
124
144
 
125
145
 
126
146
  def yellow(text):
127
- return colorize(text, Color.YELLOW)
147
+ return colorize(text, Constants.YELLOW)
@@ -347,6 +347,7 @@ class Configuration:
347
347
  json.dump(data, f, indent=2)
348
348
 
349
349
  def set_config_paths(self):
350
+ config_path = os.environ.get("GIBSONAI_CONFIG_PATH", None)
350
351
  gibson_config_dir = ".gibsonai"
351
352
  user_home = os.environ.get("HOME")
352
353
  if user_home is None:
@@ -354,7 +355,7 @@ class Configuration:
354
355
  "Gibson here. Please set your HOME environment variable."
355
356
  )
356
357
 
357
- self.paths.top = f"{user_home}/{gibson_config_dir}"
358
+ self.paths.top = config_path or f"{user_home}/{gibson_config_dir}"
358
359
  self.paths.auth = f"{self.paths.top}/auth"
359
360
  self.paths.config = f"{self.paths.top}/config"
360
361
 
gibson/core/Spinner.py ADDED
@@ -0,0 +1,37 @@
1
+ from yaspin import yaspin
2
+ from yaspin.spinners import Spinners
3
+
4
+
5
+ class Spinner:
6
+ def __init__(
7
+ self, start_text, success_text=None, fail_text=None, disappearing=False
8
+ ):
9
+ self.success_text = success_text or start_text
10
+ self.fail_text = fail_text or start_text
11
+ self.disappearing = disappearing
12
+ self.spinner = yaspin(
13
+ Spinners.binary,
14
+ text=start_text,
15
+ color="green",
16
+ )
17
+
18
+ def __enter__(self):
19
+ self.spinner.start()
20
+
21
+ def __exit__(self, exc_type, exc_val, exc_tb):
22
+ if exc_type is not None:
23
+ self.spinner.text = self.fail_text
24
+ self.spinner.fail("❌")
25
+ elif self.disappearing:
26
+ self.spinner.text = ""
27
+ self.spinner.stop()
28
+ else:
29
+ self.spinner.text = self.success_text
30
+ self.spinner.ok("✅")
31
+
32
+ self.spinner.stop()
33
+
34
+
35
+ class ComputingSpinner(Spinner):
36
+ def __init__(self):
37
+ super().__init__("Gibson is computing...", disappearing=True)
gibson/display/Header.py CHANGED
@@ -1,10 +1,9 @@
1
- import gibson.core.Colors as Colors
1
+ import math
2
2
 
3
3
 
4
4
  class Header:
5
- def render(self, text, color=None):
6
- output = text if color is None else Colors.colorize(text, color)
7
- header = "+-----------------------------------------------------------------------------+\n"
8
- header += "| " + output + " " * (76 - len(text)) + "|\n"
9
- header += "+-----------------------------------------------------------------------------+"
5
+ def render(self, text, colorizer=None):
6
+ output = text if colorizer is None else colorizer(text)
7
+ half = math.floor((78 - len(text)) / 2) # 80 line length - 2 spaces
8
+ header = "/" * half + f" {output} " + "/" * half
10
9
  return header
@@ -4,9 +4,9 @@ import gibson.core.Colors as Colors
4
4
  class WorkspaceFooter:
5
5
  def render(self):
6
6
  return (
7
- "=" * 79
7
+ "-" * 79
8
8
  + "\n"
9
- + f"[{Colors.red(':q')} + enter = {Colors.red('discard')} changes] "
9
+ + f"[{Colors.red(':q')} + enter = {Colors.red('discard')} changes] "
10
10
  + f"[{Colors.green(':wq')} + enter = {Colors.green('save')} changes + write code]\n\n"
11
- + "Using natural language, tell me how I can modify this entity."
11
+ + "Using natural language, tell me how I can modify this entity:"
12
12
  )
@@ -7,5 +7,5 @@ class WorkspaceHeader:
7
7
  f"Project {project_name}".ljust(50)
8
8
  + " " * 12
9
9
  + "[PAIR PROGRAMMER]\n"
10
- + "=" * 79
10
+ + "-" * 79
11
11
  ).replace(project_name, Colors.project(project_name))
@@ -3,8 +3,10 @@ from gibson.display.Header import Header
3
3
 
4
4
 
5
5
  def test_render():
6
- assert Header().render("abc def ghi") == (
7
- """+-----------------------------------------------------------------------------+
8
- | abc def ghi |
9
- +-----------------------------------------------------------------------------+"""
6
+ text = "abc def ghi"
7
+ assert Header().render(text) == (
8
+ "///////////////////////////////// abc def ghi /////////////////////////////////"
9
+ )
10
+ assert Header().render(text, Colors.red) == (
11
+ f"///////////////////////////////// {Colors.red(text)} /////////////////////////////////"
10
12
  )
@@ -4,8 +4,8 @@ from gibson.display.WorkspaceFooter import WorkspaceFooter
4
4
 
5
5
  def test_render():
6
6
  assert WorkspaceFooter().render() == (
7
- f"""===============================================================================
8
- [{Colors.red(':q')} + enter = {Colors.red('discard')} changes] [{Colors.green(':wq')} + enter = {Colors.green('save')} changes + write code]
7
+ f"""-------------------------------------------------------------------------------
8
+ [{Colors.red(':q')} + enter = {Colors.red('discard')} changes] [{Colors.green(':wq')} + enter = {Colors.green('save')} changes + write code]
9
9
 
10
- Using natural language, tell me how I can modify this entity."""
10
+ Using natural language, tell me how I can modify this entity:"""
11
11
  )
@@ -5,5 +5,5 @@ from gibson.display.WorkspaceHeader import WorkspaceHeader
5
5
  def test_render():
6
6
  assert WorkspaceHeader().render("abc def ghi") == (
7
7
  f"""Project {Colors.project("abc def ghi")} [PAIR PROGRAMMER]
8
- ==============================================================================="""
8
+ -------------------------------------------------------------------------------"""
9
9
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gibson-cli
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: Gibson Command Line Interface
5
5
  Author-email: GibsonAI <noc@gibsonai.com>
6
6
  Project-URL: Homepage, https://gibsonai.com/
@@ -65,6 +65,7 @@ Requires-Dist: uvicorn==0.29.0
65
65
  Requires-Dist: uvloop==0.19.0
66
66
  Requires-Dist: watchfiles==0.21.0
67
67
  Requires-Dist: websockets==12.0
68
+ Requires-Dist: yaspin==3.1.0
68
69
 
69
70
 
70
71
  [![GibsonAI](https://github.com/user-attachments/assets/26bc1002-f878-4995-a6c5-eb8d5eb69c28)](https://gibsonai.com/)
@@ -4,21 +4,21 @@ bin/release.sh,sha256=LxPqH5kxhLKvzHaPRLBlq_ApaK7FHEteH4SzeRenidk,49
4
4
  gibson/api/BaseApi.py,sha256=2vLcb4xYBAtMhCzhxAesEdan7FSxxD0eBC3EkPsW7Uk,3055
5
5
  gibson/api/Cli.py,sha256=4MWxLWV2Sl_VQGwnu_k2b7L-pFSIrEMTcgCkMxI2ojA,8065
6
6
  gibson/api/ProjectApi.py,sha256=T7TqtywJjrzFIfARenQUsrH-80x9Oo1pABbFAdlQkI0,356
7
- gibson/bin/gibson.py,sha256=N1mAWaww9pw8s5u0et87FC5cFHVU6JzN4Kls3lDn-xw,354
7
+ gibson/bin/gibson.py,sha256=56fqPBiF47uJvafHyNbWZ4GorcI0Ut98DCXeS7dt2io,420
8
8
  gibson/command/BaseCommand.py,sha256=mmWUO0FxjMCbv3cHWnnasfAWnU_hTuGHUsRVJ4hUcqM,777
9
9
  gibson/command/Build.py,sha256=FVvabrp7pGohvKS6CR30CGm-fcro7QbS-MxtKzXs4pc,4485
10
10
  gibson/command/Conf.py,sha256=MbEPT-lRujRJMBjKRQlshA3T3pplQ-zzia8RY_muWU4,2472
11
11
  gibson/command/Count.py,sha256=Jh9_ImJibpiTitbllSl0xF6KUrOhrY7Bz7-5sx9cBVs,1083
12
12
  gibson/command/Dev.py,sha256=-kmRHpOApUXklaCs4bJVqCRft4ubcVjAL7S1-BGr-ps,4355
13
13
  gibson/command/Forget.py,sha256=5fszuq6oIe0unMbXpFtDpouJ1eYZIvsi2mLsa8RwN5U,1061
14
- gibson/command/Help.py,sha256=rsC5I0GZcblejAH34msbQjcB-LoDOt9WPoepPmNzweI,4285
14
+ gibson/command/Help.py,sha256=-ZBTaTONmb7Bsi6TeyNIW4pxQwUJgNBVy0f4UKNNTSk,4301
15
15
  gibson/command/Merge.py,sha256=R5ybMC1tUR5_T8YyUfXutzFa_V9j1_flv0s7KTJRq0M,1061
16
16
  gibson/command/Modify.py,sha256=3_fEGvLfGpgoXQ77SFA9J2KQDe1GMaAUPWkl-yCwR1E,1267
17
17
  gibson/command/Question.py,sha256=RIR-TorVnQCD74wYV2jIwfnIh0pOfnNIbcWBpBmf5FM,3926
18
18
  gibson/command/Remove.py,sha256=fRPJCTCQFZVfl6Ri319E1ZudADkbWBZUOPiBue1Vrao,2512
19
19
  gibson/command/Show.py,sha256=BOfgQQSo-q6RMWPgiyjcigwuW-fQmnQwUWdRbsslto8,1529
20
20
  gibson/command/Tree.py,sha256=BeJ_13xrrRCK5FP2rQHWpDKrshVzte-_D1pNG1GXPIw,3056
21
- gibson/command/Version.py,sha256=YLd2c9eiVT6Xzj-ulRuL9QSiu21Fid2Jp_B7nD6k86o,1267
21
+ gibson/command/Version.py,sha256=zA3VtFHJm9UQFpQV69gxKFuNFJUpmKxvqoE_CEkWaQM,1198
22
22
  gibson/command/WarGames.py,sha256=V0KIpz-Z546qtQaOPdIVHQ6wp2n3r3M3tgKx-GRQzzU,1300
23
23
  gibson/command/auth/Auth.py,sha256=U8i5a7hKVjYgiJgS0kbwEmgHPCzRbMkJ8x2g6odQWSM,1204
24
24
  gibson/command/auth/Login.py,sha256=b43OfV76i6aGdOwj1NK64ZOdYlNyc08g3lZGQ_37KDw,437
@@ -26,12 +26,12 @@ gibson/command/auth/Logout.py,sha256=V01q4TdbiBqCnIrM6IA4T25fO6ws0UpXp42I3pwHZVM
26
26
  gibson/command/code/Api.py,sha256=sSvAqEJXdgQjYcu0uiM6ndHE3GnfkfVL6eqP2Otkbww,1002
27
27
  gibson/command/code/Base.py,sha256=YJ2a5Hl0f9NXHUBBPvlt-dUIqEPWQz5vH6-1EHmbFbA,640
28
28
  gibson/command/code/Code.py,sha256=Ce8jilFWl1B7Djabf4KoN3s8IgQPQchhxwOis0nFXvM,4234
29
- gibson/command/code/Entity.py,sha256=MQHtxu_dxd592XA8JYtcOkHeOKqgYC_O6dNbgGI2EMY,6937
30
- gibson/command/code/Model.py,sha256=UzJOmxgl0nEWRPuP_plKFpPmbFfW3uvur76Kv5QcjjA,1112
29
+ gibson/command/code/Entity.py,sha256=MJLGi-8a69X3KDMtXX8j6hsDvdhnI05fJUm3p2WfjN4,7779
30
+ gibson/command/code/Model.py,sha256=fEg0A-NjNLHx4I7-FoMVI5ClDf0UcCkKcti2Z-3rnwY,1340
31
31
  gibson/command/code/Models.py,sha256=eoUpZHpR0qwNgX60EWfcNz49GHmBw_FGfBuHH2ueZqY,799
32
- gibson/command/code/Schema.py,sha256=aYp-MzNB6UPvtCvoGN0X1JZQ3QYN5ldHtlxb2kGKR08,1116
32
+ gibson/command/code/Schema.py,sha256=3f6iWoq6xzdj9NU3_WrByo7AUj0Tpo2CxtUzkIx73nQ,1346
33
33
  gibson/command/code/Schemas.py,sha256=zZ1gjmOJg77gh70t5y2WkzHWSAvEKx5-gqRN9OcsCXA,802
34
- gibson/command/code/Test.py,sha256=JgUe5AB7xMw8tHnEaKqUCqRL895nlnwe34GRkOa6P0Y,1107
34
+ gibson/command/code/Test.py,sha256=XjhiepDXUgMySYMmWyhBYfUHlm_QHzROiAXMG2u2jOw,1333
35
35
  gibson/command/code/Tests.py,sha256=HO1WM6pSToVKsuJn7nUA_I5qrfBN0cgKgBzjlm2Qxt8,799
36
36
  gibson/command/importer/Import.py,sha256=qW__kT7xruUgg2kTZG-80Jah94aqQ7nvd89dZW4uxcg,6792
37
37
  gibson/command/importer/OpenApi.py,sha256=voTthxb0KDTlkEsHsIeJnyMxgEBbJKw9VTKDyGehopI,3759
@@ -43,7 +43,7 @@ gibson/command/new/New.py,sha256=-T4KobVOAKfHy3FGlqZnSWOOHEQGbRJH9AuN-4rUysA,169
43
43
  gibson/command/new/Project.py,sha256=Cw1Z6TvPIGhTi7GiQZ2VFjv6hXdpGKQdX9HuAd5gric,759
44
44
  gibson/command/rename/Entity.py,sha256=SaAiN1bYsTOsqjyVzxghK8-N3sAKITThTzS5LEYgppY,1801
45
45
  gibson/command/rename/Rename.py,sha256=T6iTjo6KRArbT8wBgrn-ehtNlY7tRlovlEZfBOUKYlk,731
46
- gibson/command/rewrite/Rewrite.py,sha256=u7FMLbj0wyX2Hl5NFooaQ_rewL7LMn6bXHoMXilCtys,4553
46
+ gibson/command/rewrite/Rewrite.py,sha256=pYg6ephFXVpZlew5bSb3dTt5nxQH3DBDf6cz67Jn434,4482
47
47
  gibson/command/tests/test_command_BaseCommand.py,sha256=hSbBfLFI3RTp_DdEHtm5oOLWoN6drI6ucFJypi7xxV8,364
48
48
  gibson/command/tests/test_command_Conf.py,sha256=5eBuCjEfskjb-JujwwUDQLFKjc3uThO4cJj148JoxkE,597
49
49
  gibson/conf/Api.py,sha256=GM9okYs1A8ujPjDwzziOoQpqRYFkr-dz5pgkfb6j4DI,59
@@ -64,14 +64,15 @@ gibson/conf/dev/Model.py,sha256=HbHRX3VDxR7hXlzuxkKw4Bf7FH6XMfQ96k9BeIUoBf4,73
64
64
  gibson/conf/dev/Schema.py,sha256=kOSlX1jEyVb82xd8TO8jEAimLcaefIFJr6d2JYvyTqg,74
65
65
  gibson/conf/tests/test_conf_Dependencies.py,sha256=LITeeYiqXM5rKkyWFBqcnMvUR5pzDRuHVAngH372jWc,116
66
66
  gibson/conf/tests/test_conf_Platform.py,sha256=Zc53IsZmV-hT9VRrZEPNrsuehSdWnJXWKGMmOhEqWHo,138
67
- gibson/core/Colors.py,sha256=dGafcWxDrUV5BcHUdzH2xIlueZW6RgkhFyOWgZ0tfL4,2531
67
+ gibson/core/Colors.py,sha256=BpzD1KQY3TVUWu8nH7q4ebA5hSar_8UiXED-XuJsBwQ,2727
68
68
  gibson/core/CommandRouter.py,sha256=G_4_OToiBQUgvZbO_yuIqYGus0FtV_sk6s9LzGwR4RY,3227
69
69
  gibson/core/Completions.py,sha256=Bsh25vnf0pjpJA6MJNR_2MA2s58Ujj8XolR8fm8AQ_s,1197
70
- gibson/core/Configuration.py,sha256=c_YX0GFmiTIr4V0-2GmOuAipdq-WKO6QU2oHtPLP4iU,15784
70
+ gibson/core/Configuration.py,sha256=sGqTRKoM0NaYuL9FKJ1oh5VttZRVshMCp5IgIHABtRA,15866
71
71
  gibson/core/Conversation.py,sha256=X9SeD9kBLmzEbZAOOTTZYV42HhHx-ud_HO_t20D33LA,10383
72
72
  gibson/core/Env.py,sha256=08dZRHzzR0ahrbM4S0bXC7V1xhYQkT8Zefs00qUHf0U,498
73
73
  gibson/core/Memory.py,sha256=kAo9kFgsIAVrofTRepv81pw43Sl2zQrNFsfIy_yMb_w,4037
74
74
  gibson/core/PythonPath.py,sha256=p1q7n_5KnPvA8XbxJyvqC2vrIdEdTiMr6vRU9yj77Cs,1567
75
+ gibson/core/Spinner.py,sha256=ditGikEUpRB1ttwRJNQ6Dbw_SzWtEd1wh_82vV8UfCY,1036
75
76
  gibson/core/TimeKeeper.py,sha256=dSeIgGOQJOi0ULlFGAigroGTBfAZXrvP9a1Op_jIsZ0,300
76
77
  gibson/core/utils.py,sha256=KTnPvA3sUYnLFTZG7Tke5YEdls8Da0rNbeaOm8hapiU,408
77
78
  gibson/data/bash-completion.tmpl,sha256=-w5y4g3ZYN-7eBlIzu7Kh-RM-X2kYCf0Yp6RXNQozsM,2657
@@ -82,12 +83,12 @@ gibson/data/postgresql/default-table.tmpl,sha256=4xON0XyY55OiZhZmJ4RemnKMNFLniuS
82
83
  gibson/db/TableExceptions.py,sha256=LGDPxAVjXmb0EJSFpHC6twHoFzv7nFsFzTj2DXNabQU,196
83
84
  gibson/db/tests/test_db_TableExceptions.py,sha256=tNzn6SybygWXSuj-3i_s6t9LOo1P8gI9S4wSz4UxeCk,312
84
85
  gibson/dev/Dev.py,sha256=O-GiMATpVd9kYHsVfbHaC-Omh17HQ8FalFQNelfxh2s,2544
85
- gibson/display/Header.py,sha256=Lx7C50pqJiBOo_UgnPXkqL1XhdM1zPFEeEg5CdvPyr0,453
86
- gibson/display/WorkspaceFooter.py,sha256=qMM-tu9ZPA1E_-uyvrt6rwqXMXMvg5vR817WXmdCEFU,408
87
- gibson/display/WorkspaceHeader.py,sha256=y05g_RyRWwTeJ5hPpCizYaT-oHWu7htjZwatY8Qo2Lg,306
88
- gibson/display/tests/test_display_Header.py,sha256=0UWumN0kHjuVYp-Sf707yZgzoMvYt5jUAfWuhoiWwh8,405
89
- gibson/display/tests/test_display_WorkspaceFooter.py,sha256=EmjK-Yc3uPPaQQKebo1SWt6rUmsPo2imWgpIVb_CLiU,464
90
- gibson/display/tests/test_display_WorkspaceHeader.py,sha256=bdfWVmnyLd6f28wL1zEANZglX32tz2zEIKvQf9qK-X4,373
86
+ gibson/display/Header.py,sha256=A6KW4lgCrH67tqi7VrKucVn7lH-lJ-hd3yIauZxhv_A,292
87
+ gibson/display/WorkspaceFooter.py,sha256=Mh18foAb33O1adnecLe7elIqBN8u2ewaSURl99qlcvE,415
88
+ gibson/display/WorkspaceHeader.py,sha256=zqWa9xh3I8ky0ghYRmLdpUr4TXSBRyaIIyyVfYsfMQU,306
89
+ gibson/display/tests/test_display_Header.py,sha256=gppahcCu3VXQMyIZiB_ixAS-ZygrTtkrx62IGFlWQOk,411
90
+ gibson/display/tests/test_display_WorkspaceFooter.py,sha256=HBcZ48UwEsJsNEXPcPH8UiuF0Wa15vffEkJILNhwPyw,471
91
+ gibson/display/tests/test_display_WorkspaceHeader.py,sha256=8aY62ucD_YfP4DiqsWA3f_PZ9CNr096TuG1vUv0MoVE,373
91
92
  gibson/lang/Python.py,sha256=WNbCTFhDh9qXVbeySyfaP-6m-c0wllSCZw8A-r_Z0Oo,1764
92
93
  gibson/lang/tests/test_lang_Python.py,sha256=YpdqYOGAssg-jP9GuzfoU4Y4L7Boj0vAUAJgjuZvedo,1862
93
94
  gibson/services/auth/Server.py,sha256=DfemWNZlZ3rDE6PsAAvDP0anK7czwhiadX6Wilo4agY,1936
@@ -124,8 +125,8 @@ gibson/structure/tests/test_structure_Entity.py,sha256=askl8w0p1uqET6HKBogJlRcPP
124
125
  gibson/tests/test_Env.py,sha256=DPWmP0-aEelducq9bAwv7rKoY2NjWXUeCrzfJDQkn2M,369
125
126
  gibson/tests/test_Memory.py,sha256=YP7owToABAk_-s7fD5UG0HTc4lamDjdA39JUlLnk3Fg,2574
126
127
  gibson/tests/test_utils.py,sha256=r_y-EG05YTCNtL8MWiAK1KmPsmeoMgypKsQC_lVgOtM,559
127
- gibson_cli-0.7.2.dist-info/METADATA,sha256=7B6rodHdoyquS6V_sR3QoLpYtlUk22S5UigseI_to74,13142
128
- gibson_cli-0.7.2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
129
- gibson_cli-0.7.2.dist-info/entry_points.txt,sha256=j5VUvq3AzL21xPvVC24zMoXFt-I5lUWulr66nL3OAPM,50
130
- gibson_cli-0.7.2.dist-info/top_level.txt,sha256=RFaUY7VXGiqkMwo1Rj7pM4kGvxkhhnfo-2LmPpuL_fs,11
131
- gibson_cli-0.7.2.dist-info/RECORD,,
128
+ gibson_cli-0.7.4.dist-info/METADATA,sha256=Nx8vTtLVMaHx3zpI_G3Pi_Xl0VZ8KjdHTdj3MJLpnrI,13171
129
+ gibson_cli-0.7.4.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
130
+ gibson_cli-0.7.4.dist-info/entry_points.txt,sha256=j5VUvq3AzL21xPvVC24zMoXFt-I5lUWulr66nL3OAPM,50
131
+ gibson_cli-0.7.4.dist-info/top_level.txt,sha256=RFaUY7VXGiqkMwo1Rj7pM4kGvxkhhnfo-2LmPpuL_fs,11
132
+ gibson_cli-0.7.4.dist-info/RECORD,,