gemcode 0.3.53__tar.gz → 0.3.54__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 (122) hide show
  1. {gemcode-0.3.53/src/gemcode.egg-info → gemcode-0.3.54}/PKG-INFO +1 -1
  2. {gemcode-0.3.53 → gemcode-0.3.54}/pyproject.toml +1 -1
  3. gemcode-0.3.54/src/gemcode/tui/welcome_banner.py +127 -0
  4. {gemcode-0.3.53 → gemcode-0.3.54/src/gemcode.egg-info}/PKG-INFO +1 -1
  5. gemcode-0.3.53/src/gemcode/tui/welcome_banner.py +0 -137
  6. {gemcode-0.3.53 → gemcode-0.3.54}/LICENSE +0 -0
  7. {gemcode-0.3.53 → gemcode-0.3.54}/MANIFEST.in +0 -0
  8. {gemcode-0.3.53 → gemcode-0.3.54}/README.md +0 -0
  9. {gemcode-0.3.53 → gemcode-0.3.54}/setup.cfg +0 -0
  10. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/__init__.py +0 -0
  11. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/__main__.py +0 -0
  12. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/agent.py +0 -0
  13. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/audit.py +0 -0
  14. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/autocompact.py +0 -0
  15. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/callbacks.py +0 -0
  16. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/capability_routing.py +0 -0
  17. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/cli.py +0 -0
  18. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/compaction.py +0 -0
  19. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/computer_use/__init__.py +0 -0
  20. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/computer_use/browser_computer.py +0 -0
  21. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/config.py +0 -0
  22. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/context_budget.py +0 -0
  23. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/context_warning.py +0 -0
  24. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/credentials.py +0 -0
  25. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/hitl_session.py +0 -0
  26. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/hooks.py +0 -0
  27. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/intent_classifier.py +0 -0
  28. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/interactions.py +0 -0
  29. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/invoke.py +0 -0
  30. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/kairos_daemon.py +0 -0
  31. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/limits.py +0 -0
  32. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/live_audio_engine.py +0 -0
  33. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/logging_config.py +0 -0
  34. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/mcp_loader.py +0 -0
  35. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/memory/__init__.py +0 -0
  36. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/memory/embedding_memory_service.py +0 -0
  37. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/memory/file_memory_service.py +0 -0
  38. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/modality_tools.py +0 -0
  39. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/model_errors.py +0 -0
  40. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/model_routing.py +0 -0
  41. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/openapi_loader.py +0 -0
  42. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/paths.py +0 -0
  43. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/permissions.py +0 -0
  44. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/plugins/__init__.py +0 -0
  45. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
  46. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
  47. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/pricing.py +0 -0
  48. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/prompt_suggestions.py +0 -0
  49. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/query/__init__.py +0 -0
  50. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/query/config.py +0 -0
  51. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/query/deps.py +0 -0
  52. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/query/engine.py +0 -0
  53. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/query/stop_hooks.py +0 -0
  54. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/query/token_budget.py +0 -0
  55. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/query/transitions.py +0 -0
  56. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/refine.py +0 -0
  57. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/repl_commands.py +0 -0
  58. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/repl_slash.py +0 -0
  59. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/review_agent.py +0 -0
  60. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/session_runtime.py +0 -0
  61. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/session_store.py +0 -0
  62. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/slash_commands.py +0 -0
  63. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/thinking.py +0 -0
  64. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tool_prompt_manifest.py +0 -0
  65. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tool_registry.py +0 -0
  66. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/__init__.py +0 -0
  67. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/bash.py +0 -0
  68. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/browser.py +0 -0
  69. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/edit.py +0 -0
  70. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/filesystem.py +0 -0
  71. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/notes.py +0 -0
  72. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/search.py +0 -0
  73. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/shell.py +0 -0
  74. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/shell_gate.py +0 -0
  75. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/subtask.py +0 -0
  76. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/think.py +0 -0
  77. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/todo.py +0 -0
  78. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools/web.py +0 -0
  79. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tools_inspector.py +0 -0
  80. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/trust.py +0 -0
  81. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tui/input_handler.py +0 -0
  82. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tui/scrollback.py +0 -0
  83. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tui/spinner.py +0 -0
  84. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/tui/welcome_rich.py +0 -0
  85. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/version.py +0 -0
  86. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/vertex.py +0 -0
  87. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/web/__init__.py +0 -0
  88. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/web/claude_sse_adapter.py +0 -0
  89. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/web/terminal_repl.py +0 -0
  90. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode/workspace_hints.py +0 -0
  91. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode.egg-info/SOURCES.txt +0 -0
  92. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode.egg-info/dependency_links.txt +0 -0
  93. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode.egg-info/entry_points.txt +0 -0
  94. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode.egg-info/requires.txt +0 -0
  95. {gemcode-0.3.53 → gemcode-0.3.54}/src/gemcode.egg-info/top_level.txt +0 -0
  96. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_agent_instruction.py +0 -0
  97. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_autocompact.py +0 -0
  98. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_capability_routing.py +0 -0
  99. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_claude_web_adapter_sse.py +0 -0
  100. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_cli_init.py +0 -0
  101. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_computer_use_permissions.py +0 -0
  102. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_context_budget.py +0 -0
  103. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_context_warning.py +0 -0
  104. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_credentials.py +0 -0
  105. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_interactive_permission_ask.py +0 -0
  106. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_kairos_scheduler.py +0 -0
  107. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_modality_tools.py +0 -0
  108. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_model_error_retry.py +0 -0
  109. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_model_errors.py +0 -0
  110. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_model_routing.py +0 -0
  111. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_paths.py +0 -0
  112. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_permissions.py +0 -0
  113. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_prompt_suggestions.py +0 -0
  114. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_repl_commands.py +0 -0
  115. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_repl_slash.py +0 -0
  116. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_slash_commands.py +0 -0
  117. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_thinking_config.py +0 -0
  118. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_token_budget.py +0 -0
  119. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_tool_context_circulation.py +0 -0
  120. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_tools.py +0 -0
  121. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_tools_inspector.py +0 -0
  122. {gemcode-0.3.53 → gemcode-0.3.54}/tests/test_workspace_hints.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.53
3
+ Version: 0.3.54
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gemcode"
7
- version = "0.3.53"
7
+ version = "0.3.54"
8
8
  description = "Local-first coding agent on Google Gemini + ADK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -0,0 +1,127 @@
1
+ """ASCII welcome banner + provider box (scrollback + full-screen TUI)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from pathlib import Path
7
+
8
+ from gemcode.version import get_version
9
+ from gemcode.vertex import vertex_env_active
10
+ from gemcode.workspace_hints import narrow_workspace_tip
11
+
12
+ _GEM_LINES = (
13
+ r" ██████╗ ███████╗███╗ ███╗",
14
+ r" ██╔════╝ ██╔════╝████╗ ████║",
15
+ r" ██║ ███╗█████╗ ██╔████╔██║",
16
+ r" ██║ ██║██╔══╝ ██║╚██╔╝██║",
17
+ r" ╚██████╔╝███████╗██║ ╚═╝ ██║",
18
+ r" ╚═════╝ ╚══════╝╚═╝ ╚═╝",
19
+ )
20
+
21
+ _CODE_LINES = (
22
+ r" ██████╗ ██████╗ ██████╗ ███████╗",
23
+ r" ██╔════╝██╔═══██╗██╔══██╗██╔════╝",
24
+ r" ██║ ██║ ██║██║ ██║█████╗ ",
25
+ r" ██║ ██║ ██║██║ ██║██╔══╝ ",
26
+ r" ╚██████╗╚██████╔╝██████╔╝███████╗",
27
+ r" ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝",
28
+ )
29
+
30
+ _TAGLINE = "✦ Gemini-powered coding agent. Fast. Capable. Local. ✦"
31
+
32
+
33
+ def _banner_width() -> int:
34
+ return max(len(x) for x in _GEM_LINES + _CODE_LINES)
35
+
36
+
37
+ def _center(line: str, width: int) -> str:
38
+ if len(line) >= width:
39
+ return line
40
+ pad = width - len(line)
41
+ left = pad // 2
42
+ return " " * left + line + " " * (pad - left)
43
+
44
+
45
+ def _provider_model_endpoint(cfg) -> tuple[str, str, str]:
46
+ model = (getattr(cfg, "model", None) or "").strip() or "gemini-2.5-flash"
47
+ if vertex_env_active():
48
+ provider = "Vertex AI"
49
+ loc = (os.environ.get("GOOGLE_CLOUD_LOCATION") or "us-central1").strip()
50
+ proj = (os.environ.get("GOOGLE_CLOUD_PROJECT") or "").strip()
51
+ end = f"vertex://{loc}"
52
+ if proj:
53
+ end = f"{end} · {proj}"
54
+ else:
55
+ provider = "Google Gemini"
56
+ end = "https://generativelanguage.googleapis.com/"
57
+ return provider, model, end
58
+
59
+
60
+ def _kv_line(inner: int, label: str, value: str) -> str:
61
+ """One row inside the box: leading space + label column + value (total width ``inner``)."""
62
+ lead = " "
63
+ prefix = f"{label:<10}"
64
+ room = inner - len(lead) - len(prefix)
65
+ if room < 4:
66
+ raw = (lead + prefix + value)[:inner]
67
+ return raw.ljust(inner)
68
+ v = value
69
+ if len(v) > room:
70
+ v = v[: max(0, room - 3)] + "..."
71
+ return (lead + prefix + v).ljust(inner)[:inner]
72
+
73
+
74
+ def format_welcome_banner(cfg, *, term_width: int = 100) -> str:
75
+ inner = min(60, max(48, term_width - 4))
76
+ top = "╔" + ("═" * inner) + "╗"
77
+ mid = "╠" + ("═" * inner) + "╣"
78
+ bot = "╚" + ("═" * inner) + "╝"
79
+
80
+ provider, model, endpoint = _provider_model_endpoint(cfg)
81
+ row_p = _kv_line(inner, "Provider", provider)
82
+ row_m = _kv_line(inner, "Model", model)
83
+ row_e = _kv_line(inner, "Endpoint", endpoint)
84
+
85
+ mode = "vertex" if vertex_env_active() else "cloud"
86
+ status_raw = f" ● {mode} Ready — type /help to begin"
87
+ if len(status_raw) > inner:
88
+ status_raw = status_raw[: max(0, inner - 3)] + "..."
89
+ row_s = status_raw.ljust(inner)[:inner]
90
+
91
+ bw = max(_banner_width(), inner + 2)
92
+ lines: list[str] = []
93
+ for row in _GEM_LINES:
94
+ lines.append(_center(row, bw))
95
+ lines.append("")
96
+ for row in _CODE_LINES:
97
+ lines.append(_center(row, bw))
98
+ lines.append("")
99
+ lines.append(_center(f" {_TAGLINE} ", bw))
100
+ lines.append("")
101
+
102
+ box_w = inner + 2
103
+ pad_b = max(0, (bw - box_w) // 2)
104
+ bp = " " * pad_b
105
+
106
+ def box_row(body: str) -> str:
107
+ b = body[:inner].ljust(inner)
108
+ return bp + "│" + b + "│"
109
+
110
+ lines.append(bp + top)
111
+ lines.append(box_row(row_p))
112
+ lines.append(box_row(row_m))
113
+ lines.append(box_row(row_e))
114
+ lines.append(bp + mid)
115
+ lines.append(box_row(row_s))
116
+ lines.append(bp + bot)
117
+
118
+ ver = os.environ.get("GEMCODE_VERSION", get_version())
119
+ lines.append(_center(f" gemcode v{ver} ", bw))
120
+
121
+ root = getattr(cfg, "project_root", None)
122
+ if isinstance(root, Path):
123
+ nt = narrow_workspace_tip(root)
124
+ if nt:
125
+ lines.append(_center(nt, bw))
126
+ lines.append("")
127
+ return "\n".join(lines)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.53
3
+ Version: 0.3.54
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
@@ -1,137 +0,0 @@
1
- """ASCII welcome banner + provider box (scrollback + full-screen TUI)."""
2
-
3
- from __future__ import annotations
4
-
5
- import os
6
- from pathlib import Path
7
-
8
- from gemcode.version import get_version
9
- from gemcode.vertex import vertex_env_active
10
- from gemcode.workspace_hints import narrow_workspace_tip
11
-
12
- _GEM_LINES = (
13
- r"██████╗ ███████╗███╗ ███╗",
14
- r"██╔════╝ ██╔════╝████╗ ████║",
15
- r"██║ ███╗█████╗ ██╔████╔██║",
16
- r"██║ ██║██╔══╝ ██║╚██╔╝██║",
17
- r"╚██████╔╝███████╗██║ ╚═╝ ██║",
18
- r" ╚═════╝ ╚══════╝╚═╝ ╚═╝",
19
- )
20
-
21
- _CODE_LINES = (
22
- r"██████╗ ██████╗ ██████╗ ███████╗",
23
- r"██╔════╝██╔═══██╗██╔══██╗██╔════╝",
24
- r"██║ ██║ ██║██║ ██║█████╗ ",
25
- r"██║ ██║ ██║██║ ██║██╔══╝ ",
26
- r"╚██████╗╚██████╔╝██████╔╝███████╗",
27
- r" ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝",
28
- )
29
-
30
- _TAGLINE = "✦ Gemini-powered coding agent. Fast. Capable. Local. ✦"
31
-
32
-
33
- def _banner_width() -> int:
34
- return max(len(x) for x in _GEM_LINES + _CODE_LINES)
35
-
36
-
37
- def _center(line: str, width: int) -> str:
38
- if len(line) >= width:
39
- return line
40
- pad = width - len(line)
41
- left = pad // 2
42
- return " " * left + line + " " * (pad - left)
43
-
44
-
45
- def _provider_model_endpoint(cfg) -> tuple[str, str, str]:
46
- model = (getattr(cfg, "model", None) or "").strip() or "gemini-2.5-flash"
47
- if vertex_env_active():
48
- provider = "Vertex AI"
49
- loc = (os.environ.get("GOOGLE_CLOUD_LOCATION") or "us-central1").strip()
50
- proj = (os.environ.get("GOOGLE_CLOUD_PROJECT") or "").strip()
51
- end = f"vertex://{loc}"
52
- if proj:
53
- end = f"{end} · {proj}"
54
- else:
55
- provider = "Google Gemini"
56
- end = "https://generativelanguage.googleapis.com/"
57
- return provider, model, end
58
-
59
-
60
- def _kv_line(inner: int, label: str, value: str) -> str:
61
- """One row inside the box: leading space + label column + value (total width ``inner``)."""
62
- lead = " "
63
- prefix = f"{label:<10}"
64
- room = inner - len(lead) - len(prefix)
65
- if room < 4:
66
- raw = (lead + prefix + value)[:inner]
67
- return raw.ljust(inner)
68
- v = value
69
- if len(v) > room:
70
- v = v[: max(0, room - 3)] + "..."
71
- return (lead + prefix + v).ljust(inner)[:inner]
72
-
73
-
74
- def format_welcome_banner(cfg, *, term_width: int = 100) -> str:
75
- provider, model, endpoint = _provider_model_endpoint(cfg)
76
- # Banner style: "solid" removes the boxed provider block and blank spacer
77
- # lines for a single rigid header (OpenClaude-like).
78
- style = (os.environ.get("GEMCODE_TUI_BANNER_STYLE", "solid") or "solid").strip().lower()
79
-
80
- bw = max(_banner_width(), min(80, max(48, term_width)))
81
- lines: list[str] = []
82
- for row in _GEM_LINES:
83
- lines.append(_center(row, bw))
84
- for row in _CODE_LINES:
85
- lines.append(_center(row, bw))
86
- lines.append(_center(_TAGLINE, bw))
87
-
88
- if style not in ("solid", "rigid", "compact"):
89
- # Backward-compat: unknown values fall back to the old boxed layout.
90
- style = "boxed"
91
-
92
- if style == "boxed":
93
- inner = min(60, max(48, term_width - 4))
94
- top = "╔" + ("═" * inner) + "╗"
95
- mid = "╠" + ("═" * inner) + "╣"
96
- bot = "╚" + ("═" * inner) + "╝"
97
-
98
- row_p = _kv_line(inner, "Provider", provider)
99
- row_m = _kv_line(inner, "Model", model)
100
- row_e = _kv_line(inner, "Endpoint", endpoint)
101
-
102
- mode = "vertex" if vertex_env_active() else "cloud"
103
- status_raw = f" ● {mode} Ready — type /help to begin"
104
- if len(status_raw) > inner:
105
- status_raw = status_raw[: max(0, inner - 3)] + "..."
106
- row_s = status_raw.ljust(inner)[:inner]
107
-
108
- box_w = inner + 2
109
- pad_b = max(0, (bw - box_w) // 2)
110
- bp = " " * pad_b
111
-
112
- def box_row(body: str) -> str:
113
- b = body[:inner].ljust(inner)
114
- return bp + "│" + b + "│"
115
-
116
- lines.append(bp + top)
117
- lines.append(box_row(row_p))
118
- lines.append(box_row(row_m))
119
- lines.append(box_row(row_e))
120
- lines.append(bp + mid)
121
- lines.append(box_row(row_s))
122
- lines.append(bp + bot)
123
- else:
124
- # Solid header: one rigid info line, no extra blocks.
125
- mode = "vertex" if vertex_env_active() else "cloud"
126
- info = f"{provider} · {model} · {endpoint} · {mode} ready — type /help"
127
- lines.append(_center(info, bw))
128
-
129
- ver = os.environ.get("GEMCODE_VERSION", get_version())
130
- lines.append(_center(f"gemcode v{ver}", bw))
131
-
132
- root = getattr(cfg, "project_root", None)
133
- if isinstance(root, Path):
134
- nt = narrow_workspace_tip(root)
135
- if nt:
136
- lines.append(_center(nt, bw))
137
- return "\n".join(lines)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes