dsh-agy-link 0.4.26 → 0.4.28

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,91 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.28 (2026-09-15)
4
+
5
+ ### English
6
+
7
+ - **Fix: Long prompts no longer hit Windows `spawn ENAMETOOLONG` (issues #14 / #11).**
8
+ - When assembled argv would exceed a 24KB budget, the bridge drops `-p <prompt>` and feeds the prompt via `--input-format stream-json` on stdin (`{"event":"user","message":{"role":"user","content":...}}`), verified against live agy 1.2.x.
9
+ - **Fix: No flashing CMD consoles on Windows GUI hosts (issue #13).**
10
+ - `openBrowser` and pool `open-terminal` / `add` `execFile('cmd.exe', …)` now pass `windowsHide: true`.
11
+ - **Fix: Dropped keyword-driven Recovery-boundary prompt injection** (from PR #20). Missing-file guidance stays in `/agy status` only.
12
+ - **Fix: Harden agy conversation DB reads.** Conversation ids are whitelist-validated before path join (path-traversal guard).
13
+ - **i18n: `@deepseek-ai/dsh-client-locale` is an optional peer.** Older DSH hosts install cleanly; the client falls back to Chinese strings when `ctx.locale` is absent.
14
+ - **CI: fork PR workflow approval documented** in `AGENTS.md` (maintainers approve `action_required` runs).
15
+ - **Fix: Windows conhost flash from agy itself (issue #23).**
16
+ - Every agy spawn now defaults `AGY_CLI_DISABLE_AUTO_UPDATE=1` and `AGY_CLI_INTERACTIVE_HEADLESS=1` (present in the official binary; breaks the `--bg-updater` child chain that creates visible conhost even under `windowsHide`). Operator-set values win.
17
+ - Boot-time `agy --version` + catalog probe is deferred 4s (unref'd); catalog still refreshes lazily on first model list / turn.
18
+
19
+ ### 中文 (Chinese)
20
+
21
+ - **修复:长 prompt 在 Windows 上触发 `spawn ENAMETOOLONG`(#14 / #11)。**
22
+ - argv 预算超过 24KB 时改为 `--input-format stream-json` 经 stdin 传入 prompt,协议已在本机 agy 1.2.x 验证。
23
+ - **修复:Windows GUI 下 CMD 窗口闪烁(#13)** — 相关 `execFile` 增加 `windowsHide: true`。
24
+ - **修复:移除关键词驱动的 Recovery boundary prompt 注入**;missing_file 指引仅保留在 `/agy status`。
25
+ - **加固:** agy 会话库 conversation id 白名单校验,防路径穿越。
26
+ - **i18n:** locale peer 改为可选,旧宿主可安装;无 `ctx.locale` 时回退中文。
27
+ - **CI:** 在 `AGENTS.md` 记录 fork PR 需维护者批准 workflow。
28
+ - **修复:Windows 上 agy 自身拉起可见 conhost(#23)。** 所有 agy spawn 默认注入 `AGY_CLI_DISABLE_AUTO_UPDATE=1` 与 `AGY_CLI_INTERACTIVE_HEADLESS=1`(阻断 `--bg-updater`);启动探测延迟 4s。
29
+
30
+ ### English
31
+
32
+ - **Feature: Native `agy_tool` Tool Card UI for DSH >= 0.1.5.**
33
+ - **Root cause (verified against DSH 0.1.5-rc.2)**: The browser conversation UI (`@deepseek-ai/dsh-client-ui-tool`) hardcodes card rendering by wire tool name through a lookup table (`TOOL_VARIANTS`: `bash`/`pwsh`→terminal, `write`/`edit`→diff, `read`/`grep`/`glob`→read/search, etc.), and never consults `presentCall`/`presentResult`. The bridge's internal `agy_tool` had no entry, causing every mirrored tool step (`run_command`, `write_to_file`, `replace_file_content`, `view_file`, `grep_search`, ...) to regress to a generic "agy_tool" raw JSON text row.
34
+ - **Fix**: Registered a keyed `tool.call.toolview` extension slot for `agy_tool`, rendering native cards (`terminal`, `diff`, `read`, `search`, `list`, `delete`, `generic`) directly from mirror arguments in pure React with DSH theme CSS variables.
35
+ - **Fix: Restore Full Tool Arguments & Real Line Diffs via Agy DB (`replace_file_content` / `write_to_file`).**
36
+ - **Root cause**: agy CLI's `filterToolParameters` strips large arguments (`CodeContent`, `TargetContent`, `ReplacementContent`) from `stream-json`, leaving only metadata like `TargetFile`. Diff cards could not show old vs new line contents.
37
+ - **Fix**:
38
+ - `src/host/agy-db.ts`: Sub-millisecond deterministic protobuf parser directly extracts `tool_name` and full arguments JSON from the agy SQLite conversation database (`~/.gemini/antigravity-cli/conversations/<id>.db`), copying `-wal` and `-shm` sidecars to guarantee WAL commit visibility.
39
+ - `src/host/adapter.ts`: Dynamically resolves `activeConvId` and step index (`parseInt(ev.stepKey, 10)`), pre-resolving full tool args. Incorporates `getGitHeadContent` for `write_to_file` to diff against committed git HEAD on full-file writes.
40
+ - Fixed `readFullToolArgs` cache to reload SQLite DB when newly generated steps are queried, plus added 50ms WAL flush retry.
41
+ - **Fix: Tool Span Cutting on Completion When Output Is Omitted in Stream-JSON.**
42
+ - **Root cause**: In `agy stream-json`, file modification tools (`replace_file_content`, `write_to_file`) emit `state: "DONE"` without an `output` field in `tool_info`. `mapper.ts` previously checked `ev.tool.output !== undefined || ev.tool.error !== undefined`, dropping the completion event and causing the tool card to be skipped entirely (falling through to assistant text).
43
+ - **Fix**: Updated `EventMapper` to recognize `ev.state === 'DONE' || ev.state === 'ERROR'`, cutting the span and emitting native `agy_tool` cards even when `output` is omitted. Ensured `toolInfo.error` is populated on `state: 'ERROR'`.
44
+ - **UI: Default Collapsed State, Content Previews, Badges, and Semantic Diff Styling.**
45
+ - **Default Collapsed**: Tool cards now default to collapsed state (`useToggle(false)`), keeping the conversation stream neat and compact.
46
+ - **Content Preview**: Collapsed cards display a concise one-line preview in the header (e.g. `± demo/old.txt` for edits, `+ demo/old.txt` for writes, first line of terminal output, search queries).
47
+ - **Header Badges**: Added card kind badge (`[diff]`, `[terminal]`, etc.) and wire tool name badge (`[replace_file_content]`, `[run_command]`, etc.) beside the title.
48
+ - **Body Output Caption**: Added an uppercase **输出** (OUTPUT) label caption above the output content in the expanded card body.
49
+ - **Line Diff Styling**: Line diffs format relative paths (`Edit demo/old.txt`), bold red deletion markers (`-`) on red background, and bold green addition markers (`+`) on green background.
50
+ - **Reliable Toggle**: Replaced raw `useState` setter with `makeToggle(setValue)` to ensure infinite multi-click collapse/expand reliability.
51
+ - **Test Suite**: 22 new unit tests across `test/toolview.test.ts`, `test/agy-db.test.ts`, and `test/mapper.test.ts`. 173/173 tests passing.
52
+
53
+ ---
54
+
55
+ ### 中文 (Chinese)
56
+
57
+ - **新特性:适配 DSH >= 0.1.5 的 `agy_tool` 原生工具卡片 UI**
58
+ - **根因分析(针对 DSH 0.1.5-rc.2 前端验证)**:DSH 浏览器对话界面(`@deepseek-ai/dsh-client-ui-tool`)通过硬编码变体表(`TOOL_VARIANTS`)按 wire tool name 渲染卡片,且未消费 `presentCall`/`presentResult`。桥接内部镜像工具 `agy_tool` 未在表中,导致所有工具调用(`run_command`、`write_to_file`、`replace_file_content`、`view_file`、`grep_search` 等)均退化为带有原始 JSON 参数的通用文本行。
59
+ - **修复方案**:为 `agy_tool` 注册专有的 keyed `tool.call.toolview` 扩展槽,直接基于镜像参数渲染高仿生的原生卡片(终端 `terminal`、代码对比 `diff`、阅读 `read`、搜索 `search`、列出目录 `list`、删除 `delete`、通用 `generic`),完全使用原生 React 与 DSH 主题 CSS 变量实现。
60
+ - **修复:通过 Agy 会话数据库恢复完整工具参数与真实代码 Diff(`replace_file_content` / `write_to_file`)**
61
+ - **根因分析**:`agy` CLI 在输出 `stream-json` 时通过 `filterToolParameters` 过滤掉了大参数字段(`CodeContent`、`TargetContent`、`ReplacementContent` 等),导致前端 Diff 卡片仅能拿到 `TargetFile`,无法展示旧行与新行的代码变更。
62
+ - **修复方案**:
63
+ - `src/host/agy-db.ts`:实现确定性亚毫秒级 Protobuf 解析器,直接从本地 SQLite 会话库(`~/.gemini/antigravity-cli/conversations/<id>.db`)精准提取完整 JSON 参数,并拷贝 `-wal` 和 `-shm` 侧车文件以保证 WAL 提交完全可见。
64
+ - `src/host/adapter.ts`:动态获取 `activeConvId` 与真实的步骤索引(`parseInt(ev.stepKey, 10)`),提前异步解析全量参数;并在 `write_to_file` 时结合 `getGitHeadContent` 读取已提交的 Git HEAD 内容进行整文件 Diff 比对。
65
+ - 修复 `readFullToolArgs` 缓存:当查询会话后续新增的步骤时重新读取数据库,并加入 50ms WAL 刷盘重试容错。
66
+ - **修复:解决 stream-json 中工具完成无 output 时卡片截断丢失问题**
67
+ - **根因分析**:在 `agy stream-json` 中,文件修改与写入工具(`replace_file_content`、`write_to_file`)在 `state: "DONE"` 时 `tool_info` 不输出 `output` 字段。原 `mapper.ts` 检查 `output !== undefined` 导致该完成事件被丢弃,卡片从未触发截断派发,直接滑入了后续助手正文。
68
+ - **修复方案**:更新 `EventMapper` 完成判断,支持 `state === 'DONE' || state === 'ERROR'`,确保无输出工具亦能正常截断并生成原生工具卡片。
69
+ - **界面优化:默认折叠状态、单行内容预览、卡片双徽章与高亮 Diff 呈现**
70
+ - **默认折叠**:工具卡片默认初始为折叠状态(`useToggle(false)`),保持对话流整洁紧凑,点击卡片头部即可展开查看输出。
71
+ - **单行内容预览**:折叠状态下在头部展示单行内容摘要(如 Diff 显示 `± demo/old.txt` 或 `+ demo/old.txt`,终端显示首行输出,只读显示文件路径等)。
72
+ - **双标签徽章**:卡片头部展示卡片类型徽章(如 `[diff]`、`[terminal]`)与工具原始名(如 `[replace_file_content]`、`[run_command]`)。
73
+ - **正文输出标题**:卡片正文区域增设大写 **输出**(OUTPUT)标签标题。
74
+ - **Diff 高亮呈现**:标题展示相对工作区路径(`Edit demo/old.txt`),删除行带有加粗红底 `-`,新增行带有加粗绿底 `+`。
75
+ - **展开/折叠防死锁**:修复 `useToggle` 在无参调用时触发 `setState(undefined)` 导致折叠后无法再次展开的缺陷,封装为纯函数 `makeToggle` 保证多轮点击稳定翻转。
76
+ - **测试套件**:新增 22 个单元测试用例,涵盖 `test/toolview.test.ts`、`test/agy-db.test.ts` 与 `test/mapper.test.ts`,173 个测试全部通过。
77
+
78
+ ---
79
+
80
+ ## 0.4.27 (2026-09-11)
81
+
82
+ - **Fixed: Windows binary discovery misses the official Google installer path (Issue #7).**
83
+ - `resolveAgyBin()` now probes `%LOCALAPPDATA%\agy\bin\agy.exe` (plus `.cmd`/`.bat` siblings and the WinGet Links shim), so installs via `irm https://antigravity.google/cli/install.ps1 | iex` no longer raise `AGY_NOT_INSTALLED` when PATH has not propagated to the GUI process.
84
+ - **Fixed: Quota unavailable on Linux (Issue #8).**
85
+ - Added `readLinuxSecretToken()`: the primary account's OAuth credential is now read from the FreeDesktop Secret Service (GNOME Keyring / KDE Wallet) via `secret-tool`, with a python3-dbus fallback — the same `service="gemini" / username="antigravity"` go-keyring slot agy writes on Linux.
86
+ - `QuotaService.readSystemKeychainToken()` now dispatches per platform (darwin → Keychain, linux → Secret Service), restoring quota refresh on Linux where no on-disk token file exists.
87
+ - Shared go-keyring payload parsing (raw or `go-keyring-base64:` prefixed JSON) extracted into `parseGoKeyringPayload`.
88
+
3
89
  ## 0.4.26 (2026-09-07)
4
90
 
5
91
  - **Added: Support for `gemini-3.8-flash` in Fallback Models Catalog (Issue #6).**
package/README.md CHANGED
@@ -14,7 +14,10 @@
14
14
  <p align="center">
15
15
  <b>🌐 Language / 语言:</b>
16
16
  <a href="#中文">中文</a> ·
17
- <a href="#english">English</a>
17
+ <a href="#english">English</a> ·
18
+ <a href="./docs/README.pt-BR.md">Português (Brasil)</a> ·
19
+ <a href="./docs/README.es.md">Español</a> ·
20
+ <a href="./docs/README.en.md">English (standalone)</a>
18
21
  </p>
19
22
 
20
23
  ---
@@ -127,7 +130,7 @@ dsh plugin --profile web add dsh-agy-link
127
130
  | --- | --- | --- | --- |
128
131
  | `enabled` | `DSH_AGY_ENABLED` | `true` | 插件主开关 |
129
132
  | `agyBin` | `DSH_AGY_BIN` | 自动探测 | 显式指定 `agy` 二进制路径 |
130
- | `permissionMode` | `DSH_AGY_MODE` | `skip` | 权限模式:`skip`(免审批推荐)/ `plan`(只读)/ `accept-edits` |
133
+ | `permissionMode` | `DSH_AGY_MODE` | `skip` | 权限模式:`skip`(无人值守执行)/ `plan` / `accept-edits` |
131
134
  | `defaultModel` | `DSH_AGY_DEFAULT_MODEL` | `(agy 默认)` | 默认模型 slug |
132
135
  | `defaultEffort` | `DSH_AGY_DEFAULT_EFFORT` | `(模型默认)` | 思考预算:`low` / `medium` / `high` |
133
136
  | `timeoutMs` | `DSH_AGY_TIMEOUT_MS` | `600000` | 单轮活跃看门狗超时(毫秒) |
@@ -263,7 +266,7 @@ dsh plugin --profile web add dsh-agy-link
263
266
  | --- | --- | --- | --- |
264
267
  | `enabled` | `DSH_AGY_ENABLED` | `true` | Master switch |
265
268
  | `agyBin` | `DSH_AGY_BIN` | auto-detected | Path to `agy` binary |
266
- | `permissionMode` | `DSH_AGY_MODE` | `skip` | `skip` (recommended) / `plan` (read-only) / `accept-edits` |
269
+ | `permissionMode` | `DSH_AGY_MODE` | `skip` | `skip` (unattended execution) / `plan` / `accept-edits` |
267
270
  | `defaultModel` | `DSH_AGY_DEFAULT_MODEL` | `(agy default)` | Default model slug |
268
271
  | `defaultEffort` | `DSH_AGY_DEFAULT_EFFORT` | `(model default)` | Thinking budget: `low` / `medium` / `high` |
269
272
  | `timeoutMs` | `DSH_AGY_TIMEOUT_MS` | `600000` | Activity watchdog timeout in milliseconds |
@@ -271,6 +274,22 @@ dsh plugin --profile web add dsh-agy-link
271
274
 
272
275
  ---
273
276
 
277
+ ## Headless operation
278
+
279
+ See [Headless permissions](docs/HEADLESS-PERMISSIONS.md) for a bounded reproduction,
280
+ least-privilege read-rule validation, and process-versus-tool acceptance checks.
281
+
282
+ The plugin passes the selected permission mode to `agy`; it does not approve,
283
+ deny, or bypass permissions itself. In headless/print operation, `agy` can
284
+ automatically deny a tool request in `plan` or `accept-edits`. The raw tool
285
+ error is retained in `/agy status`; it is not proof of a human denial.
286
+
287
+ Do not assume undocumented wildcard semantics for either mode. Test the exact
288
+ `agy` version and command set in a scoped workspace. Choose `skip` only when
289
+ you explicitly accept unattended tool execution.
290
+
291
+ ---
292
+
274
293
  ## ⚠️ Disclaimer
275
294
 
276
295
  This plugin operates strictly by invoking the official, unmodified `agy` CLI binary installed on your local system. Use of this plugin is subject to Google Antigravity's Terms of Service.