Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c46c285
feat: setup 自动登记 Console 工作区
Dandre126 Aug 4, 2026
94b10a2
feat: 优化首页编码工具引导
Dandre126 Aug 4, 2026
b0bbc68
feat: 支持 Codex 与 Claude 桌面版
Dandre126 Aug 4, 2026
f5cd7f2
feat: 优化 Dyro 引导与控制台体验
Dandre126 Aug 4, 2026
d00d5ca
feat: 完善首次设置个人偏好引导
Dandre126 Aug 4, 2026
41a8276
feat: 建立 Agent Bridge 只读基础能力
Dandre126 Aug 6, 2026
f30edb9
feat: 实现 Agent Bridge 确定性计划
Dandre126 Aug 6, 2026
6a9e7ed
fix: 收紧 Agent Bridge Git 配置边界
Dandre126 Aug 6, 2026
2787921
feat: 实现 Agent Bridge 严格传输边界
Dandre126 Aug 6, 2026
e7e1225
feat: 完善 Agent Bridge 外部能力与安全门禁
Dandre126 Aug 7, 2026
7718932
docs: 补充 Dyro 功能介绍视觉资产
Dandre126 Aug 7, 2026
e284c1c
Revert "docs: 补充 Dyro 功能介绍视觉资产"
Dandre126 Aug 7, 2026
5a7f467
fix: 修复 Agent Bridge 零副作用审计运行时路径与 fixture 契约
Dandre126 Aug 11, 2026
0c4cc7a
merge: 合并 main 并解决 cli.py 格式冲突
Dandre126 Aug 11, 2026
eb6111c
fix: 修复 Bridge CI 归档目录与版本元数据漂移
Dandre126 Aug 11, 2026
abca42c
fix: 修复 Bridge CI bind mount 与黑盒强制操作断言
Dandre126 Aug 11, 2026
f9bb14f
docs: 归档 Agent Bridge Phase 0 CI 与 host 验收证据
Dandre126 Aug 11, 2026
cc29fd6
docs: 补充 Agent Bridge F04 上下文预算证据
Dandre126 Aug 11, 2026
de6b783
docs: 记录 Agent Bridge Phase 0 最终质量门 No-Go
Dandre126 Aug 11, 2026
c329ad1
refactor: 卸掉 Ubuntu 门控 Agent Bridge 与 MCP 发布面
Dandre126 Aug 11, 2026
3d8e75f
feat: Skill 改为镜像加分身,支持多宿主安装
Dandre126 Aug 11, 2026
a450938
feat: 自定义选仓支持序号输入
Dandre126 Aug 11, 2026
c0cc8f4
fix: harden Skill legacy bounds and prep 0.6.3 release metadata
Dandre126 Aug 11, 2026
7bb8c64
docs: align Skill install note across localized READMEs
Dandre126 Aug 11, 2026
7be05c0
feat: guide and auto-repair managed Skill across setup and updates
Dandre126 Aug 11, 2026
79d18b5
merge: sync main after Skill lifecycle PR #20
Dandre126 Aug 11, 2026
92e6448
merge: sync main after 0.6.4 release metadata
Dandre126 Aug 12, 2026
98476ab
chore: 移出本地审查与会话资料
Dandre126 Aug 12, 2026
07f4d42
feat: 扩展 Dyro 只读控制面与安全边界
Dandre126 Aug 12, 2026
6d4bbac
fix: 收紧控制面隐私并优化创建确认
Dandre126 Aug 13, 2026
9d749a0
merge: sync main after 0.6.5 release metadata
Dandre126 Aug 13, 2026
b34c470
feat: 启动面支持本机已装编码工具
Dandre126 Aug 13, 2026
5535428
fix: 修正 agent discover 测试对桌面宿主的依赖
Dandre126 Aug 13, 2026
0e02266
merge: sync main after 0.6.6 release metadata
Dandre126 Aug 13, 2026
94dafa7
fix: 让裸 dyro update 确认后安装
Dandre126 Aug 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

- Make bare `dyro update` check, confirm, and install (same path as
`update now`). `update check` remains check-only; `--yes` skips the
confirmation on both `update` and `update now`.

## 0.6.6 - 2026-08-13

- Launch any installed coding tool from `dyro start` / `open`, not only a
Expand Down
6 changes: 3 additions & 3 deletions README.de.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ Erstinstallation bleibt opt-in über Setup oder
Interaktive Starts mit `dyro`, `dyro home` oder `dyro start` prüfen höchstens einmal pro lokalem Tag den offiziellen PyPI-Endpunkt. Fehler blockieren den Arbeitsbereich nicht. Standardmäßig bleibt jede Aktualisierung bestätigt:

```bash
dyro update # entspricht dyro update check
dyro update check
dyro update now
dyro update # prüfen, bestätigen, dann installieren (entspricht dyro update now)
dyro update check # nur prüfen
dyro update now # Alias von dyro update
dyro update auto on # automatische Patch-Updates aktivieren
dyro update auto off
dyro update disable
Expand Down
6 changes: 3 additions & 3 deletions README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ primera instalación sigue siendo opt-in vía setup o
Los inicios interactivos con `dyro`, `dyro home` o `dyro start` consultan el endpoint oficial de PyPI como máximo una vez al día local. Los errores nunca bloquean el espacio de trabajo y, por defecto, cada actualización requiere confirmación:

```bash
dyro update # equivalente a dyro update check
dyro update check
dyro update now
dyro update # comprobar, confirmar e instalar (equivalente a dyro update now)
dyro update check # solo comprobar
dyro update now # alias de dyro update
dyro update auto on # activa actualizaciones automáticas de parches
dyro update auto off
dyro update disable
Expand Down
6 changes: 3 additions & 3 deletions README.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ obsolète. La première installation reste opt-in via setup ou
Les lancements interactifs `dyro`, `dyro home` ou `dyro start` interrogent le point officiel PyPI au plus une fois par jour local. Un échec ne bloque jamais l’espace de travail et chaque mise à jour reste soumise à confirmation par défaut :

```bash
dyro update # équivalent à dyro update check
dyro update check
dyro update now
dyro update # vérifier, confirmer, puis installer (équivalent à dyro update now)
dyro update check # vérification seulement
dyro update now # alias de dyro update
dyro update auto on # active les mises à jour correctives automatiques
dyro update auto off
dyro update disable
Expand Down
6 changes: 3 additions & 3 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,9 @@ python3 -m pip install --user --upgrade dyro
대화형 `dyro`, `dyro home`, `dyro start` 실행은 현지 날짜 기준 하루에 한 번만 공식 PyPI 엔드포인트를 확인합니다. 실패해도 작업 공간 진입을 막지 않으며 기본적으로 업데이트 전 확인을 요청합니다.

```bash
dyro update # dyro update check 와 동일
dyro update check
dyro update now
dyro update # 확인 후 설치 (dyro update now 와 동일)
dyro update check # 검사만
dyro update now # dyro update 별칭
dyro update auto on # 패치 버전 자동 업데이트 사용
dyro update auto off
dyro update disable
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,9 @@ PyPI endpoint at most once per local day. A failed or slow check never blocks
workspace entry. Updates remain confirmation-first by default:

```bash
dyro update # same as: dyro update check
dyro update check
dyro update now
dyro update # check, confirm, then install (same as: dyro update now)
dyro update check # check only
dyro update now # alias of dyro update
dyro update auto on # opt in to patch-only automatic updates
dyro update auto off
dyro update disable # also disables automatic updates
Expand Down
6 changes: 3 additions & 3 deletions README.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ primeira instalação continua opt-in via setup ou
Execuções interativas de `dyro`, `dyro home` ou `dyro start` consultam o endpoint oficial do PyPI no máximo uma vez por dia local. Falhas nunca bloqueiam o workspace e, por padrão, toda atualização exige confirmação:

```bash
dyro update # equivalente a dyro update check
dyro update check
dyro update now
dyro update # verificar, confirmar e instalar (equivalente a dyro update now)
dyro update check # apenas verificar
dyro update now # alias de dyro update
dyro update auto on # ativa atualizações automáticas de patch
dyro update auto off
dyro update disable
Expand Down
6 changes: 3 additions & 3 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ python3 -m pip install --user --upgrade dyro
Интерактивные запуски `dyro`, `dyro home` и `dyro start` проверяют официальный PyPI не чаще одного раза за локальный день. Ошибка не блокирует вход в рабочую область, а по умолчанию обновление требует подтверждения:

```bash
dyro update # то же, что dyro update check
dyro update check
dyro update now
dyro update # проверить, подтвердить и установить (то же, что dyro update now)
dyro update check # только проверка
dyro update now # псевдоним dyro update
dyro update auto on # включить автообновление patch-версий
dyro update auto off
dyro update disable
Expand Down
6 changes: 3 additions & 3 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,9 @@ python3 -m pip install --user --upgrade dyro
交互运行 `dyro`、`dyro home` 或 `dyro start` 时,Dyro 每个本地自然日最多访问一次官方 PyPI;断网、超时或状态目录不可写都不会阻塞进入工作区。默认仍由用户确认更新:

```bash
dyro update # 等价于 dyro update check
dyro update check
dyro update now
dyro update # 检查后确认安装(等价于 dyro update now)
dyro update check # 仅检查
dyro update now # dyro update 的别名
dyro update auto on # 主动开启补丁版本自动更新
dyro update auto off
dyro update disable # 同时关闭自动更新
Expand Down
14 changes: 7 additions & 7 deletions docs/updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ automatic check.
Use an explicit command to retry or to control the saved preference:

```bash
dyro update # same as: dyro update check
dyro update check
dyro update # check, confirm, then install (same as: dyro update now)
dyro update check # check only
dyro update enable
dyro update disable
```
Expand All @@ -44,9 +44,9 @@ filter).

## Installing an update

`dyro update now` fetches the latest stable `X.Y.Z` version, shows the exact
plan, and asks before writing. For automation, review the plan first and then
use `dyro update now --yes`. Dyro recognizes its active `uv tool` or `pipx`
`dyro update` (or the `now` alias) fetches the latest stable `X.Y.Z` version,
shows the exact plan, and asks before writing. For automation, review the plan
first and then use `dyro update --yes`. Dyro recognizes its active `uv tool` or `pipx`
environment and otherwise uses the active Python interpreter's `pip`. A normal
virtual environment without pip falls back to `uv pip --python` when uv is
available. Commands are fixed argument arrays, never shell strings or
Expand All @@ -58,7 +58,7 @@ command succeeds.

Interactive `dyro setup` can install the Skill during personal preferences
(preview in the plan, applied only after confirmation). After a successful
`dyro update now` (or patch auto-update), Dyro best-effort syncs an **already
`dyro update` (or patch auto-update), Dyro best-effort syncs an **already
managed** Skill via the fresh `dyro` entry point. On interactive
`dyro` / `dyro home` / `dyro start` launches, an **outdated** managed Skill is
repaired automatically. First-time install is never forced on upgrade or
Expand Down Expand Up @@ -87,5 +87,5 @@ dyro update auto off
This preference is off by default. When enabled, only a higher patch within the
same major and minor line can install automatically, such as `0.5.5` to
`0.5.6`. A minor or major change still produces a notice and requires
`dyro update now`. An installation failure is reported but does not prevent the
`dyro update`. An installation failure is reported but does not prevent the
current Dyro launch from continuing.
24 changes: 15 additions & 9 deletions src/dyro/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1946,16 +1946,17 @@ def cmd_update_check(args: argparse.Namespace) -> None:
result = _explicit_update_check()
_print_update_result(result)
if result.kind != UpdateKind.NONE:
print("运行 dyro update now 可确认并完成更新。")
print("运行 dyro update 可确认并完成更新。")


def cmd_update_now(args: argparse.Namespace) -> None:
result = _explicit_update_check(persist=not args.dry_run)
_print_update_result(result)
if result.kind == UpdateKind.NONE:
return
yes = bool(getattr(args, "yes", False))
if (
not args.yes
not yes
and not args.dry_run
and not (sys.stdin.isatty() and sys.stdout.isatty())
):
Expand All @@ -1964,7 +1965,7 @@ def cmd_update_now(args: argparse.Namespace) -> None:
)
updated = perform_update(
result.latest_version,
yes=args.yes,
yes=yes,
dry_run=args.dry_run,
)
if updated:
Expand Down Expand Up @@ -3791,14 +3792,19 @@ def build_parser() -> argparse.ArgumentParser:
integration_uninstall_parser.set_defaults(func=cmd_integration_uninstall)
update = sub.add_parser(
"update",
help="检测并安全更新 Dyro(无子命令时等价于 update check)",
help="检测并安全更新 Dyro(无子命令时确认后安装)",
)
update.add_argument(
"--yes", action="store_true", help="确认执行已展示的更新命令"
)
update_sub = update.add_subparsers(dest="update_command", required=False)
update.set_defaults(func=cmd_update_check)
update.set_defaults(func=cmd_update_now)
update_sub.add_parser(
"check", help="立即检查官方 PyPI 的最新稳定版本(等价于 dyro update)"
"check", help="仅检查官方 PyPI 的最新稳定版本,不安装"
).set_defaults(func=cmd_update_check)
update_now = update_sub.add_parser("now", help="显示计划并更新到最新稳定版本")
update_now = update_sub.add_parser(
"now", help="显示计划并更新到最新稳定版本(等价于 dyro update)"
)
update_now.add_argument(
"--yes", action="store_true", help="确认执行已展示的更新命令"
)
Expand Down Expand Up @@ -4451,14 +4457,14 @@ def _maybe_run_daily_update(*, install=None) -> bool:
)
except (DyroError, OSError) as exc:
print(f"自动更新失败:{exc}")
print("本次启动继续使用当前版本;稍后可运行 dyro update now 重试。")
print("本次启动继续使用当前版本;稍后可运行 dyro update 重试。")
return False
if updated:
print("自动更新完成;本次启动继续运行,下次将使用新版本。")
_refresh_skill_via_new_cli()
return True
return False
print("运行 dyro update now 可一键确认更新;今天不再重复提示。")
print("运行 dyro update 可确认并完成更新;今天不再重复提示。")
return False


Expand Down
59 changes: 53 additions & 6 deletions tests/test_updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,8 @@ def test_patch_auto_update_is_opt_in_and_minor_updates_only_notify(self) -> None
install.assert_not_called()
refresh_skill.assert_not_called()
self.assertFalse(refreshed)
self.assertIn("dyro update now", output.getvalue())
self.assertIn("dyro update", output.getvalue())
self.assertNotIn("dyro update now", output.getvalue())

def test_daily_check_failure_never_blocks_or_prints(self) -> None:
from dyro.cli import _maybe_run_daily_update
Expand Down Expand Up @@ -709,7 +710,7 @@ def test_update_now_refreshes_skill_only_when_update_succeeds(self) -> None:
main(["update", "now", "--yes"])
refresh_skip.assert_not_called()

def test_bare_update_is_equivalent_to_update_check(self) -> None:
def test_bare_update_confirms_and_installs(self) -> None:
from dyro.cli import main

result = UpdateResult(
Expand All @@ -719,20 +720,66 @@ def test_bare_update_is_equivalent_to_update_check(self) -> None:
kind=UpdateKind.PATCH,
)
with tempfile.TemporaryDirectory(prefix="dyro-update-bare-") as tmp:
for argv in (["update"], ["update", "check"]):
for argv in (["update", "--yes"], ["update", "now", "--yes"]):
output = StringIO()
with (
patch.dict(os.environ, {"DYRO_HOME": tmp}),
patch("dyro.cli.check_for_update", return_value=result) as check,
patch("dyro.cli.perform_update") as install,
patch("dyro.cli.perform_update", return_value=True) as install,
patch("dyro.cli._refresh_skill_via_new_cli") as refresh,
redirect_stdout(output),
):
main(argv)
check.assert_called_once()
install.assert_not_called()
install.assert_called_once_with("0.5.6", yes=True, dry_run=False)
refresh.assert_called_once_with()
text = output.getvalue()
self.assertIn("发现 Dyro 0.5.6", text)
self.assertIn("dyro update now", text)
self.assertNotIn("运行 dyro update", text)

def test_update_check_does_not_install(self) -> None:
from dyro.cli import main

result = UpdateResult(
checked=True,
current_version="0.5.5",
latest_version="0.5.6",
kind=UpdateKind.PATCH,
)
output = StringIO()
with tempfile.TemporaryDirectory(prefix="dyro-update-check-") as tmp:
with (
patch.dict(os.environ, {"DYRO_HOME": tmp}),
patch("dyro.cli.check_for_update", return_value=result) as check,
patch("dyro.cli.perform_update") as install,
redirect_stdout(output),
):
main(["update", "check"])
check.assert_called_once()
install.assert_not_called()
text = output.getvalue()
self.assertIn("发现 Dyro 0.5.6", text)
self.assertIn("运行 dyro update 可确认并完成更新。", text)

def test_bare_update_without_yes_rejects_noninteractive(self) -> None:
from dyro.cli import cmd_update_now

result = UpdateResult(
checked=True,
current_version="0.5.5",
latest_version="0.5.6",
kind=UpdateKind.PATCH,
)
with (
patch("dyro.cli.check_for_update", return_value=result),
patch("dyro.cli.perform_update") as install,
patch("sys.stdin.isatty", return_value=False),
patch("sys.stdout.isatty", return_value=False),
redirect_stdout(StringIO()),
):
with self.assertRaisesRegex(DyroError, "非交互环境"):
cmd_update_now(argparse.Namespace(yes=False, dry_run=False))
install.assert_not_called()

def test_update_commands_work_without_a_workspace(self) -> None:
from dyro.cli import main
Expand Down