gemcode 0.3.96__tar.gz → 0.3.98__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. {gemcode-0.3.96/src/gemcode.egg-info → gemcode-0.3.98}/PKG-INFO +1 -1
  2. {gemcode-0.3.96 → gemcode-0.3.98}/pyproject.toml +1 -1
  3. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/invoke.py +26 -8
  4. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/multimodal_input.py +18 -0
  5. {gemcode-0.3.96 → gemcode-0.3.98/src/gemcode.egg-info}/PKG-INFO +1 -1
  6. {gemcode-0.3.96 → gemcode-0.3.98}/LICENSE +0 -0
  7. {gemcode-0.3.96 → gemcode-0.3.98}/MANIFEST.in +0 -0
  8. {gemcode-0.3.96 → gemcode-0.3.98}/README.md +0 -0
  9. {gemcode-0.3.96 → gemcode-0.3.98}/setup.cfg +0 -0
  10. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/__init__.py +0 -0
  11. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/__main__.py +0 -0
  12. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/agent.py +0 -0
  13. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/audit.py +0 -0
  14. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/autocompact.py +0 -0
  15. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/autotune.py +0 -0
  16. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/callbacks.py +0 -0
  17. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/capability_routing.py +0 -0
  18. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/checkpoints.py +0 -0
  19. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/cli.py +0 -0
  20. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/compaction.py +0 -0
  21. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/computer_use/__init__.py +0 -0
  22. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/computer_use/browser_computer.py +0 -0
  23. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/config.py +0 -0
  24. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/context_budget.py +0 -0
  25. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/context_warning.py +0 -0
  26. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/credentials.py +0 -0
  27. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/curated_memory.py +0 -0
  28. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/dynamic_policy.py +0 -0
  29. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/evals/harness.py +0 -0
  30. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/hitl_session.py +0 -0
  31. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/hooks.py +0 -0
  32. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/ide_protocol.py +0 -0
  33. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/ide_stdio.py +0 -0
  34. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/intent_classifier.py +0 -0
  35. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/interactions.py +0 -0
  36. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/kaira_daemon.py +0 -0
  37. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/learning.py +0 -0
  38. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/limits.py +0 -0
  39. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/live_audio_engine.py +0 -0
  40. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/logging_config.py +0 -0
  41. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/mcp_loader.py +0 -0
  42. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/memory/__init__.py +0 -0
  43. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/memory/embedding_memory_service.py +0 -0
  44. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/memory/file_memory_service.py +0 -0
  45. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/modality_tools.py +0 -0
  46. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/model_errors.py +0 -0
  47. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/model_routing.py +0 -0
  48. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/openapi_loader.py +0 -0
  49. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/output_styles.py +0 -0
  50. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/paths.py +0 -0
  51. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/permissions.py +0 -0
  52. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/plugins/__init__.py +0 -0
  53. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
  54. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
  55. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/policy_profile.py +0 -0
  56. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/pricing.py +0 -0
  57. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/prompt_suggestions.py +0 -0
  58. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/query/__init__.py +0 -0
  59. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/query/config.py +0 -0
  60. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/query/deps.py +0 -0
  61. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/query/engine.py +0 -0
  62. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/query/stop_hooks.py +0 -0
  63. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/query/token_budget.py +0 -0
  64. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/query/transitions.py +0 -0
  65. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/query_sanitizer.py +0 -0
  66. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/refine.py +0 -0
  67. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/repl_commands.py +0 -0
  68. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/repl_slash.py +0 -0
  69. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/review_agent.py +0 -0
  70. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/rules.py +0 -0
  71. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/session_runtime.py +0 -0
  72. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/session_store.py +0 -0
  73. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/session_summariser.py +0 -0
  74. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/skills.py +0 -0
  75. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/slash_commands.py +0 -0
  76. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/thinking.py +0 -0
  77. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tool_prompt_manifest.py +0 -0
  78. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tool_registry.py +0 -0
  79. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tool_result_store.py +0 -0
  80. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/__init__.py +0 -0
  81. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/bash.py +0 -0
  82. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/browser.py +0 -0
  83. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/compress_memory.py +0 -0
  84. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/curated_memory.py +0 -0
  85. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/edit.py +0 -0
  86. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/filesystem.py +0 -0
  87. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/notebook.py +0 -0
  88. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/notes.py +0 -0
  89. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/repo_map.py +0 -0
  90. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/search.py +0 -0
  91. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/shell.py +0 -0
  92. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/shell_gate.py +0 -0
  93. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/skills.py +0 -0
  94. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/subtask.py +0 -0
  95. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/tasks.py +0 -0
  96. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/think.py +0 -0
  97. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/todo.py +0 -0
  98. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/veomem_tools.py +0 -0
  99. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/web.py +0 -0
  100. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools/web_search.py +0 -0
  101. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tools_inspector.py +0 -0
  102. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/trust.py +0 -0
  103. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tui/input_handler.py +0 -0
  104. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tui/scrollback.py +0 -0
  105. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tui/spinner.py +0 -0
  106. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tui/welcome_banner.py +0 -0
  107. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/tui/welcome_rich.py +0 -0
  108. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/veomem_bridge.py +0 -0
  109. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/version.py +0 -0
  110. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/vertex.py +0 -0
  111. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/wal.py +0 -0
  112. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/web/__init__.py +0 -0
  113. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/web/sse_adapter.py +0 -0
  114. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/web/terminal_repl.py +0 -0
  115. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/web/web_sse_compat.py +0 -0
  116. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode/workspace_hints.py +0 -0
  117. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode.egg-info/SOURCES.txt +0 -0
  118. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode.egg-info/dependency_links.txt +0 -0
  119. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode.egg-info/entry_points.txt +0 -0
  120. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode.egg-info/requires.txt +0 -0
  121. {gemcode-0.3.96 → gemcode-0.3.98}/src/gemcode.egg-info/top_level.txt +0 -0
  122. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_add_dir.py +0 -0
  123. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_agent_instruction.py +0 -0
  124. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_autocompact.py +0 -0
  125. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_capability_routing.py +0 -0
  126. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_checkpoint_diff_command.py +0 -0
  127. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_cli_init.py +0 -0
  128. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_compress_memory_tool.py +0 -0
  129. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_computer_use_permissions.py +0 -0
  130. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_context_budget.py +0 -0
  131. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_context_warning.py +0 -0
  132. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_credentials.py +0 -0
  133. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_eval_harness_layout.py +0 -0
  134. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_ide_stdio_attachments.py +0 -0
  135. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_interactive_permission_ask.py +0 -0
  136. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_kaira_scheduler.py +0 -0
  137. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_modality_tools.py +0 -0
  138. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_model_error_retry.py +0 -0
  139. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_model_errors.py +0 -0
  140. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_model_routing.py +0 -0
  141. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_multimodal_input.py +0 -0
  142. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_output_styles_and_rules.py +0 -0
  143. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_paths.py +0 -0
  144. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_permissions.py +0 -0
  145. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_prompt_suggestions.py +0 -0
  146. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_repl_commands.py +0 -0
  147. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_repl_slash.py +0 -0
  148. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_skills.py +0 -0
  149. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_slash_commands.py +0 -0
  150. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_slash_completion_registry.py +0 -0
  151. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_thinking_config.py +0 -0
  152. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_token_budget.py +0 -0
  153. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_tool_context_circulation.py +0 -0
  154. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_tools.py +0 -0
  155. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_tools_inspector.py +0 -0
  156. {gemcode-0.3.96 → gemcode-0.3.98}/tests/test_web_sse_adapter.py +0 -0
  157. {gemcode-0.3.96 → gemcode-0.3.98}/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.96
3
+ Version: 0.3.98
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.96"
7
+ version = "0.3.98"
8
8
  description = "Local-first coding agent on Google Gemini + ADK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -184,15 +184,33 @@ async def run_turn(
184
184
  # user-granted "Files and Folders" permissions on first access.
185
185
  # If approved once, we don't re-prompt for the rest of this session.
186
186
  attach_allow = True
187
- if cfg is not None:
188
- attach_allow = bool(getattr(cfg, "interactive_permission_ask", False))
189
- attach_allow = attach_allow and hasattr(sys.stdin, "isatty") and sys.stdin.isatty()
190
- if attach_allow and not bool(getattr(cfg, "_attachments_allowed", False)):
191
- attach_allow = _prompt_yes_no(
192
- "Allow GemCode to read and upload the attached file(s) from disk? (y/n) "
193
- )
194
- if attach_allow:
187
+ if hasattr(sys.stdin, "isatty") and sys.stdin.isatty():
188
+ # Default-on: attachments can read any local file path (not workspace-scoped),
189
+ # but we ask once per session so the user is in control and macOS can trigger
190
+ # its permission prompt at the moment we attempt the read.
191
+ attach_allow = os.environ.get("GEMCODE_ATTACHMENTS_ASK", "1").lower() not in (
192
+ "0",
193
+ "false",
194
+ "no",
195
+ "off",
196
+ )
197
+ if cfg is not None:
198
+ # If user already approved earlier in this session, don't prompt again.
199
+ if bool(getattr(cfg, "_attachments_allowed", False)):
200
+ attach_allow = True
201
+ # If yes-to-all is enabled, auto-allow attachments.
202
+ elif bool(getattr(cfg, "yes_to_all", False)):
203
+ attach_allow = True
195
204
  object.__setattr__(cfg, "_attachments_allowed", True)
205
+ elif attach_allow:
206
+ attach_allow = _prompt_yes_no(
207
+ "Allow GemCode to read and upload the attached file(s) from disk? (y/n) "
208
+ )
209
+ if attach_allow:
210
+ object.__setattr__(cfg, "_attachments_allowed", True)
211
+ else:
212
+ # Non-interactive sessions can't prompt; default to allow.
213
+ attach_allow = True
196
214
  effective_attachments = attachment_paths if attach_allow else None
197
215
 
198
216
  root = cfg.project_root if cfg is not None else Path.cwd()
@@ -97,6 +97,18 @@ def _infer_mime(path: Path, data: bytes) -> tuple[str, list[str]]:
97
97
  return "application/octet-stream", warnings
98
98
 
99
99
 
100
+ def _is_supported_mime(m: str) -> bool:
101
+ mm = (m or "").strip().lower()
102
+ if not mm:
103
+ return False
104
+ if mm.startswith(("image/", "audio/", "video/", "text/")):
105
+ return True
106
+ if mm == "application/pdf":
107
+ return True
108
+ # Most other application/* types are rejected by Gemini file parts.
109
+ return False
110
+
111
+
100
112
  def build_user_content(
101
113
  prompt: str,
102
114
  attachment_paths: Sequence[Path | str] | None,
@@ -135,6 +147,12 @@ def build_user_content(
135
147
  continue
136
148
  mime, mw = _infer_mime(p, data)
137
149
  warnings.extend(mw)
150
+ if not _is_supported_mime(mime) or mime == "application/octet-stream":
151
+ warnings.append(
152
+ f"unsupported attachment type for {p} (mime={mime}); "
153
+ "skipping (export to PDF/image/text if needed)"
154
+ )
155
+ continue
138
156
  parts.append(types.Part(inline_data=types.Blob(data=data, mime_type=mime)))
139
157
 
140
158
  text = (prompt or "").strip() or (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.96
3
+ Version: 0.3.98
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes