gemcode 0.3.20__tar.gz → 0.3.22__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 (112) hide show
  1. {gemcode-0.3.20/src/gemcode.egg-info → gemcode-0.3.22}/PKG-INFO +1 -1
  2. {gemcode-0.3.20 → gemcode-0.3.22}/pyproject.toml +1 -1
  3. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/repl_commands.py +2 -0
  4. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/repl_slash.py +20 -3
  5. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tui/input_handler.py +10 -9
  6. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tui/scrollback.py +32 -19
  7. {gemcode-0.3.20 → gemcode-0.3.22/src/gemcode.egg-info}/PKG-INFO +1 -1
  8. {gemcode-0.3.20 → gemcode-0.3.22}/LICENSE +0 -0
  9. {gemcode-0.3.20 → gemcode-0.3.22}/MANIFEST.in +0 -0
  10. {gemcode-0.3.20 → gemcode-0.3.22}/README.md +0 -0
  11. {gemcode-0.3.20 → gemcode-0.3.22}/setup.cfg +0 -0
  12. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/__init__.py +0 -0
  13. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/__main__.py +0 -0
  14. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/agent.py +0 -0
  15. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/audit.py +0 -0
  16. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/autocompact.py +0 -0
  17. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/callbacks.py +0 -0
  18. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/capability_routing.py +0 -0
  19. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/cli.py +0 -0
  20. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/compaction.py +0 -0
  21. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/computer_use/__init__.py +0 -0
  22. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/computer_use/browser_computer.py +0 -0
  23. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/config.py +0 -0
  24. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/context_budget.py +0 -0
  25. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/context_warning.py +0 -0
  26. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/credentials.py +0 -0
  27. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/hitl_session.py +0 -0
  28. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/interactions.py +0 -0
  29. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/invoke.py +0 -0
  30. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/kairos_daemon.py +0 -0
  31. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/limits.py +0 -0
  32. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/live_audio_engine.py +0 -0
  33. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/logging_config.py +0 -0
  34. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/mcp_loader.py +0 -0
  35. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/memory/__init__.py +0 -0
  36. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/memory/embedding_memory_service.py +0 -0
  37. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/memory/file_memory_service.py +0 -0
  38. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/modality_tools.py +0 -0
  39. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/model_errors.py +0 -0
  40. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/model_routing.py +0 -0
  41. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/paths.py +0 -0
  42. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/permissions.py +0 -0
  43. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/plugins/__init__.py +0 -0
  44. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
  45. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
  46. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/prompt_suggestions.py +0 -0
  47. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/query/__init__.py +0 -0
  48. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/query/config.py +0 -0
  49. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/query/deps.py +0 -0
  50. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/query/engine.py +0 -0
  51. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/query/stop_hooks.py +0 -0
  52. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/query/token_budget.py +0 -0
  53. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/query/transitions.py +0 -0
  54. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/session_runtime.py +0 -0
  55. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/slash_commands.py +0 -0
  56. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/thinking.py +0 -0
  57. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tool_prompt_manifest.py +0 -0
  58. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tool_registry.py +0 -0
  59. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/__init__.py +0 -0
  60. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/bash.py +0 -0
  61. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/edit.py +0 -0
  62. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/filesystem.py +0 -0
  63. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/search.py +0 -0
  64. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/shell.py +0 -0
  65. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/shell_gate.py +0 -0
  66. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/subtask.py +0 -0
  67. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/think.py +0 -0
  68. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/todo.py +0 -0
  69. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools/web.py +0 -0
  70. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tools_inspector.py +0 -0
  71. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/trust.py +0 -0
  72. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tui/spinner.py +0 -0
  73. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tui/welcome_banner.py +0 -0
  74. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/tui/welcome_rich.py +0 -0
  75. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/version.py +0 -0
  76. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/vertex.py +0 -0
  77. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/web/__init__.py +0 -0
  78. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/web/claude_sse_adapter.py +0 -0
  79. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/web/terminal_repl.py +0 -0
  80. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode/workspace_hints.py +0 -0
  81. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode.egg-info/SOURCES.txt +0 -0
  82. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode.egg-info/dependency_links.txt +0 -0
  83. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode.egg-info/entry_points.txt +0 -0
  84. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode.egg-info/requires.txt +0 -0
  85. {gemcode-0.3.20 → gemcode-0.3.22}/src/gemcode.egg-info/top_level.txt +0 -0
  86. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_agent_instruction.py +0 -0
  87. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_autocompact.py +0 -0
  88. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_capability_routing.py +0 -0
  89. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_claude_web_adapter_sse.py +0 -0
  90. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_cli_init.py +0 -0
  91. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_computer_use_permissions.py +0 -0
  92. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_context_budget.py +0 -0
  93. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_context_warning.py +0 -0
  94. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_credentials.py +0 -0
  95. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_interactive_permission_ask.py +0 -0
  96. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_kairos_scheduler.py +0 -0
  97. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_modality_tools.py +0 -0
  98. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_model_error_retry.py +0 -0
  99. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_model_errors.py +0 -0
  100. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_model_routing.py +0 -0
  101. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_paths.py +0 -0
  102. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_permissions.py +0 -0
  103. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_prompt_suggestions.py +0 -0
  104. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_repl_commands.py +0 -0
  105. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_repl_slash.py +0 -0
  106. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_slash_commands.py +0 -0
  107. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_thinking_config.py +0 -0
  108. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_token_budget.py +0 -0
  109. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_tool_context_circulation.py +0 -0
  110. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_tools.py +0 -0
  111. {gemcode-0.3.20 → gemcode-0.3.22}/tests/test_tools_inspector.py +0 -0
  112. {gemcode-0.3.20 → gemcode-0.3.22}/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.20
3
+ Version: 0.3.22
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.20"
7
+ version = "0.3.22"
8
8
  description = "Local-first coding agent on Google Gemini + ADK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -177,6 +177,8 @@ def slash_help_lines() -> list[str]:
177
177
  " /model use <id> Override model for this REPL session",
178
178
  " /model list List available Gemini model IDs",
179
179
  " /thinking Show current thinking config",
180
+ " /thinking verbose Show full thinking text each turn",
181
+ " /thinking brief Show collapsed one-line excerpt (default)",
180
182
  " /thinking off Disable model thinking",
181
183
  " /thinking on Re-enable thinking (auto budget/level)",
182
184
  " /thinking budget <N> Set thinking token budget (Gemini 2.5, 0=off, -1=dynamic)",
@@ -278,12 +278,14 @@ async def process_repl_slash(
278
278
 
279
279
  if not args:
280
280
  # Show current thinking config.
281
- disable = bool(getattr(cfg, "disable_thinking", False))
282
- level = getattr(cfg, "thinking_level", None)
283
- budget = getattr(cfg, "thinking_budget", None)
281
+ disable = bool(getattr(cfg, "disable_thinking", False))
282
+ level = getattr(cfg, "thinking_level", None)
283
+ budget = getattr(cfg, "thinking_budget", None)
284
+ verbose = bool(getattr(cfg, "show_full_thinking", False))
284
285
  out("Thinking config:")
285
286
  out(f" model: {model_id or '(default)'}")
286
287
  out(f" disable_thinking: {disable}")
288
+ out(f" display_mode: {'verbose (full)' if verbose else 'brief (collapsed)'}")
287
289
  if is_25:
288
290
  out(f" thinking_budget: {budget if budget is not None else '(auto / dynamic)'}")
289
291
  out()
@@ -298,12 +300,27 @@ async def process_repl_slash(
298
300
  out(" /thinking off — use minimal thinking")
299
301
  out(" /thinking on — re-enable auto level")
300
302
  out(" /thinking level <minimal|low|medium|high>")
303
+ out("Display commands (all models):")
304
+ out(" /thinking verbose — show full thinking text each turn")
305
+ out(" /thinking brief — show collapsed one-line excerpt (default)")
301
306
  out()
302
307
  return ReplSlashResult(skip_model_turn=True)
303
308
 
304
309
  parts = args.split()
305
310
  sub = parts[0].lower()
306
311
 
312
+ if sub in ("verbose", "full"):
313
+ setattr(cfg, "show_full_thinking", True)
314
+ out("thinking display: verbose — full thinking shown each turn")
315
+ out()
316
+ return ReplSlashResult(skip_model_turn=True)
317
+
318
+ if sub in ("brief", "short", "collapsed"):
319
+ setattr(cfg, "show_full_thinking", False)
320
+ out("thinking display: brief — collapsed one-line excerpt (default)")
321
+ out()
322
+ return ReplSlashResult(skip_model_turn=True)
323
+
307
324
  if sub == "off":
308
325
  setattr(cfg, "disable_thinking", True)
309
326
  out("thinking: disabled (runner will rebuild on next turn)")
@@ -41,19 +41,20 @@ except ImportError:
41
41
  # ---------------------------------------------------------------------------
42
42
  SLASH_COMMANDS: list[tuple[str, str]] = [
43
43
  ("help", "List all available commands"),
44
- ("clear", "Start a fresh session clears conversation history"),
44
+ ("clear", "Start a fresh session (clears history) · alias: /session new"),
45
45
  ("model", "View or switch model · /model use <id> · /model list"),
46
+ ("thinking", "Thinking config · /thinking verbose · /thinking brief · /thinking budget <N>"),
46
47
  ("status", "Show session ID, model, and current settings"),
47
48
  ("context", "Show context window usage and token counts"),
48
- ("tools", "List all tools and their permission categories"),
49
49
  ("compact", "Summarise conversation history to reclaim context space"),
50
+ ("tools", "List all tools and their permission categories"),
50
51
  ("config", "Show active configuration and environment variables"),
51
52
  ("permissions", "Show current permission mode (default / strict / yes)"),
52
- ("thinking", "View or change thinking config · /thinking level <low|medium|high> · /thinking budget <N>"),
53
+ ("session", "Show current session ID · /session new to reset"),
53
54
  ("audit", "Show recent audit log · /audit [N lines]"),
54
55
  ("memory", "Show memory / storage settings"),
55
56
  ("doctor", "Run diagnostics and validate the environment"),
56
- ("hooks", "Show hooks configuration"),
57
+ ("hooks", "Show post-turn hook configuration"),
57
58
  ("version", "Show installed GemCode version"),
58
59
  ("exit", "Exit GemCode"),
59
60
  ]
@@ -157,11 +158,11 @@ class GemCodeInputHandler:
157
158
  style=style,
158
159
  bottom_toolbar=bottom_toolbar,
159
160
  key_bindings=kb,
160
- mouse_support=False,
161
- complete_in_thread=True,
162
- reserve_space_for_menu=10,
163
- # Show completion descriptions to the right (like VS Code)
164
- complete_style="COLUMN",
161
+ mouse_support=False,
162
+ complete_in_thread=True,
163
+ reserve_space_for_menu=20,
164
+ # Single-column popup with description column (like VS Code)
165
+ complete_style="COLUMN",
165
166
  )
166
167
 
167
168
  def is_interactive(self) -> bool:
@@ -9,6 +9,8 @@ from dataclasses import dataclass
9
9
  from google.adk.agents.run_config import RunConfig
10
10
  from google.genai import types
11
11
  from rich.console import Console
12
+ from rich.markdown import Markdown as _RichMarkdown
13
+ from rich.padding import Padding as _RichPadding
12
14
 
13
15
  from gemcode.capability_routing import apply_capability_routing
14
16
  from gemcode.config import load_cli_environment
@@ -492,28 +494,39 @@ async def run_gemcode_scrollback_tui(
492
494
 
493
495
  confirmation_fcs = _get_confirmation_fcs(events)
494
496
  if not confirmation_fcs:
495
- # Render buffered thinking and final response separately.
496
- thought_text = "".join(buffered_thought)
497
- final_text = "".join(buffered_final)
498
- if buffered_thought:
499
- if buffered_final and _normalize_ws(thought_text) == _normalize_ws(final_text):
500
- print(
501
- f" ⎿ {ansi.dim}{ansi.bold}\u2234 Thinking{ansi.reset}: "
502
- f"{ansi.reset}(omitted: identical to final response)"
503
- )
497
+ thought_text = "".join(buffered_thought).strip()
498
+ final_text = "".join(buffered_final).strip()
499
+
500
+ # ── Thinking display (collapsed by default, verbose with /thinking verbose)
501
+ if thought_text and not (
502
+ buffered_final and _normalize_ws(thought_text) == _normalize_ws(final_text)
503
+ ):
504
+ show_full = bool(getattr(cfg, "show_full_thinking", False))
505
+ if show_full:
506
+ # Verbose mode: full thinking rendered as Markdown, like transcript mode.
507
+ print(f" \u23bf {ansi.dim}\u2234 Thinking{ansi.reset}")
508
+ console.print(_RichPadding(_RichMarkdown(thought_text), (0, 0, 0, 4)))
504
509
  print("")
505
510
  else:
506
- sys.stdout.write(
507
- f" ⎿ {ansi.dim}{ansi.bold}\u2234 Thinking{ansi.reset}: "
511
+ # Collapsed: one-line excerpt + hint to expand.
512
+ excerpt = thought_text.replace("\n", " ").strip()
513
+ if len(excerpt) > 90:
514
+ excerpt = excerpt[:87] + "\u2026"
515
+ print(
516
+ f" \u23bf {ansi.dim}\u2234 Thinking {excerpt}"
517
+ f" \u00b7 /thinking verbose to expand{ansi.reset}"
508
518
  )
509
- sys.stdout.flush()
510
- await typewrite(thought_text)
511
- sys.stdout.write("\n")
512
- sys.stdout.flush()
513
- if buffered_final:
514
- sys.stdout.write(f" ⎿ {ansi.bold}GemCode{ansi.reset}: ")
515
- sys.stdout.flush()
516
- await typewrite(final_text)
519
+ print("")
520
+
521
+ # ── Response — rendered as Rich Markdown ──────────────────────────
522
+ # Pipes the text through Rich's Markdown renderer so **bold**,
523
+ # *italic*, `code`, bullet lists and fenced code blocks all display
524
+ # correctly instead of showing raw asterisks and backticks.
525
+ if final_text:
526
+ print(f" \u23bf {ansi.bold}GemCode{ansi.reset}:")
527
+ console.print(
528
+ _RichPadding(_RichMarkdown(final_text), (0, 0, 0, 4)),
529
+ )
517
530
  break
518
531
 
519
532
  interactive_enabled = bool(getattr(cfg, "interactive_permission_ask", False))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.20
3
+ Version: 0.3.22
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
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