fix(code): dedupe update/install log path output (#4553)

`dcode update` and install commands no longer print the same log path
twice.

---

Previously, update and install flows printed the log path once by itself
and then repeated it in the tail command:

```text
Update log: /tmp/deepagents-update.log
Tail progress: tail -f /tmp/deepagents-update.log
```

Now they print a single copy-pasteable command next to the log label:

```text
Update log: tail -f /tmp/deepagents-update.log
```

The same before/after applies to `Install log:` output for both extras
installs and arbitrary package installs. This keeps the path visible
while avoiding duplicate path output in the terminal.

Made by [Open
SWE](https://openswe.vercel.app/agents/91e79ce5-84aa-d27e-8cd5-dae63b3546c1)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
Mason Daugherty
2026-07-08 20:26:14 -04:00
committed by GitHub
parent 434c84ae14
commit 1398feeca5
3 changed files with 14 additions and 5 deletions
+10 -5
View File
@@ -15,6 +15,7 @@ import importlib.util
import json
import logging
import os
import shlex
import shutil
import sys
import traceback
@@ -40,6 +41,11 @@ _SANDBOX_DEFAULT_SENTINEL = "\x00default"
"""Marker stored by `--sandbox` with no value, resolved to `[sandboxes].default`."""
def _tail_log_command(log_path: Path | str) -> str:
"""Return a copy-pasteable command for following a log file."""
return f"tail -f {shlex.quote(str(log_path))}"
def build_version_text() -> str:
"""Build the plain-text output for the `--version` CLI flag.
@@ -371,7 +377,7 @@ def _run_startup_auto_update(console: "Console") -> None:
return
log_path = create_update_log_path()
console.print(
f"Progress: tail -f {log_path}",
f"Update log: {_tail_log_command(log_path)}",
style="dim",
highlight=False,
markup=False,
@@ -2978,7 +2984,7 @@ def cli_main() -> None:
sys.exit(0)
log_path = create_update_log_path()
console.print(
f"Update log: {log_path}\nTail progress: tail -f {log_path}",
f"Update log: {_tail_log_command(log_path)}",
style="dim",
highlight=False,
markup=False,
@@ -3099,8 +3105,7 @@ def cli_main() -> None:
console.print(f"Installing package '{package}'...")
pkg_log_path = create_update_log_path()
console.print(
f"Install log: {pkg_log_path}\n"
f"Tail progress: tail -f {pkg_log_path}",
f"Install log: {_tail_log_command(pkg_log_path)}",
style="dim",
highlight=False,
markup=False,
@@ -3210,7 +3215,7 @@ def cli_main() -> None:
console.print(f"Installing extra '{extra}'...")
log_path = create_update_log_path()
console.print(
f"Install log: {log_path}\nTail progress: tail -f {log_path}",
f"Install log: {_tail_log_command(log_path)}",
style="dim",
highlight=False,
markup=False,
+2
View File
@@ -132,6 +132,8 @@ class TestStartupAutoUpdate:
_run_startup_auto_update(console)
upgrade.assert_awaited_once()
printed = " ".join(str(c.args[0]) for c in console.print.call_args_list)
assert "tail -f /tmp/dcode-update.log" in printed
restart.assert_called_once_with()
def test_successful_update_skips_restart_when_shadowed(self) -> None:
@@ -1937,6 +1937,7 @@ class TestInstallExtraSubcommand:
assert code == 0
text = self._printed_text(console_mock)
assert "Installed extra 'quickjs'" in text
assert "tail -f /tmp/deepagents-install.log" in text
def test_failure_renders_log_path_and_manual_command(self) -> None:
"""A failed install surfaces both the log path and manual script command."""
@@ -2106,6 +2107,7 @@ class TestInstallPackageSubcommand:
perform_mock.assert_awaited_once()
text = self._printed_text(console_mock)
assert "Installed package 'langchain-custom'" in text
assert "tail -f /tmp/deepagents-install.log" in text
def test_package_non_interactive_without_yes_refuses(self) -> None:
"""Non-TTY stdin + no --yes must exit 2 without installing."""