gemcode 0.3.1__tar.gz → 0.3.2__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.
- {gemcode-0.3.1/src/gemcode.egg-info → gemcode-0.3.2}/PKG-INFO +1 -1
- {gemcode-0.3.1 → gemcode-0.3.2}/pyproject.toml +1 -1
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/agent.py +1 -1
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tool_prompt_manifest.py +1 -1
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tools/shell.py +20 -9
- {gemcode-0.3.1 → gemcode-0.3.2/src/gemcode.egg-info}/PKG-INFO +1 -1
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_tools.py +18 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/LICENSE +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/MANIFEST.in +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/README.md +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/setup.cfg +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/__init__.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/__main__.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/audit.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/autocompact.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/callbacks.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/capability_routing.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/cli.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/compaction.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/computer_use/__init__.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/computer_use/browser_computer.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/config.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/context_budget.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/context_warning.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/credentials.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/hitl_session.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/interactions.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/invoke.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/kairos_daemon.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/limits.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/live_audio_engine.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/mcp_loader.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/memory/__init__.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/memory/embedding_memory_service.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/memory/file_memory_service.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/modality_tools.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/model_errors.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/model_routing.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/paths.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/permissions.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/plugins/__init__.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/prompt_suggestions.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/query/__init__.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/query/config.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/query/deps.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/query/engine.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/query/stop_hooks.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/query/token_budget.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/query/transitions.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/repl_commands.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/repl_slash.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/session_runtime.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/slash_commands.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/thinking.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tool_registry.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tools/__init__.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tools/edit.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tools/filesystem.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tools/search.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tools/shell_gate.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tools/todo.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tools_inspector.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/trust.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tui/app.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/tui/scrollback.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/vertex.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/web/__init__.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/web/claude_sse_adapter.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode/web/terminal_repl.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode.egg-info/SOURCES.txt +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode.egg-info/dependency_links.txt +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode.egg-info/entry_points.txt +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode.egg-info/requires.txt +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/src/gemcode.egg-info/top_level.txt +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_autocompact.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_capability_routing.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_claude_web_adapter_sse.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_cli_init.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_computer_use_permissions.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_context_budget.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_context_warning.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_credentials.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_interactive_permission_ask.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_kairos_scheduler.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_modality_tools.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_model_error_retry.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_model_errors.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_model_routing.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_paths.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_permissions.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_prompt_suggestions.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_repl_commands.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_repl_slash.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_slash_commands.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_thinking_config.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_token_budget.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_tool_context_circulation.py +0 -0
- {gemcode-0.3.1 → gemcode-0.3.2}/tests/test_tools_inspector.py +0 -0
|
@@ -74,7 +74,7 @@ You operate only inside the user's project directory (current working directory)
|
|
|
74
74
|
- **`run_command` rules (critical):**
|
|
75
75
|
- `command` must be a **single executable basename** (e.g. `npm`, `npx`, `mkdir`) — **not** `bash`, `sh`, or `cd foo && ...`.
|
|
76
76
|
- Pass argv as `args` (list). To run a command **inside** a subfolder (e.g. Next app in `testing/`), set **`cwd_subdir`** to that relative path (e.g. `"testing"`) and run `npm run dev` there — **never** simulate `cd` with `bash`.
|
|
77
|
-
- **Scaffolding** (`create-next-app`, etc.): many CLIs require non-interactive mode — pass **`
|
|
77
|
+
- **Scaffolding** (`create-next-app`, etc.): many CLIs require non-interactive mode — pass **`extra_env_keys`** / **`extra_env_values`** as parallel lists (e.g. `["CI"]` and `["1"]`) and/or flags supported by that tool (`--yes` where documented).
|
|
78
78
|
- **Dev servers** (`npm run dev`, `vite`, etc.) run until stopped: use **`background=True`** so the process detaches; otherwise the tool may time out. You cannot open a *new OS terminal window* from here—background start is the supported way to keep running.
|
|
79
79
|
- **Parallelize:** when you need several **independent** reads or searches (no output from one is required to form the next call), issue them together in one turn so the user gets answers faster. When step B depends on step A's result, run **sequentially**.
|
|
80
80
|
- **Deletion:** use `delete_file` for a single file under the project root; reserve `rm` via `run_command` for unusual cases.
|
|
@@ -120,7 +120,7 @@ You may call tools as follows:
|
|
|
120
120
|
Notes:
|
|
121
121
|
- Prefer `python -m pip ...` (or `python3 -m pip ...`) so installs stay in the active virtualenv.
|
|
122
122
|
- Do not assume sudo/system package manager access.
|
|
123
|
-
- `run_command` supports `cwd_subdir` (relative path under the project) instead of `cd`/`bash`; use `
|
|
123
|
+
- `run_command` supports `cwd_subdir` (relative path under the project) instead of `cd`/`bash`; use parallel `extra_env_keys` / `extra_env_values` (e.g. ["CI"] and ["1"]) for non-interactive installers; use `background=true` for long-running dev servers.
|
|
124
124
|
|
|
125
125
|
Optional capability tools:
|
|
126
126
|
- Deep research built-ins are {'ON' if deep_research_on else 'OFF'}.
|
|
@@ -7,7 +7,6 @@ import re
|
|
|
7
7
|
import shutil
|
|
8
8
|
import subprocess
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any
|
|
11
10
|
|
|
12
11
|
from google.adk.tools.tool_context import ToolContext
|
|
13
12
|
|
|
@@ -18,12 +17,12 @@ from gemcode.tools.shell_gate import consume_confirmed_shell_if_matches
|
|
|
18
17
|
from gemcode.trust import is_trusted_root
|
|
19
18
|
|
|
20
19
|
|
|
21
|
-
def _merge_child_env(
|
|
22
|
-
"""Merge
|
|
20
|
+
def _merge_child_env(keys: list[str], values: list[str]) -> dict[str, str]:
|
|
21
|
+
"""Merge parallel key/value lists into os.environ (Gemini API rejects dict-typed tool params)."""
|
|
23
22
|
out = {**os.environ}
|
|
24
|
-
if not
|
|
23
|
+
if not keys and not values:
|
|
25
24
|
return out
|
|
26
|
-
for k, v in
|
|
25
|
+
for k, v in zip(keys, values):
|
|
27
26
|
if not isinstance(k, str) or not isinstance(v, str):
|
|
28
27
|
continue
|
|
29
28
|
if not re.match(r"^[A-Za-z_][A-Za-z0-9_]*$", k):
|
|
@@ -45,7 +44,8 @@ def make_run_command(cfg: GemCodeConfig):
|
|
|
45
44
|
tool_context: ToolContext | None = None,
|
|
46
45
|
cwd_subdir: str = ".",
|
|
47
46
|
background: bool = False,
|
|
48
|
-
|
|
47
|
+
extra_env_keys: list[str] | None = None,
|
|
48
|
+
extra_env_values: list[str] | None = None,
|
|
49
49
|
) -> dict:
|
|
50
50
|
"""
|
|
51
51
|
Run an allowlisted executable with arguments.
|
|
@@ -57,8 +57,9 @@ def make_run_command(cfg: GemCodeConfig):
|
|
|
57
57
|
For long-running servers (e.g. `npm run dev`), set `background=True` to start
|
|
58
58
|
a detached process and return its PID (non-interactive; no TTY for the child).
|
|
59
59
|
|
|
60
|
-
Optional `
|
|
61
|
-
|
|
60
|
+
Optional `extra_env_keys` / `extra_env_values` are parallel lists (same length)
|
|
61
|
+
merged into the child environment (e.g. keys ["CI"], values ["1"] for
|
|
62
|
+
non-interactive scaffolding tools). Omit both to use the default environment.
|
|
62
63
|
"""
|
|
63
64
|
if not trusted:
|
|
64
65
|
return {"error": "Project folder is not trusted. Re-run GemCode and approve folder trust."}
|
|
@@ -111,7 +112,17 @@ def make_run_command(cfg: GemCodeConfig):
|
|
|
111
112
|
)
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
ek = list(extra_env_keys or [])
|
|
116
|
+
ev = list(extra_env_values or [])
|
|
117
|
+
if len(ek) != len(ev):
|
|
118
|
+
return {
|
|
119
|
+
"error": (
|
|
120
|
+
"extra_env_keys and extra_env_values must be parallel lists of the same length "
|
|
121
|
+
"(one value per key)."
|
|
122
|
+
),
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
child_env = _merge_child_env(ek, ev)
|
|
115
126
|
|
|
116
127
|
if background:
|
|
117
128
|
try:
|
|
@@ -118,6 +118,24 @@ def test_run_command_background_returns_pid(tmp_path: Path, monkeypatch) -> None
|
|
|
118
118
|
assert isinstance(out.get("pid"), int)
|
|
119
119
|
|
|
120
120
|
|
|
121
|
+
def test_run_command_extra_env_merges(tmp_path: Path, monkeypatch) -> None:
|
|
122
|
+
monkeypatch.setenv("GEMCODE_HOME", str(tmp_path / ".gemstate"))
|
|
123
|
+
trust_root(tmp_path, trusted=True)
|
|
124
|
+
cfg = GemCodeConfig(project_root=tmp_path)
|
|
125
|
+
run_command = make_run_command(cfg)
|
|
126
|
+
ctx = MagicMock()
|
|
127
|
+
ctx.state = {HITL_STICKY_SESSION_KEY: True}
|
|
128
|
+
out = run_command(
|
|
129
|
+
"python3",
|
|
130
|
+
["-c", "import os; print(os.environ.get('GEMCODE_TEST_EXTRA', ''))"],
|
|
131
|
+
extra_env_keys=["GEMCODE_TEST_EXTRA"],
|
|
132
|
+
extra_env_values=["ok"],
|
|
133
|
+
tool_context=ctx,
|
|
134
|
+
)
|
|
135
|
+
assert out.get("exit_code") == 0
|
|
136
|
+
assert "ok" in (out.get("stdout") or "")
|
|
137
|
+
|
|
138
|
+
|
|
121
139
|
def test_delete_file(tmp_path: Path, monkeypatch) -> None:
|
|
122
140
|
monkeypatch.setenv("GEMCODE_HOME", str(tmp_path / ".gemstate"))
|
|
123
141
|
trust_root(tmp_path, trusted=True)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|