gibson-cli 0.7.5__py3-none-any.whl → 0.7.6__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.
Files changed (41) hide show
  1. bin/gibson +26 -0
  2. gibson/api/BaseApi.py +1 -1
  3. gibson/api/Cli.py +1 -1
  4. gibson/command/Build.py +6 -6
  5. gibson/command/Conf.py +1 -2
  6. gibson/command/Count.py +1 -1
  7. gibson/command/Dev.py +5 -8
  8. gibson/command/Forget.py +1 -1
  9. gibson/command/Help.py +112 -47
  10. gibson/command/Modify.py +2 -4
  11. gibson/command/Question.py +2 -4
  12. gibson/command/Remove.py +2 -2
  13. gibson/command/Show.py +3 -5
  14. gibson/command/Version.py +1 -1
  15. gibson/command/auth/Auth.py +3 -3
  16. gibson/command/code/Code.py +10 -10
  17. gibson/command/code/Entity.py +10 -3
  18. gibson/command/code/Model.py +2 -4
  19. gibson/command/code/Schema.py +9 -8
  20. gibson/command/code/Test.py +1 -3
  21. gibson/command/importer/Import.py +8 -8
  22. gibson/command/importer/OpenApi.py +1 -1
  23. gibson/command/list/Entities.py +25 -37
  24. gibson/command/list/List.py +3 -3
  25. gibson/command/list/Projects.py +23 -13
  26. gibson/command/new/Module.py +2 -2
  27. gibson/command/new/New.py +4 -4
  28. gibson/command/rename/Rename.py +1 -1
  29. gibson/command/rewrite/Rewrite.py +1 -1
  30. gibson/core/Colors.py +34 -7
  31. gibson/core/CommandRouter.py +0 -1
  32. gibson/core/Configuration.py +8 -3
  33. gibson/core/Conversation.py +17 -24
  34. gibson/core/Memory.py +1 -0
  35. gibson/core/Spinner.py +8 -3
  36. {gibson_cli-0.7.5.dist-info → gibson_cli-0.7.6.dist-info}/METADATA +16 -7
  37. {gibson_cli-0.7.5.dist-info → gibson_cli-0.7.6.dist-info}/RECORD +40 -40
  38. {gibson_cli-0.7.5.dist-info → gibson_cli-0.7.6.dist-info}/WHEEL +1 -1
  39. gibson/command/WarGames.py +0 -34
  40. {gibson_cli-0.7.5.dist-info → gibson_cli-0.7.6.dist-info}/entry_points.txt +0 -0
  41. {gibson_cli-0.7.5.dist-info → gibson_cli-0.7.6.dist-info}/top_level.txt +0 -0
@@ -14,9 +14,7 @@ class Schema(BaseCommand):
14
14
  self.configuration.require_project()
15
15
  entity = self.memory.recall_stored_entity(entity_name)
16
16
  if entity is None:
17
- self.conversation.not_sure_no_entity(
18
- self.configuration.project.name, entity_name
19
- )
17
+ self.conversation.not_sure_no_entity(self.configuration, entity_name)
20
18
  exit(1)
21
19
 
22
20
  time_keeper = TimeKeeper()
@@ -24,15 +22,18 @@ class Schema(BaseCommand):
24
22
  with Spinner("Gibson is writing the schemas...", "Schemas written"):
25
23
  cli = Cli(self.configuration)
26
24
  response = cli.code_schemas([entity["name"]])
27
- Dev(self.configuration).schema(
28
- response["code"][0]["entity"]["name"], response["code"][0]["definition"]
29
- )
25
+ code = response["code"][0] if len(response["code"]) > 0 else None
26
+ if code:
27
+ Dev(self.configuration).schema(
28
+ code["entity"]["name"], code["definition"]
29
+ )
30
30
 
31
- if self.configuration.project.dev.active is True:
31
+ if code and self.configuration.project.dev.active is True:
32
32
  self.conversation.type(
33
33
  f"\nGibson wrote the following {Colors.argument('schema')} code to your project:\n"
34
34
  )
35
35
 
36
36
  if not self.conversation.muted():
37
- print(response["code"][0]["definition"])
37
+ if code:
38
+ print(code["definition"])
38
39
  time_keeper.display()
@@ -14,9 +14,7 @@ class Test(BaseCommand):
14
14
  self.configuration.require_project()
15
15
  entity = self.memory.recall_stored_entity(entity_name)
16
16
  if entity is None:
17
- self.conversation.not_sure_no_entity(
18
- self.configuration.project.name, entity_name
19
- )
17
+ self.conversation.not_sure_no_entity(self.configuration, entity_name)
20
18
  exit(1)
21
19
 
22
20
  time_keeper = TimeKeeper()
@@ -56,7 +56,7 @@ class Import(BaseCommand):
56
56
  self.conversation.type("Building schema...\n")
57
57
 
58
58
  for entity in response["project"]["entities"]:
59
- self.conversation.type(f" {entity['name']}\n", delay=0.002)
59
+ self.conversation.type(f" {entity['name']}\n")
60
60
 
61
61
  return response["project"]["entities"]
62
62
 
@@ -74,7 +74,7 @@ class Import(BaseCommand):
74
74
  entities = []
75
75
  for table in tables:
76
76
  if table[0] not in table_exceptions:
77
- self.conversation.type(f" {table[0]}\n", delay=0.002)
77
+ self.conversation.type(f" {table[0]}\n")
78
78
 
79
79
  create_statement = session.execute(
80
80
  f"show create table {table[0]}"
@@ -139,7 +139,7 @@ class Import(BaseCommand):
139
139
 
140
140
  entities = []
141
141
  for table_name, definition in tables.items():
142
- self.conversation.type(f" {table_name}\n", delay=0.002)
142
+ self.conversation.type(f" {table_name}\n")
143
143
 
144
144
  definition[-1] = definition[-1].rstrip(",")
145
145
 
@@ -160,19 +160,19 @@ class Import(BaseCommand):
160
160
  else ""
161
161
  )
162
162
  self.conversation.type(
163
- f"usage: {Colors.command(self.configuration.command)} {Colors.subcommand('import')} {Colors.arguments(['api', 'mysql', 'pg_dump', 'openapi'])} {Colors.hint('import entities')}\n"
163
+ f"usage: {Colors.command(self.configuration.command, 'import', args=['api', 'mysql', 'pg_dump', 'openapi'], hint='import entities')}\n"
164
164
  )
165
165
  self.conversation.type(
166
- f" {Colors.command(self.configuration.command)} {Colors.subcommand('import')} {Colors.argument('api')} {Colors.hint(f'import all entities from your project created on {Colors.link(self.configuration.app_domain())}')}\n"
166
+ f" {Colors.command(self.configuration.command, 'import', args='api', hint=f'import all entities from your project created on {Colors.link(self.configuration.app_domain())}')}\n"
167
167
  )
168
168
  self.conversation.type(
169
- f" {Colors.command(self.configuration.command)} {Colors.subcommand('import')} {Colors.argument('mysql')} {Colors.hint('import all entities from your MySQL database')} ({Colors.link(datastore_uri)})\n"
169
+ f" {Colors.command(self.configuration.command, 'import', args='mysql', hint='import all entities from your MySQL database')} ({Colors.link(datastore_uri)})\n"
170
170
  )
171
171
  self.conversation.type(
172
- f" {Colors.command(self.configuration.command)} {Colors.subcommand('import')} {Colors.argument('pg_dump')} {Colors.input('path/to/pg_dump.sql')} {Colors.hint('import all entities from a pg_dump file')}\n"
172
+ f" {Colors.command(self.configuration.command, 'import', args='pg_dump', inputs='path/to/pg_dump.sql', hint='import all entities from a pg_dump file')}\n"
173
173
  )
174
174
  self.conversation.type(
175
- f" {Colors.command(self.configuration.command)} {Colors.subcommand('import')} {Colors.argument('openapi')} {Colors.input('path/to/openapi.json')} {Colors.hint('import all entities from an OpenAPI spec file')}\n"
175
+ f" {Colors.command(self.configuration.command, 'import', args='openapi', inputs='path/to/openapi.json', hint='import all entities from an OpenAPI spec file')}\n"
176
176
  )
177
177
  self.conversation.newline()
178
178
  exit(1)
@@ -46,7 +46,7 @@ class OpenApi(BaseCommand):
46
46
 
47
47
  i = 0
48
48
  for path in path_list:
49
- self.conversation.type(f" {i}: ".rjust(10) + path + "\n", delay=0.0009)
49
+ self.conversation.type(f" {i}: ".rjust(10) + path + "\n")
50
50
  i += 1
51
51
 
52
52
  self.conversation.newline()
@@ -1,5 +1,10 @@
1
1
  import sys
2
2
 
3
+ from rich import box
4
+ from rich.console import Console
5
+ from rich.table import Table
6
+ from rich.text import Text
7
+
3
8
  from gibson.command.BaseCommand import BaseCommand
4
9
 
5
10
 
@@ -8,44 +13,27 @@ class Entities(BaseCommand):
8
13
  self.configuration.require_project()
9
14
  self.configuration.display_project()
10
15
 
11
- entities = {"last": [], "stored": []}
12
-
13
- last = self.memory.recall_last()
14
- if last is not None:
15
- for entity in last["entities"]:
16
- entities["last"].append(entity["name"])
17
-
18
- stored = self.memory.recall_entities()
19
- if stored is not None:
20
- for entity in stored:
21
- entities["stored"].append(entity["name"])
16
+ last = self.memory.recall_last() or []
17
+ stored = self.memory.recall_entities() or []
22
18
 
23
- if len(entities["last"]) == 0 and len(entities["stored"]) == 0:
19
+ if len(last) == 0 and len(stored) == 0:
24
20
  self.conversation.nothing_to_list(sys.argv[2])
25
21
  self.conversation.newline()
26
22
  else:
27
- self.conversation.type(" Name".ljust(60), delay=0.0001)
28
- self.conversation.type("Memory", delay=0.002)
29
- self.conversation.newline()
30
- self.conversation.type(" ----".ljust(60), delay=0.0001)
31
- self.conversation.type("------", delay=0.002)
32
- self.conversation.newline()
33
-
34
- entities["last"].sort()
35
- entities["stored"].sort()
36
-
37
- if len(entities["stored"]) > 0:
38
- for entity in entities["stored"]:
39
- self.conversation.type(f" {entity}".ljust(60), delay=0.0001)
40
- self.conversation.type("[stored]", delay=0.002)
41
- self.conversation.newline()
42
-
43
- self.conversation.newline()
44
-
45
- if len(entities["last"]) > 0:
46
- for entity in entities["last"]:
47
- self.conversation.type(f" {entity}".ljust(60), delay=0.0001)
48
- self.conversation.type("[last]", delay=0.002)
49
- self.conversation.newline()
50
-
51
- self.conversation.newline()
23
+ console = Console()
24
+ table = Table(
25
+ title="Entities",
26
+ header_style="bold",
27
+ box=box.ROUNDED,
28
+ leading=1,
29
+ )
30
+ table.add_column("Name", style="magenta", header_style="magenta")
31
+ table.add_column("Memory")
32
+
33
+ for entity in sorted(stored, key=lambda x: x["name"]):
34
+ table.add_row(entity["name"], Text("stored", style="green"))
35
+
36
+ for entity in sorted(last, key=lambda x: x["name"]):
37
+ table.add_row(entity["name"], Text("last", style="yellow"))
38
+
39
+ console.print(table)
@@ -18,13 +18,13 @@ class List(BaseCommand):
18
18
  def usage(self):
19
19
  self.configuration.display_project()
20
20
  self.conversation.type(
21
- f"usage: {Colors.command(self.configuration.command)} {Colors.subcommand('list')} {Colors.arguments(['entities', 'projects'])}\n"
21
+ f"usage: {Colors.command(self.configuration.command, 'list', args=['entities', 'projects'])}\n"
22
22
  )
23
23
  self.conversation.type(
24
- f" {Colors.command(self.configuration.command)} {Colors.subcommand('list')} {Colors.argument('entities')} {Colors.hint('list all entities')}\n"
24
+ f" {Colors.command(self.configuration.command, 'list', args='entities', hint='list all entities')}\n"
25
25
  )
26
26
  self.conversation.type(
27
- f" {Colors.command(self.configuration.command)} {Colors.subcommand('list')} {Colors.argument('projects')} {Colors.hint('list all projects')}\n"
27
+ f" {Colors.command(self.configuration.command, 'list', args='projects', hint='list all projects')}\n"
28
28
  )
29
29
  self.conversation.newline()
30
30
  exit(1)
@@ -1,31 +1,41 @@
1
- import re
1
+ from rich import box
2
+ from rich.console import Console
3
+ from rich.table import Table
2
4
 
3
5
  import gibson.core.Colors as Colors
4
6
  from gibson.api.ProjectApi import ProjectApi
5
7
  from gibson.command.BaseCommand import BaseCommand
8
+ from gibson.core.Spinner import DisappearingSpinner
6
9
 
7
10
 
8
11
  class Projects(BaseCommand):
9
12
  def execute(self):
10
13
  self.configuration.require_login()
11
- projects = ProjectApi(self.configuration).all_projects()
14
+
15
+ with DisappearingSpinner():
16
+ projects = ProjectApi(self.configuration).all_projects()
12
17
 
13
18
  if len(projects) == 0:
14
19
  self.conversation.type(
15
- f"No projects found. Create one with {Colors.command('gibson')} {Colors.subcommand('new')} {Colors.argument('project')}\n"
20
+ f"No projects found. Create one with {Colors.command(self.configuration.command, 'new', args='project')}\n"
16
21
  )
17
22
  exit(1)
18
23
 
19
- self.conversation.type("Name".ljust(40))
20
- self.conversation.type("ID")
21
- self.conversation.newline()
22
- self.conversation.type("----".ljust(40))
23
- self.conversation.type("-" * 36)
24
- self.conversation.newline()
24
+ console = Console()
25
+ table = Table(
26
+ title="Projects",
27
+ header_style="bold magenta",
28
+ box=box.ROUNDED,
29
+ leading=1,
30
+ )
31
+ table.add_column("Name")
32
+ table.add_column("ID", min_width=36)
25
33
 
26
34
  for project in projects:
27
35
  name = project["name"] if project["name"] is not None else "Untitled"
28
- name = re.sub(r"^(.{36}).*$", "\g<1>...", name).ljust(40)
29
- self.conversation.type(f"{Colors.command(name)}")
30
- self.conversation.type(f"{project['uuid']}")
31
- self.conversation.newline()
36
+ table.add_row(
37
+ name,
38
+ project["uuid"],
39
+ )
40
+
41
+ console.print(table)
@@ -34,7 +34,7 @@ class Module(BaseCommand):
34
34
  self.conversation.newline()
35
35
  self.conversation.type(f"If you want to persist these new entities run:\n")
36
36
  self.conversation.type(
37
- f"{Colors.command(self.configuration.command)} {Colors.subcommand('merge')}\n"
37
+ f"{Colors.command(self.configuration.command, 'merge')}\n"
38
38
  )
39
39
 
40
40
  self.conversation.newline()
@@ -42,5 +42,5 @@ class Module(BaseCommand):
42
42
  f"Afterwards, you can modify any of these entities by running:\n"
43
43
  )
44
44
  self.conversation.type(
45
- f"{Colors.command(self.configuration.command)} {Colors.subcommand('modify')} {Colors.argument('[entity name]')} {Colors.input('[instructions]')}\n"
45
+ f"{Colors.command(self.configuration.command, 'modify', inputs=['[entity name]', '[instructions]'])}\n"
46
46
  )
gibson/command/new/New.py CHANGED
@@ -21,16 +21,16 @@ class New(BaseCommand):
21
21
  def usage(self):
22
22
  self.configuration.display_project()
23
23
  self.conversation.type(
24
- f"usage: {Colors.command(self.configuration.command)} {Colors.subcommand('new')} {Colors.arguments(['project', 'module', 'entity'])} {Colors.hint('create something new')}\n"
24
+ f"usage: {Colors.command(self.configuration.command, 'new', args=['project', 'module', 'entity'], hint='create something new')}\n"
25
25
  )
26
26
  self.conversation.type(
27
- f" {Colors.command(self.configuration.command)} {Colors.subcommand('new')} {Colors.argument('project')} {Colors.hint('create a new project')}\n"
27
+ f" {Colors.command(self.configuration.command, 'new', args='project', hint='create a new project')}\n"
28
28
  )
29
29
  self.conversation.type(
30
- f" {Colors.command(self.configuration.command)} {Colors.subcommand('new')} {Colors.argument('module')} {Colors.hint('create a new module')}\n"
30
+ f" {Colors.command(self.configuration.command, 'new', args='module', hint='create a new module')}\n"
31
31
  )
32
32
  self.conversation.type(
33
- f" {Colors.command(self.configuration.command)} {Colors.subcommand('new')} {Colors.argument('entity')} {Colors.input('[entity name]')} {Colors.hint('create a new entity')}\n"
33
+ f" {Colors.command(self.configuration.command, 'new', args='entity', inputs='[entity name]', hint='create a new entity')}\n"
34
34
  )
35
35
  self.conversation.newline()
36
36
  exit(1)
@@ -15,7 +15,7 @@ class Rename(BaseCommand):
15
15
  def usage(self):
16
16
  self.configuration.display_project()
17
17
  self.conversation.type(
18
- f"usage: {Colors.command(self.configuration.command)} {Colors.subcommand('rename')} {Colors.argument('entity')} {Colors.input('[existing name]')} {Colors.input('[new name]')} {Colors.hint('rename an entity')}\n"
18
+ f"usage: {Colors.command(self.configuration.command, 'rename', args='entity', inputs=['[existing name]', '[new name]'], hint='rename an entity')}\n"
19
19
  )
20
20
  self.conversation.newline()
21
21
  exit(1)
@@ -115,7 +115,7 @@ class Rewrite(BaseCommand):
115
115
  def usage(self):
116
116
  self.configuration.display_project()
117
117
  self.conversation.type(
118
- f"usage: {Colors.command(self.configuration.command)} {Colors.subcommand('rewrite')} {Colors.hint('rewrite all code')}\n"
118
+ f"usage: {Colors.command(self.configuration.command, 'rewrite', hint='rewrite all code')}\n"
119
119
  )
120
120
  self.conversation.newline()
121
121
  exit(1)
gibson/core/Colors.py CHANGED
@@ -46,8 +46,30 @@ def colorize(text, color):
46
46
 
47
47
 
48
48
  # Colorize a command
49
- def command(text):
50
- return green(text)
49
+ def command(
50
+ command,
51
+ sub=None,
52
+ args=None,
53
+ inputs=None,
54
+ hint=None,
55
+ ):
56
+ parts = [green(command)]
57
+ if sub:
58
+ parts.append(subcommand(sub))
59
+ if args:
60
+ if isinstance(args, list):
61
+ parts.append(arguments(args))
62
+ else:
63
+ parts.append(argument(args))
64
+ if inputs:
65
+ if isinstance(inputs, list):
66
+ for input_ in inputs:
67
+ parts.append(user_input(input_))
68
+ else:
69
+ parts.append(user_input(inputs))
70
+ if hint:
71
+ parts.append(grey(hint))
72
+ return " ".join(parts)
51
73
 
52
74
 
53
75
  # Colorize a subcommand
@@ -66,7 +88,7 @@ def arguments(list):
66
88
 
67
89
 
68
90
  # Colorize user input
69
- def input(text):
91
+ def user_input(text):
70
92
  return white(text)
71
93
 
72
94
 
@@ -90,15 +112,20 @@ def link(text):
90
112
  return underline(blue(text))
91
113
 
92
114
 
115
+ # Colorize an entity name
116
+ def entity(text):
117
+ return bold(violet(text))
118
+
119
+
93
120
  # Colorize the table name in a SQL statement
94
121
  def table(sql, name):
95
- return sql.replace(name, violet(name))
122
+ return sql.replace(name, entity(name), 1)
96
123
 
97
124
 
98
125
  # Colorize the table name in model code
99
- def model(code, name):
100
- return code.replace(
101
- f'__tablename__ = "{name}"', f'__tablename__ = "{violet(name)}"'
126
+ def model(code, model_name, entity_name):
127
+ return code.replace(model_name, entity(model_name), 1).replace(
128
+ f'__tablename__ = "{entity_name}"', f'__tablename__ = "{entity(entity_name)}"'
102
129
  )
103
130
 
104
131
 
@@ -20,7 +20,6 @@ from gibson.command.rewrite.Rewrite import Rewrite
20
20
  from gibson.command.Show import Show
21
21
  from gibson.command.Tree import Tree
22
22
  from gibson.command.Version import Version
23
- from gibson.command.WarGames import WarGames
24
23
  from gibson.core.Configuration import Configuration
25
24
  from gibson.core.Conversation import Conversation
26
25
  from gibson.core.Env import Env
@@ -313,7 +313,7 @@ class Configuration:
313
313
 
314
314
  def require_login(self):
315
315
  if self.get_access_token() is None:
316
- self.conversation.message_login_required()
316
+ self.conversation.message_login_required(self)
317
317
  exit(1)
318
318
 
319
319
  return self
@@ -329,9 +329,12 @@ class Configuration:
329
329
 
330
330
  return self
331
331
 
332
- def require_project_key(self):
332
+ def require_project_key_or_id(self):
333
+ if self.project.id:
334
+ return self
335
+
333
336
  if not self.project.api.key or self.project.api.key == "FIXME":
334
- self.conversation.project_api_key_not_set(self.app_domain())
337
+ self.conversation.project_api_key_not_set(self)
335
338
  exit(1)
336
339
 
337
340
  return self
@@ -345,6 +348,7 @@ class Configuration:
345
348
  with open(f"{self.paths.auth}/{self.API_ENV}", "w") as f:
346
349
  data = {"access_token": access_token, "refresh_token": refresh_token}
347
350
  json.dump(data, f, indent=2)
351
+ f.write("\n")
348
352
 
349
353
  def set_config_paths(self):
350
354
  config_path = os.environ.get("GIBSONAI_CONFIG_PATH", None)
@@ -448,6 +452,7 @@ class Configuration:
448
452
 
449
453
  with open(self.paths.config, "w") as f:
450
454
  json.dump(self.settings, f, indent=2)
455
+ f.write("\n")
451
456
 
452
457
  self.read_config()
453
458
 
@@ -10,10 +10,9 @@ from gibson.conf.Version import Version
10
10
 
11
11
 
12
12
  class Conversation:
13
- DEFAULT_DELAY = 0.01
13
+ DEFAULT_DELAY = 0
14
14
 
15
15
  def __init__(self):
16
- self.__delay = self.DEFAULT_DELAY
17
16
  self.__mute = False
18
17
 
19
18
  def c64_boot_loading(self):
@@ -101,7 +100,7 @@ class Conversation:
101
100
  def message_configuration_added(self, config_path, section):
102
101
  self.type(f"I store my configuration in this file:\n\n{config_path}\n\n")
103
102
  self.type("And I just added this section to the configuration:\n\n")
104
- self.type(f"{section}\n", delay=0.002)
103
+ self.type(f"{section}\n")
105
104
  return self
106
105
 
107
106
  def message_customize_settings(self):
@@ -133,10 +132,10 @@ class Conversation:
133
132
  self.type("Login failed, please try again.\n")
134
133
  return self
135
134
 
136
- def message_login_required(self):
135
+ def message_login_required(self, configuration):
137
136
  self.type("You need to login before performing this action.\n")
138
137
  self.type(
139
- f"Run {Colors.command('gibson')} {Colors.subcommand('auth')} {Colors.argument('login')} and try again.\n"
138
+ f"Run {Colors.command(configuration.command, 'auth', args='login')} and try again.\n"
140
139
  )
141
140
  return self
142
141
 
@@ -198,15 +197,18 @@ class Conversation:
198
197
  else:
199
198
  self.type("Back...again? You know what to do.\n\n")
200
199
 
201
- def not_sure_no_entity(self, project_name, entity_name):
202
- self.display_project(project_name)
203
- self.type(f'Not sure what to do. "{entity_name}" does not exist.\n\n')
200
+ def not_sure_no_entity(self, configuration, entity_name):
201
+ self.display_project(configuration.project.name)
202
+ self.type(
203
+ f"No entity named {Colors.entity(entity_name)} exists. You can create it by executing:\n\n"
204
+ )
205
+ self.type(
206
+ f"{Colors.command(configuration.command, 'code', args='entity', inputs=entity_name)}\n\n"
207
+ )
204
208
  return self
205
209
 
206
210
  def nothing_to_list(self, whats_being_listed):
207
- self.type(
208
- f"There is only so much I can do. No {whats_being_listed}, nothing to list."
209
- )
211
+ self.type(f"No {whats_being_listed} to list.")
210
212
  self.newline()
211
213
 
212
214
  def pause(self):
@@ -216,17 +218,17 @@ class Conversation:
216
218
  self.type(f'\nA project named "{project_name}" already exists.\n')
217
219
  self.newline()
218
220
 
219
- def project_api_key_not_set(self, domain):
221
+ def project_api_key_not_set(self, configuration):
220
222
  self.type(
221
223
  f"\nYou have not set the API key for your project. Please set the API key by executing:\n"
222
224
  )
223
225
  self.newline()
224
226
  self.type(
225
- f"{Colors.command('gibson')} {Colors.subcommand('conf')} {Colors.argument('api::key')} {Colors.input('[API key]')}\n"
227
+ f"{Colors.command(configuration.command, 'conf', args='api::key', inputs='[API key]')}\n"
226
228
  )
227
229
  self.newline()
228
230
  self.type(
229
- f"If you don't have an API key, you can get one by creating a new project at {Colors.link(domain + '/chat')}\n"
231
+ f"If you don't have an API key, you can get one by creating a new project at {Colors.link(configuration.app_domain() + '/chat')}\n"
230
232
  )
231
233
  self.newline()
232
234
 
@@ -272,10 +274,6 @@ class Conversation:
272
274
  print("+" + "-" * 75 + "+\n")
273
275
  return self
274
276
 
275
- def set_delay(self, delay):
276
- self.__delay = delay
277
- return self
278
-
279
277
  def spin(self, thread: threading.Thread):
280
278
  animation = self.spinner()
281
279
  while thread.is_alive():
@@ -289,15 +287,10 @@ class Conversation:
289
287
  for cursor in "|/-\\":
290
288
  yield cursor
291
289
 
292
- def type(self, message, delay=None):
290
+ def type(self, message, delay=DEFAULT_DELAY):
293
291
  if self.__mute is True:
294
292
  return self
295
293
 
296
- if delay is None:
297
- delay = self.DEFAULT_DELAY
298
- if self.__delay is not None:
299
- delay = self.__delay
300
-
301
294
  try:
302
295
  for char in message:
303
296
  sys.stdout.write(char)
gibson/core/Memory.py CHANGED
@@ -106,6 +106,7 @@ class Memory:
106
106
  def __remember(self, file, data):
107
107
  with open(file, "w") as f:
108
108
  json.dump(data, f, indent=2)
109
+ f.write("\n")
109
110
 
110
111
  return self
111
112
 
gibson/core/Spinner.py CHANGED
@@ -4,7 +4,7 @@ from yaspin.spinners import Spinners
4
4
 
5
5
  class Spinner:
6
6
  def __init__(
7
- self, start_text, success_text=None, fail_text=None, disappearing=False
7
+ self, start_text="", success_text=None, fail_text=None, disappearing=False
8
8
  ):
9
9
  self.success_text = success_text or start_text
10
10
  self.fail_text = fail_text or start_text
@@ -32,6 +32,11 @@ class Spinner:
32
32
  self.spinner.stop()
33
33
 
34
34
 
35
- class ComputingSpinner(Spinner):
35
+ class DisappearingSpinner(Spinner):
36
+ def __init__(self, start_text="", success_text=None, fail_text=None):
37
+ super().__init__(start_text, success_text, fail_text, disappearing=True)
38
+
39
+
40
+ class ComputingSpinner(DisappearingSpinner):
36
41
  def __init__(self):
37
- super().__init__("Gibson is computing...", disappearing=True)
42
+ super().__init__("Gibson is computing...")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gibson-cli
3
- Version: 0.7.5
3
+ Version: 0.7.6
4
4
  Summary: Gibson Command Line Interface
5
5
  Author-email: GibsonAI <noc@gibsonai.com>
6
6
  Project-URL: Homepage, https://gibsonai.com/
@@ -20,10 +20,10 @@ Requires-Dist: certifi==2024.2.2
20
20
  Requires-Dist: charset-normalizer==3.3.2
21
21
  Requires-Dist: click==8.1.7
22
22
  Requires-Dist: dnspython==2.6.1
23
- Requires-Dist: email-validator==2.1.1
23
+ Requires-Dist: email_validator==2.1.1
24
24
  Requires-Dist: exceptiongroup==1.2.0
25
25
  Requires-Dist: Faker==24.0.0
26
- Requires-Dist: faker-sqlalchemy==0.10.2208140
26
+ Requires-Dist: faker_sqlalchemy==0.10.2208140
27
27
  Requires-Dist: fastapi==0.111.0
28
28
  Requires-Dist: fastapi-cli==0.0.2
29
29
  Requires-Dist: h11==0.14.0
@@ -40,7 +40,7 @@ Requires-Dist: orjson==3.10.3
40
40
  Requires-Dist: packaging==23.2
41
41
  Requires-Dist: pluggy==1.4.0
42
42
  Requires-Dist: pydantic==2.6.1
43
- Requires-Dist: pydantic-core==2.16.2
43
+ Requires-Dist: pydantic_core==2.16.2
44
44
  Requires-Dist: pyfiglet==1.0.2
45
45
  Requires-Dist: Pygments==2.18.0
46
46
  Requires-Dist: PyMySQL==1.1.0
@@ -50,15 +50,16 @@ Requires-Dist: python-dotenv==1.0.1
50
50
  Requires-Dist: python-multipart==0.0.9
51
51
  Requires-Dist: PyYAML==6.0.1
52
52
  Requires-Dist: requests==2.31.0
53
- Requires-Dist: rich==13.7.1
53
+ Requires-Dist: rich==13.9.2
54
54
  Requires-Dist: shellingham==1.5.4
55
55
  Requires-Dist: six==1.16.0
56
56
  Requires-Dist: sniffio==1.3.1
57
57
  Requires-Dist: SQLAlchemy==1.4.41
58
58
  Requires-Dist: starlette==0.37.2
59
+ Requires-Dist: textual==0.83.0
59
60
  Requires-Dist: tomli==2.0.1
60
61
  Requires-Dist: typer==0.12.3
61
- Requires-Dist: typing-extensions==4.9.0
62
+ Requires-Dist: typing_extensions==4.9.0
62
63
  Requires-Dist: ujson==5.9.0
63
64
  Requires-Dist: urllib3==1.26.6
64
65
  Requires-Dist: uvicorn==0.29.0
@@ -84,12 +85,20 @@ Portions of the Gibson backend code are written by Gibson. So far, versus a hum
84
85
 
85
86
  ## Installation / Upgrading
86
87
 
87
- Install the latest version of the CLI using pip.
88
+ Install the latest version of the CLI using `pip`
88
89
 
89
90
  ```sh
90
91
  pip3 install gibson-cli --upgrade
91
92
  ```
92
93
 
94
+ Note: the first time you install any package from PyPI via `pip` that includes an executable, it is placed in a directory that is likely not in your `PATH`. There are a number of ways to do this, but one method is to run the following command:
95
+
96
+ ```sh
97
+ echo 'export PATH="$PATH:${$(which python3)%python3}"' >> ~/.zshrc # or ~/.bashrc
98
+ ```
99
+
100
+ You will only need to do this once.
101
+
93
102
  ## Key Terms
94
103
 
95
104
  - Dev Mode