tianshu-mcp 0.5.2 → 0.5.4

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.en.md CHANGED
@@ -1,744 +1,798 @@
1
- # Changelog
2
-
3
- All notable changes to `tianshu-mcp` are documented here. The format follows
4
- [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to
5
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
-
7
- Chinese version: [CHANGELOG.md](CHANGELOG.md)
8
-
9
- ---
10
-
11
- ## [Unreleased]
12
-
13
- ### Planned
14
-
15
- - **Visual acceptance phase 2 — AI visual content validation** (issue #13): validate whether image/page-screenshot *content* matches the task description (logo elements, style match, page semantics, etc.). Marked in issue #3 as an "optional extension"; its pixel-comparison phase 1 shipped with v0.5.0. Requires settling the model/credential source (without breaking the "zero credential management" red line), judgement debouncing, and gate placement (warning-only by default is suggested).
16
- - More external AI-Agent adapters (a new agent = one profile + an optional adapter file).
17
- - TraeWork executable discovery and native-dialog driving on macOS (currently fail-closed).
18
- - Optional project-level skill seeding (by default nothing is written into target repos).
19
- - Cancel/rework/new-project matrices for the Codex and ZCode GUI drivers on macOS (both remain `research` on darwin).
20
- - Best-effort stop of a GUI-side pending session (via a temporary CDP connection) when cancelling
21
- a task in the `needs_user` state.
22
- - Real-machine verification of project-less dispatch on macOS (this round covers Windows 10 only).
23
-
24
- ---
25
-
26
- ## [0.5.2] — 2026-09-14
27
-
28
- **Project-less dispatch for ZCode (issue #12)**: `run_task`'s `projectPath` is now optional, letting ZCode run tasks in its `default` workspace; the companion `allowCreateProject` can forbid automatic project import. See the [v0.5.2 release notes](docs/release-v0.5.2.en.md) and the [Windows 10 acceptance record](docs/zcode-issue-12-windows-evidence.en.md).
29
-
30
- ### Added
31
-
32
- - **Project-less dispatch for ZCode (issue #12)**: `run_task`'s `projectPath` is now optional. When omitted, ZCode runs the task in its `default` workspace — no directory assigned, no project registered or imported, no Git baseline, no project snapshot freeze, no project lock, no project acceptance. On success the task is marked structurally as `not_applicable: no_project` and the terminal message states "no project acceptance performed". `query_task` / `list_tasks` display such tasks normally; `verify_task` / `get_task_report` return an explicit not-applicable explanation instead of deriving a directory from cwd.
33
- - **`allowCreateProject` (ZCode-only, optional boolean)**: omitted keeps the existing "auto-import when the target is unregistered" behaviour; explicit `false` stops dispatch **before any import side effect** when the target is unregistered, returning a recognisable `project_not_registered` reason with remediation (no native folder dialog, no project added). Other agents passing this parameter get an explicit "not supported" error rather than a silent ignore.
34
- - **Windows 10 hardware acceptance record** (`docs/zcode-issue-12-windows-evidence{,.en}.md`): complete evidence for project-less dispatch and `allowCreateProject=false` on ZCode 3.11.2.6792, including the before/after comparison "ZCode project entries 34 → 34, 0 added / 0 removed".
35
-
36
- ### Fixed
37
-
38
- - **Divergent project-trigger readiness criteria (issue #12 §5)**: waiting used `exists` (element has width/height only) while clicking went through `pick` (exactly one unclipped visible node in the winning tier), so an `exists=true` / `click=false` window existed. Waiting and clicking now share one **structured probe** that distinguishes not-mounted / mounted-but-invisible-or-clipped / ambiguous / disabled / covered / ready, plus a post-click condition: the project menu must actually open, and `menu-not-open` is classified separately.
39
- - **Error message contradicting behaviour**: "waiting for the project trigger timed out" is no longer used for early exits (multiple matches, disabled) or a menu that never opened; failure text carries `selector`, match count and minimal hit-node attributes, and diagnostics log attempt count, elapsed time and remaining budget.
40
- - **Centralised timeout**: new `gui.projectTriggerTimeoutMs` (default 15s) replaces the two hard-coded `15_000` literals; the whole "wait → one sidebar fallback → wait" sequence shares a single deadline, retries do not reset the budget, and it is clamped by the setup-recovery budget and the task deadline.
41
- - **`projectPath` was never opened up in the MCP schema (found on hardware)**: the handler already had the project-less branch, but `RunTaskParamsSchema.projectPath` was still required, so a real `run_task` was rejected by the SDK with `-32602 Required at projectPath`. Unit tests call the handler directly and therefore bypass `inputSchema`, which is why a green suite missed it. Changed to `AbsPath.optional()`, plus a protocol-level regression case in `test/integration/task-flow.test.ts` asserting neither `-32602` nor `Input validation error` appears.
42
- - **No "work outside a project" switch, and the menu click was undone by toggle semantics (found on hardware)**: ZCode's "New task" inherits the previous binding, so project-less dispatch parked at `needs_user` forever; meanwhile `clickProjectTriggerAndConfirm` kept clicking the trigger even when the project menu was **already open**, closing the Radix dropdown and then polling until its deadline, misreported as "the project menu did not open". Added the `workOutsideProject` selector and `enterDefaultWorkspace()` for an explicit switch (confirmed by `workspaceBinding` read-back, not by click success), made the click check the menu state first, and made `confirmDefaultWorkspace` return immediately for "definitely bound to a project".
43
-
44
- ---
45
-
46
- ## [0.5.1] — 2026-09-14
47
-
48
- Documentation and validation-evidence completion; **no runtime behaviour changes**. See the [v0.5.1 release notes](docs/release-v0.5.1.en.md) for details.
49
-
50
- ### Added
51
-
52
- - `npm run evidence:visual:windows` (`scripts/evidence-visual-windows.mjs`): collects the full Windows 10 local functional matrix (existing/static/command sources, port conflict that blocks without terminating another service, bounded readiness failure that cleans up the child process, local Edge isolated instance and version mismatch, missing-browser blocker), 9/9 passed.
53
- - `docs/visual-validation-evidence/`: raw machine-readable validation records (Windows 10 matrix JSON and test output, macOS dual-architecture `environment.json`, macOS CI summaries), distributed with the package.
54
-
55
- ### Fixed
56
-
57
- - Stale `package-lock.json` root version: the lockfile still said `0.4.1` at the v0.5.0 release while `package.json` said `0.5.0`; both are now synced to `0.5.1`.
58
-
59
- ### Tests
60
-
61
- - Two additional real-browser-gated visual cases: screenshots succeed when the project path contains CJK characters and spaces; a main-document 302 redirect to a non-allowlisted origin is blocked by policy and passes once explicitly allowed. Full suite: **486 passed / 10 skipped**.
62
- - Collected macOS 13+ platform evidence: on macOS 15 hardware runners, Intel x64 and Apple Silicon arm64 (Node 20/22/24) each passed 10 files with 51 cases.
63
-
64
- ### Docs
65
-
66
- - **Skill docs (`skills/tianshu-mcp/`) aligned with the code**: `SKILL.md` now lists all 11 tools with capability/approval columns (including `prepare_visual_baseline`/`approve_visual_baseline`), gives visual acceptance its own section (blockers do not trigger repair; `rework_task` re-verifies first; baseline approval and freezing), adds `setup_recovery` and the `errorType` value set to the error table, corrects agent status semantics (`traework` is always `ready`; `codex` is platform-dependent) and notes that `continue_task` only supports codex/zcode. `usage-examples.md` fixes the claim that `get_task_report` carries a meta block, removes the mis-listed `reasoningLevel` from the meta table, distinguishes the auto repair-plan location per agent (codex writes inside the project's `.zcode/plans/`; others write to the task directory), and adds the actual `list_tasks` output columns plus the visual CLI commands.
67
- - `docs/visual-validation{,.en}.md` rewritten with full platform evidence tables (system, Node, browser version, command, result).
68
- - Bilingual README and HANDOFF updated against the current code and commit history.
69
-
70
- ---
71
-
72
- ## [0.5.0] — 2026-09-14
73
-
74
- Adds an **optional visual acceptance module** that wires screenshot comparison and static image specification checks into the "develop → verify → repair → re-verify" loop. Projects that do not enable visuals behave compatibly, and legacy reports and task snapshots remain readable. See the [v0.5.0 release notes](docs/release-v0.5.0.en.md) for the full description.
75
-
76
- ### Added
77
-
78
- - **Page sources**: mutually exclusive `existing` / `command` / `static`; identical service definitions share one managed instance per round; the static host rejects traversal and out-of-project symlinks; an occupied port blocks instead of reusing or terminating another service.
79
- - **Screenshots and interaction**: `viewport` / `fullPage` / `element` modes with declarative `click` / `input` / `hover` / `scroll` / `wait` steps; a fixed readiness flow (isolated context, login state, fonts and images, disabled animations, masks, sampling); bounded full-page scrolling to trigger lazy loading.
80
- - **Stabilization and masks**: up to 3 samples taking two adjacent identical captures; continuously changing pages, exceeded pixel budgets and unstable captures block; an unmatchable mask selector or a fully masked image never passes.
81
- - **Pixel comparison**: unified PNG; size mismatches fail without scaling; masked regions are excluded from numerator and denominator; pixelmatch antialiasing is excluded by default; connected-component analysis outputs coordinates, areas and an annotated image, keeping at most 100 regions while recording the remaining count and overall bounds.
82
- - **Static image specifications**: explicit file lists; encoded-format/extension consistency, existence with complete decoding, EXIF-orientation-normalized dimensions, aspect ratio, byte size, optional DPI and real-transparent-pixel detection; unsupported formats are reported explicitly.
83
- - **Two-phase baselines**: `prepare` produces a candidate (candidate ID, digest, target paths, preview) and `approve` verifies candidate/original-baseline/configuration digests before atomically writing the official baseline and manifest; a missing baseline can only produce a candidate and never a pass; automatic repair never calls the approval entry point.
84
- - **Rule freezing**: visual configuration and baseline digests are saved before the agent starts and checked around each round; changes require a new snapshot through the dedicated `rules review` / `rules approve` flow.
85
- - **MCP tools**: new `prepare_visual_baseline` and `approve_visual_baseline`, both side-effecting `write` operations requiring host approval.
86
- - **CLI**: new `tianshu-mcp visual` subcommand (`init`, `browser install`, `doctor`, `baseline prepare/approve`, `rules review/approve`, `artifacts clean`), dispatched before the stdio connection.
87
- - **Reports and artifacts**: `VerifyReport` gains an optional `visual` field and `files.html`; the offline HTML supports status filtering, side-by-side images, opacity overlays and region location with only local artifacts, escaped text and no CDN; each round's artifacts live at `<home>/tasks/<taskId>/visual/<round>/` with rounds allocated by a unified task-level lock.
88
- - **Blockers and recovery**: distinguishes repairable defects, environment blockers and user cancellation; visual blockers enter `needs_attention` with a re-verification-pending marker; `rework_task` re-verifies first for visually blocked tasks and only real defects consume the repair budget; both the generic and Codex-specific repair plans include visual evidence and state that baselines, thresholds and switches must not be modified to bypass failures.
89
- - **Configuration robustness**: an invalid acceptance configuration blocks explicitly instead of falling back silently; only an explicit `checks: []` disables command checks; `extraChecks` and `checksMode=replace` never override the visual gate; `visual` strictly validates unknown fields, duplicate IDs, empty rules and conflicting options.
90
- - **Dependencies and runtime**: pinned `puppeteer-core@24.43.1`, `@puppeteer/browsers@2.13.2`, `sharp@0.34.5`, `pixelmatch@7.2.0`; the image library is an optional dynamic dependency whose absence does not prevent startup; browsers are installed explicitly on demand with no download during npm install or MCP startup; the visual module requires Node.js >=20.3 while non-visual features retain >=20.
91
- - **Docs and gates**: new bilingual visual acceptance guide and validation progress; CI adds a real-browser matrix (ubuntu/windows/macos-intel/macos × Node 20/22/24) plus production-package consumer acceptance; release requires a successful CI for the target commit and blocks when mirror credentials are missing.
92
-
93
- ### Fixed
94
-
95
- - The acceptance engine no longer silently falls back to default checks when a project configuration is invalid; it blocks explicitly with a reason.
96
- - Manual and automatic verification share the task-level lock for report round allocation, preventing concurrency or recovery from overwriting historical evidence.
97
- - Manual verification now lands a visually blocked task in `needs_attention` instead of misreporting `failed`.
98
- - `rework_task` allows a visually blocked task that lacks original session location information to re-verify first instead of being rejected outright.
99
- - The ZCode recovery budget now determines the controlling reason before aborting dependent operations, so the reason is not overwritten by downstream abort listeners.
100
- - `TaskOrchestrator` distinguishes "cancelled" from "blocked" when a visual integrity problem appears during startup, so cancellation is no longer misrecorded as `needs_attention`.
101
-
102
- ### Tests
103
-
104
- - Full suite: **486 passed / 8 skipped** (Windows 10 x64, Node 24.18.0), adding visual configuration, image specification, report, baseline, budget, snapshot, service, real-browser capture, flow and repair cases.
105
- - The 8 real-browser-gated cases pass separately with `TIANSHU_VISUAL_BROWSER_TEST=1`; the production tarball visual smoke test passes in an isolated consumer.
106
-
107
- ---
108
-
109
- ## [0.4.1] — 2026-09-13
110
-
111
- Documentation release: the orchestration skill docs are aligned with the actual v0.4.0 tool
112
- surface, and the open-source repos now credit community contributors. No code behaviour changes.
113
-
114
- ### Docs
115
-
116
- - **Skill docs fully aligned with the v0.4.0 tool surface** (`skills/tianshu-mcp/`, idempotently synced
117
- into `~/.rivet/skills/tianshu-mcp/` at server startup):
118
- - `SKILL.md` now documents the **projectPath safety gate** (absolute path + existing directory +
119
- realpath canonicalization, rejection of the home directory and system/root directories, dirty-repo
120
- warning), so an infrastructure rejection is not mistaken for an agent failure.
121
- - `SKILL.md` adds a **hard-failure error-code reference** (`setup_failed`/`project_ambiguous`/
122
- `project_mismatch`/`model_unavailable`/`model_mismatch`/`permission_unknown`/`cdp_disconnected`/
123
- `instance_busy`/`session_lost`/`input_mismatch`/`send_unknown`/`idle_timeout` and more), stating
124
- that hard failures never enter acceptance or auto-rework.
125
- - `SKILL.md` covers all `needs_user` kinds, including the new `setup_recovery` (zcode initialization
126
- recovery exhausted), plus `continue_task` state/type restrictions and the refusal semantics when the
127
- zcode session anchor is lost.
128
- - `SKILL.md` documents the `codex-cli` headless path (user-defined `driver=spawn` profile, `model` not
129
- applicable, CLI ≥0.154.0 requirement), the `ready`/`research` status semantics, **default-parallel 2**
130
- acceptance checks (`verifyConcurrency`), and the `requireChanges` zero-change gate.
131
- - `usage-examples.md` adds: a `codex-cli` dispatch example; the **full meta-block field table** (now
132
- including `agentEndReason`/`lastRunSignal`/`checks`/`round`/`keptInstance`/`zcodeSessionId`/
133
- `modelProvider`/`permissionMode`/`progressSummary`); an **error-code reference table**; a project-level
134
- `.tianshu-mcp/acceptance.json` template (with the parallel-interference warning and `requireChanges`
135
- guidance); a `setup_recovery` recovery example; and the profile whole-key override semantics.
136
- - **Bilingual README contributor credits**: a new "Contributors" section lists, in order of first
137
- participation, the community members who took part through Issues and pull requests (avatar + name).
138
-
139
- ### Other
140
-
141
- - `package.json` version bumped to `0.4.1` (`serverInfo.version` is synced automatically at build time).
142
-
143
- ---
144
-
145
- ## [0.4.0] — 2026-09-13
146
-
147
- ### Added
148
-
149
- - `projectPath` safety gate: `run_task`/`verify_task` validate at submission (absolute path +
150
- existing directory + realpath symlink resolution), reject the home directory itself and
151
- system/root directories (including macOS `/private/*` realpath forms); the submission receipt
152
- notes symlink resolution; dirty git repos get an uncommitted-changes coexistence warning.
153
- - ZCode GUI driver supports macOS: adapts to the main process rewriting its title (relaxed port
154
- attribution + bounded scan of the configured port range when argv hides the debug port) and
155
- detached+unref instance persistence; the folder-panel driver is rewritten for the macOS window
156
- form (NSOpenPanel as a standalone window + AX value write into the go-to field, immune to IME
157
- interception). Machine-verified closed loop on 2026-09-13 (macOS arm64, ZCode 3.11.2: bind →
158
- readback → send → run evidence → acceptance PASS → succeeded); macOS stays `research` until
159
- the cancel/rework/new-project matrix is covered.
160
- - Codex GUI driver supports macOS: spawns the ChatGPT.app bundle executable directly
161
- (per-platform `activation` default spawn/msix-com) with detached+unref instance persistence;
162
- POSIX process enumeration and SIGTERM stop; default discovery dirs on darwin; project
163
- registration writes the shared state file (`~/.codex/.codex-global-state.json`) on darwin too;
164
- the observation loop reconnects CDP across transient renderer hangs / target replacement
165
- (only 5 consecutive failures count as disconnected). Machine-verified closed loop on
166
- 2026-09-13 (macOS arm64: discover → register → bind → send → run evidence → acceptance PASS
167
- → succeeded); macOS stays `research` until the cancel/rework matrix is covered.
168
-
169
- ### Fixed
170
-
171
- - zcode macOS new-task inert-button fallback: `conversation-new-task` can hit an inert home-screen
172
- icon (click does nothing); when the project trigger misses, the flow now falls back to the
173
- sidebar `[data-testid=task-new-button]` and retries.
174
- - `normalizeProjectPath` resolves symlinks: macOS `/tmp`→`/private/tmp` used to fail project
175
- path matching and degrade into a name match, falsely reporting `project_ambiguous`;
176
- falls back to lexical normalization when realpath fails.
177
- - zcode macOS panel failures no longer misreport `needsPermission`: the execFile message embeds
178
- the full script text (containing the `ACCESSIBILITY_PERMISSION_REQUIRED` literal), so every
179
- failure looked like a permission problem — the check now reads the stderr execution-error line.
180
- - `get_profiles` now lists user-defined profiles from the data-directory `agent-profiles.json`
181
- (previously hidden until first resolve, even though `run_task` could already use them — inconsistent discovery feedback).
182
- - zcode-flow test stubs now cover `listDialogs`, removing a flake where real osascript/PowerShell
183
- calls blew the `taskTimeoutMs` wall-clock budget under full-suite load.
184
- - CDP `connect()` failure paths now dispose of the WebSocket themselves (no longer relying on
185
- callers to disconnect); the `send()` timeout timer is unref'd.
186
- - **Drive roots were not rejected by the `projectPath` gate** (Windows): `normPath` strips the
187
- trailing slash (`D:\` -> `d:`), which never equals the `d:/` entries in the reject list, so the
188
- gate was effectively a no-op for drive roots; a dedicated drive-root check now covers every
189
- drive letter instead of relying on enumeration.
190
- - `test/unit/project-dir-guard.test.ts` had a non-portable system-directory assertion: `/etc` and
191
- `/usr` are POSIX paths, and on Windows they hit "directory does not exist" rather than the reject
192
- list; the assertion is now platform-branched and verifies drive roots plus `C:/Windows` on Windows.
193
- - `test/unit/acceptance-parallel.test.ts` cancellation case was flaky (green alone, red in a full
194
- run): a fixed 250ms delay can precede the child spawn on slower platforms, mislabelling an
195
- in-flight check as `skipped`; it now waits until both in-flight checks have really started.
196
-
197
- ### Performance
198
-
199
- - All `execFileSync`/`spawnSync` calls across GUI instance probing, discovery and registration
200
- are now async; ready-wait loops reuse a per-tick process snapshot with a 1.5s TTL cache —
201
- eliminating event-loop freezes during Windows polling (up to 30s per call).
202
- - Acceptance command checks run with bounded parallelism: new `verifyConcurrency` (**⚠ default
203
- changed from serial to 2**, range 1–4; project-level `.tianshu-mcp/acceptance.json` overrides,
204
- 1 = fully serial — set 1 explicitly for checks that write build outputs, run with `--fix`, or
205
- share cache directories); logs are concatenated in declaration order with unchanged format;
206
- cancellation interrupts both in-flight and pending checks.
207
- - Git baseline hashing is single-pass with bounded async concurrency (untracked cap 5000);
208
- code analysis reads each file at most once, sniffing only a prefix of large files.
209
- - `get_profiles` and task snapshot reads now use `Promise.all`.
210
- - Test suite 267s → 51s: traework UI-layer sleeps are injectable (production defaults unchanged);
211
- vitest split into parallel unit / serial integration projects.
212
- - `tsconfig.build.json` no longer emits declarations — 70 `.d.ts` files dropped (140 → 71 files).
213
-
214
- ### Documentation
215
-
216
- - README (both languages) gains "macOS headless path: codex-cli (user profile)" — including the
217
- revoked-certificate warning for ≤0.130.0 and a complete profile example.
218
-
219
- ---
220
-
221
- ## [0.3.4] — 2026-09-13
222
-
223
- - Fix #8/#10 project-selector ambiguity, full-path binding false negatives and contaminated model readback.
224
- - Fix #9 environment recovery without a session: send full task/context/references once and locate the session through its marker or unique delta.
225
- - Add initialization recovery with shared deadlines, configurable budgets and a resumable `setup_recovery` state. Reconcile native side effects after timeouts and terminate helper processes on cancellation.
226
- - Handle split model labels, hidden outgoing animation text, residual project menus trapping focus and send buttons that are not yet ready.
227
- - Add real DOM and recovery/cancellation regressions. Windows hardware verifies cold first import, imported-project reuse and same-task recovery with actual artifacts and 2/2 acceptance checks.
228
- - Published as a GitHub Release/tarball and to npm (`latest`). macOS has no real-device verification for this patch and the ZCode profile remains `research`.
229
-
230
- See [release notes](docs/release-v0.3.4.en.md) and [validation evidence](docs/zcode-issue-8-10-validation.en.md).
231
-
232
- ## [0.3.3] — 2026-09-12
233
-
234
- Fixes issues #4 / #7 by adapting the ZCode GUI driver to the 3.11.2 model-menu and project-binding semantics, while making acceptance fail closed for zero-test and zero-change outcomes.
235
-
236
- ### Fixed
237
-
238
- - ZCode provider selectors now support both `group-provider` and the 3.11.2 `group-family` prefix. Model selection tries the visible model first and only expands a provider/family group as a fallback; failures include visible text and `data-testid` candidates.
239
- - New-project import dismisses the stale workspace menu before opening Add Project and uses a bounded three-round dismiss/click/verify loop, preventing the first click from being consumed as an outside click.
240
- - Project binding prioritizes the composer menu's `menuitemcheckbox`; the legacy sidebar item remains a compatibility fallback. Display-name matching normalizes NFKC, whitespace, and case.
241
- - Binding read-back combines the composer trigger text with the full-path fast path, rejects known unbound placeholders, and retries the idempotent bind operation for up to two rounds.
242
- - Built-in ZCode and TraeWork discovery paths use `{PROGRAMFILES}` / `{PROGRAMFILES(X86)}`. Environment placeholders in custom profiles are expanded case-insensitively while unknown placeholders remain unchanged.
243
- - A mandatory test check is failed when it exits with code 0 but its output reports zero executed tests.
244
- - Git projects now require a change relative to the pre-work baseline by default. Pure question/analysis tasks can explicitly opt out with `"requireChanges": false` in `.tianshu-mcp/acceptance.json`.
245
-
246
- ### Tests
247
-
248
- - Regression coverage now models ZCode 3.11.2 flat family layouts, legacy provider fallback, testid diagnostics, swallowed project clicks, composer binding and read-back retries, plus zero-test/zero-change acceptance gates.
249
-
250
- ---
251
-
252
- ## [0.3.2] — 2026-09-12
253
-
254
- Fixes for issues #5 / #6: **the MCP task model was disconnected from the state of the turn inside
255
- the Codex GUI**. The former is the completion-detection deadlock that kept reporting `running`
256
- while Codex waited for user confirmation; the latter is `cancel_task` only aborting the MCP-side
257
- wait loop, never stopping the in-GUI run, with a misleading description. Both share the same root
258
- cause and are resolved together.
259
-
260
- ### Fixed
261
-
262
- - **Waiting-for-user detection (issue #5)**:
263
- - `judgeCodexPoll` gains a stall fallback: while the stop button stays visible and the
264
- conversation hash is unchanged for `gui.stallTimeoutMs` (default 5 minutes), the task
265
- transitions to `needs_user` (`needsUserKind=user_confirmation`) instead of deadlocking in
266
- `running` until the overall timeout; the stall timer resets as soon as content changes again.
267
- - New configurable UI detection `gui.selectors.userGate` (e.g. the embedded-checkout page or
268
- approval cards): when configured and matched, transitions to `needs_user` immediately.
269
- Unset by default (disabled) — no unverified selectors are built in.
270
- - Tightened the `stopButton` selector: removed the `aria-label*="取消"` over-match (the Cancel
271
- button on waiting-for-user screens used to be mistaken for a running signal).
272
- - **Recovery path (issue #5 fallout)**: `continue_task` now supports codex —
273
- - `user_confirmation`: after the user completes the action in the Codex window, resume by
274
- re-attaching as an observer of the in-GUI run (no message is sent); if the turn already
275
- finished before resuming, the task is still judged `succeeded` correctly;
276
- - `login_required`: after login, re-checks the environment and re-dispatches the task brief
277
- (fresh session + project binding + full initial prompt);
278
- - zcode recovery behaviour is unchanged; other agents are rejected explicitly.
279
- - **Cancel actually stops the GUI (issue #6)**:
280
- - `cancel_task` no longer succeeds on request alone for GUI agents: it first best-effort clicks
281
- the in-app stop button over CDP, then waits (bounded by `gui.cancelWaitMs`, default 15s) for
282
- the GUI to become idle before settling `cancelled`; if the stop could not be confirmed the
283
- terminal message states "GUI 内运行未确认停止…" (the in-GUI run may still be going);
284
- - process-tree termination for CLI agents is unchanged;
285
- - cancelling from `needs_user` now notes that a pending session may remain in the GUI
286
- (no CDP connection exists at that point — documented limitation).
287
- - **Re-dispatch anti-overlap guard (issue #6 chain risk)**: when dispatching, if the managed
288
- instance still has an unstopped run, MCP first tries to stop it; if it cannot, the dispatch
289
- fails hard with `instance_busy`, preventing old and new turns from overlapping inside the same
290
- app (observed in the wild when re-dispatching right after a cancel).
291
- - The startup log no longer hardcodes the tool count as `8`; it reports the actual registry size
292
- (`TOOL_DEFS.length`, currently 9).
293
-
294
- ### Changed
295
-
296
- - Tool descriptions match actual semantics: `cancel_task` distinguishes CLI (kill process tree)
297
- from GUI (best-effort stop click + bounded wait); `continue_task` no longer claims to be
298
- ZCode-only.
299
- - `GuiProfile` gains two configurable options, `stallTimeoutMs` (default 300000) and
300
- `cancelWaitMs` (default 15000), both overridable via agent-profiles.json.
301
- - Skill docs (SKILL.md §4/§5, usage-examples.md §7) document the codex `user_confirmation` /
302
- `login_required` recovery flows, GUI cancel semantics and the new options.
303
-
304
- ---
305
-
306
- ## [0.3.1] — 2026-09-12
307
-
308
- Post-v0.3.0 housekeeping for docs and release automation: **no source-level behavior changes**.
309
- The focus is a full rewrite of the self-installed skill docs plus GitHub/Gitee release-body
310
- composition and link fixes.
311
-
312
- ### Changed
313
-
314
- - **Skill docs (`skills/tianshu-mcp/`) fully rewritten to match the actual v0.3.0 tool surface**:
315
- - Corrected the `codex` description from "headless CLI" to the ChatGPT desktop GUI adapter
316
- (MSIX + COM activation + CDP); documents the required `model`, optional `reasoningLevel` /
317
- `planDoc` / `designSystem`, and that `mode` is not supported;
318
- - Documented the `run_task` `context` parameter and the send-time validation of path references
319
- inside task/context; corrected the `autoFixRounds` default precedence
320
- (call argument > codex 5 / zcode 2 > server default 0);
321
- - Added usage for `list_tasks`, `query_task(tailLines)`, `get_task_report(round)` and
322
- `verify_task` (`extraChecks` / `checksMode` / `baselineRef`) plus the four-level acceptance
323
- command precedence;
324
- - Documented the four `needs_user` kinds and meta fields such as `needsUserKind` /
325
- `pendingQuestion` / `errorType` / `reportRound` / `verificationSource`;
326
- - Added `continue_task` to the approval list; replaced emoji status markers with plain text
327
- (PASS / warning) in the usage examples.
328
- - **Release automation fixes (exposed by the v0.3.0 tag)**:
329
- - The release body is now composed bilingually from `docs/release-v<version>.md` and `.en.md`,
330
- with in-document relative links rewritten to tag-absolute links; a missing doc fails the
331
- workflow loudly instead of producing a shell-only body;
332
- - `Full Changelog` resolves the previous tag via `git describe` into a `compare/<prev>...<tag>`
333
- link instead of degrading to a commits link;
334
- - The body's `CI` link resolves the CI run for the same SHA instead of pointing at the Release run;
335
- - Gitee releases are automated in `release.yml`: `scripts/gitee-release.mjs` idempotently
336
- creates/updates the mirrored release (requires the `GITEE_TOKEN` secret; skipped loudly when unset).
337
- - `.gitignore` now ignores npm pack artifacts and local temporary verification directories.
338
- - Added the missing `[0.1.10]` / `[0.2.0]` / `[0.3.0]` / `[0.3.1]` compare links at the bottom of
339
- this file and its Chinese counterpart.
340
-
341
- ---
342
-
343
- ## [0.3.0] — 2026-09-12
344
-
345
- The Codex desktop app now runs through a **GUI driver**: a new `codex-gui` adapter uses MSIX COM activation
346
- plus CDP to drive the ChatGPT desktop app through the full loop (locate install → launch GUI → bind/create
347
- project → pick model and reasoning level → send instructions → run detection → verify → auto-repair).
348
-
349
- ### BREAKING CHANGES
350
-
351
- - **`agentId=codex` now executes via the desktop GUI instead of the headless CLI**: a new `driver=gui` +
352
- `adapter=codex-gui` + `activation=msix-com`, with the previous **`codex exec` headless path removed**.
353
- After upgrading, `run_task(agentId="codex")` launches and drives the Codex desktop window rather than a
354
- headless child process. To keep headless execution, add a separate `driver=spawn` profile
355
- (`argsTemplate: ["exec", "<prompt:arg>", "--skip-git-repo-check", "--sandbox", "workspace-write"]`) as
356
- documented in `docs/agent-profiles.en.md`.
357
- - This path requires the Codex desktop app (MSIX store package) to be installed; CLI-only environments are
358
- no longer directly supported.
359
-
360
- ### Added
361
-
362
- - `codex-gui` adapter (`src/agents/codex/**`): Appx-first install discovery (scan fallback taking the newest
363
- version), MSIX COM activation with a dedicated `user-data-dir` and dynamic debug port, plus CDP attach and
364
- target convergence (excluding the overlay secondary window).
365
- - Task parameters: `reasoningLevel` (low/medium/high, bilingual), `planDoc`, `designSystem`.
366
- - Model and reasoning level: models are `menuitemradio` candidates while **reasoning strength is a slider**
367
- (0–4: 轻度/中/高/极高/极高), set precisely with arrow keys and read back for verification; level
368
- comparison is exact to avoid matching "高" against "极高".
369
- - **Automatic project registration**: a target directory not yet registered on the Codex side is written
370
- directly into Codex project state (idempotent, backup-before-write, atomic write, only while the
371
- MCP-managed instance is stopped), so it takes the stable bound-project path instead of the brittle native
372
- folder dialog; on failure it falls back to UI creation.
373
- - Verification and repair: reuses the existing AcceptanceEngine (defaults derived from `package.json`, with
374
- weak-verification labelling); on failure the MCP generates an in-project
375
- `.zcode/plans/codex-fix-r<N>.md` (one per round, never overwritten) and cites it in the repair instruction,
376
- up to 5 rounds by default (`defaultAutoFixRounds`).
377
- - Run detection: the stop button is the authoritative running signal, and text stability counts as completion
378
- evidence only after it; without a running signal it fails open to `idle_timeout` while keeping the instance
379
- (never a false completion).
380
- - `scripts/probe-codex.mjs` hardware diagnostic script; 67 Codex unit tests plus integration coverage of the
381
- verify-fail → generated plan → repair-pass loop.
382
- - Docs: `docs/codex-gui-cdp.en.md`, `docs/codex-windows-smoke.en.md` (including the round-2 real business task
383
- acceptance) and their Chinese counterparts.
384
-
385
- ### Changed
386
-
387
- - `GuiProfile` gains `activation` / `userDataDir` / `appxPackageName` / `permissionMode` / `fixPlanDir`;
388
- existing `spawn` profiles are unaffected.
389
- - `ExecutableDiscovery` gains `appxPackageName` / `installRelativeExe` / `scanRoots` / `scanPattern`.
390
-
391
- ### Fixed (exposed by hardware testing)
392
-
393
- - The model trigger mis-matched the sibling permission chip (4 chips share `aria-haspopup`; only the model chip
394
- lacks `aria-label`).
395
- - Reasoning strength was clicked like a menu item and could never be set (it is actually a slider).
396
- - Menus/popovers only open on **trusted** mouse events (DOM `.click()` is ignored).
397
- - A transient empty model read during toolbar re-render after binding was treated as a "model mismatch".
398
- - Model/reasoning trigger selectors now exclude the top menu bar and the mode switcher.
399
- - Cold-start readiness budget widened to 150s (registration stops the instance first; cold start measured ~85s).
400
- - CI: fixed a `normalizeDir` assertion that depended on the host platform, which failed on ubuntu/macos.
401
- - Fixed integration tests polluting real Codex project state by not injecting `ensureRegistered`.
402
-
403
- ### Verification
404
-
405
- - Windows 10 x64 hardware: full loop for a registered project, and the verify-fail → generated plan →
406
- repair-pass loop; an unregistered project completed the full loop after automatic registration.
407
- - Real business task: drove Codex to build a "Fruit Ninja" mini-game in HTML+CSS+JS (`GPT-5.6 Sol` with
408
- reasoning strength "高"); the artifacts passed acceptance and were verified playable in a headless browser
409
- (score rises, lives decrement, Game Over and restart work, no JS exceptions).
410
- - macOS unverified: the built-in Codex GUI status is `research` and is excluded from readiness.
411
-
412
- ---
413
-
414
- ## [0.2.0] — 2026-09-11
415
-
416
- ### Added
417
-
418
- - Dedicated `zcode-gui` Electron CDP adapter with data-driven Windows/macOS discovery, dynamic ports, product/process checks, and a global serial lock.
419
- - Exact ZCode project binding, guarded native folder pickers, `provider/model`, Full Access read-back, and idempotent sending.
420
- - Paused `needs_user` state and approval-gated `continue_task` for original-session answers and environment rechecks after instance, login, or permission handling.
421
- - Multi-signal liveness, progress events, UI preservation, default auto-verification, and two same-session repair rounds. Repair plans stay in MCP task storage.
422
- - `scripts/probe-zcode.mjs`, fake-CDP/state/path/model tests, and bilingual documentation.
423
-
424
- ### Safety and compatibility
425
-
426
- - GUI profiles support an explicit `adapter`; legacy `driver="gui"` profiles retain TraeWork behavior.
427
- - The built-in ZCode profile remains `research` until both real platform loops pass.
428
- - No private `app-server`, credential access, automatic user-instance termination, or fixed screen coordinates.
429
-
430
- ### Fixed and verified
431
-
432
- - Fixed ZCode read-back for dynamic model labels, transient renderer load/reload, delayed new-session registration, and stale session-ID contamination.
433
- - `AskUserQuestion` continuation now selects and submits an exact accessible option in the original session; zero or ambiguous matches fail closed.
434
- - Windows 10 x64 passed three hardware loops: real file development, same-session repair after a controlled failure, and `continue_task` after a model question. macOS hardware evidence remains pending.
435
-
436
- ---
437
-
438
- ## [0.1.10] — 2026-09-10
439
-
440
- ### Fixed
441
-
442
- - **Fixed stdio log pollution (issue #1)**: the unified logger previously sent only ERROR to
443
- `console.error` while INFO/WARN/DEBUG went to `console.log`, sharing stdout with MCP JSON-RPC
444
- messages and breaking handshakes or tool calls in strict stdio clients. All levels passing the
445
- threshold now go to stderr, leaving stdout for valid MCP messages only.
446
- - Log file appending, timestamps, level tags and the `<data dir>/logs/server.log` path are unchanged;
447
- a startup failure is still reported on stderr.
448
-
449
- ### Added
450
-
451
- - New `scripts/check-stdio.mjs` strict stdio smoke: a real child process validates the complete
452
- stdout/stderr byte stream, allowing only newline-delimited, schema-valid MCP JSON-RPC messages on
453
- stdout; empty lines, non-JSON lines, parser errors, or trailing fragments at exit fail the run.
454
- It covers six scenarios: first start, second start with matching skills, `--no-skill-install`,
455
- a corrupt `config.json`, logs during a stub task, and clean EOF shutdown.
456
- - New `npm run check:stdio` and `npm run check:stdio:src` scripts.
457
-
458
- ### Tests
459
-
460
- - New `test/unit/log.test.ts`: real-child-process checks for the four log levels' channels, default
461
- INFO filtering, threshold-filtered file logging, and UTF-8 content (4/6 failed before the fix; see
462
- `docs/m2-evidence/issue1-old-impl-log-test-failure.txt`).
463
- - CI's three-platform matrix now includes Node 24; the build step runs the strict stdio check instead
464
- of an EOF-exit-only smoke.
465
- - CI `pack-check` and Release install the freshly built tarball into a clean consumer directory, read
466
- the installed bin dynamically, and reuse the same strict stdio check; Release adds `lint` and the
467
- installed-package protocol gate, failing before a draft is created.
468
- - ESLint enables `no-console` (allowing `error` only) for `src/**/*.ts` to prevent new direct stdout writes.
469
-
470
- ---
471
-
472
- ## [0.1.9] — 2026-09-09
473
-
474
- ### Fixed
475
-
476
- - Fixed premature TraeWork completion while the model was still thinking but the DOM stayed unchanged for about 36 seconds.
477
- The stop button and loading task tail are now authoritative running signals and override completion marks; stable rounds now
478
- start an idle timer, which defaults to ten minutes before returning `idle`.
479
- - Fixed permanently pending `Runtime.evaluate` calls after a CDP WebSocket disconnect. Close/error rejects all pending requests,
480
- each CDP command has a 15-second default timeout, and task cancellation is observed within about one second.
481
- - Only `completion_mark` / `ask_user` release an instance launched by this module. Idle, timeout, cancellation, and CDP loss retain
482
- it, with `agentEndReason` / `keptInstance` exposed in task metadata.
483
- - Fixed a shutdown race where an orchestrator still collecting its baseline could remain `queued` and be mislabeled as a user
484
- cancellation. User cancellation is now determined only from structured cancellation intent.
485
-
486
- ### Added
487
-
488
- - Polling emits a progress event visible through `query_task` every 30 seconds by default.
489
- - Added `gui.idleTimeoutMs`, `gui.cdpSendTimeoutMs`, `gui.progressIntervalMs`, and five overrideable liveness selectors.
490
-
491
- ### Testing
492
-
493
- - Added liveness truth-table, CDP timeout/disconnect convergence, selector-expression, and fake-CDP instance-retention regressions.
494
- - Windows/macOS/Linux × Node 20/22 and tarball gates remain covered.
495
-
496
- ---
497
-
498
- ## [0.1.8] — 2026-09-08
499
-
500
- ### Fixed
501
-
502
- - **Atomic-write concurrency defect** (the real cause of intermittent CI failures): the temp filename in
503
- `writeJsonAtomic`/`writeTextAtomic` was `<target>.<pid>.tmp`, so concurrent writes to the same target in one
504
- process shared one temp file - the first to finish renames it away and the next throws `ENOENT`; on Windows a
505
- concurrent rename can also throw `EPERM`. Symptom: `rework_task` intermittently returned an `undefined` meta
506
- (hit on CI windows/Node 20). Fixed by a random temp suffix plus backoff-retry on transient rename errors.
507
-
508
- ### Testing
509
-
510
- - New `test/unit/atomic-write.test.ts` (3 cases: concurrent JSON/text writes all succeed, no leftover temp files).
511
-
512
- ---
513
-
514
- ## [0.1.7] — 2026-09-08
515
-
516
- ### Fixed
517
-
518
- - **Project-folder binding still failed** (v0.1.6 did not fully resolve it; field report: the native dialog
519
- appeared but the edit box was empty and confirm was clicked anyway):
520
- - **Root cause**: the MCP passes a `normPath()`-normalized path (lowercase drive + forward slashes, e.g.
521
- `d:/Trae项目/AI游戏/象棋`), which the **native Windows picker rejects** — measured: read-back matched, yet the dialog
522
- stayed open after confirm. Fix: convert via the new `toNativeWindowsPath()` to `D:\a\b`.
523
- - `WM_GETTEXT` **read-back verification** after writing; on mismatch re-locate and retry (up to 3 times);
524
- if it still mismatches, **never click confirm** and fail loudly.
525
- - The hwnd detected after the footer click is **passed into the write script**; after clicking, success
526
- requires that hwnd to be gone.
527
- - **Auto-close stale dialogs** (left over from a previous failure) before binding.
528
- - Confirm button now also requires its rect to be in the lower half of the dialog.
529
- - The dialog script's full trace (HWND/READBACK) is written to the task log.
530
-
531
- ### Testing
532
-
533
- - Total tests **172 → 181** (unit incl. path normalization and atomic-write concurrency; integration incl. stale-dialog cleanup).
534
- - Machine-verified: a new Chinese project `D:\Trae项目\AI游戏\象棋` (absent from the dropdown)
535
- passed end-to-end through the native dialog; `五子棋` and the ASCII project `ts-bind-test` regressed green.
536
-
537
- ---
538
-
539
- ## [0.1.6] — 2026-09-08
540
-
541
- ### Fixed
542
-
543
- - **Project-folder binding got stuck / reported "waiting for native dialog timed out"** (field report; the adapter was not broken):
544
- - `clickDropdownFooter` used to trust `element.click()`'s return value, but the native popup may never
545
- appear → it now **confirms the dialog actually appeared**, otherwise it logs a dropdown DOM snapshot and fails loudly.
546
- - Dialog detection polled from Node every 800 ms while PowerShell cold start is ~4.5–6 s, so a 15 s budget
547
- allowed only ~2 probes → now it polls **inside a single PowerShell call** (400 ms interval) with a 30 s budget.
548
- - **CJK paths were corrupted** (measured: `D:\Trae项目\ts-bind-test` became `D:Traes-bind-test`):
549
- SendKeys/clipboard are mangled by the console code page → the path is now written via Win32
550
- **`WM_SETTEXT`**, which is fully reliable for CJK.
551
- - **The confirm click hit a file-list row**: `AutomationId="1"` is not unique (rows also use 0/1/2…) →
552
- now located by **AutomationId=1 AND ControlType=Pane**, then clicked by bounding rect.
553
- - PowerShell output was garbled for Chinese → the script now emits **ASCII-only** and Node maps it back
554
- via `localizeDialogMessage()`.
555
-
556
- ### Added
557
-
558
- - **Non-Work binding fallback**: when binding fails in Code/Design, the driver **falls back to Work once**,
559
- switches back to the target mode, and re-verifies the project is still bound; only if both attempts fail
560
- does it report an error including the reason from each mode.
561
- - Machine-verified: for a project **absent from the dropdown** (`D:\Trae项目\ts-bind-test`),
562
- `run_task(agentId=traework, mode=Code)` passed end-to-end — native dialog wrote the path → confirm clicked →
563
- project entered TraeWork's list (`solo-lite.local-project-folders` 22→23) → task sent → auto-verification `succeeded`.
564
-
565
- ### Changed
566
-
567
- - `docs/traework-cdp.md` / `.en.md`: 7 new pitfall entries; added the "dropdown entries ≠ project map" fact and the fallback note.
568
-
569
- ### Testing
570
-
571
- - Total tests **167 → 172** (new dialog message-mapping/platform-branch unit tests + Code→Work fallback integration test).
572
-
573
- ---
574
-
575
- ## [0.1.5] — 2026-09-08
576
-
577
- ### Added
578
-
579
- - **TraeWork panel mode switching**: `run_task` gained a `mode` parameter supporting `Work` / `Code` / `Design`.
580
- - Resolution order: explicit `mode` parameter > task-text detection > keep `Work`.
581
- - Text detection handles mixed Chinese/English phrasing ("switch to Code mode", "use design mode", "工作模式", "代码模式", "设计模式", …).
582
- - New `gui.modeSwitch` profile switch (default `true`).
583
- - New pure functions `detectModeFromText` / `resolveMode` (unit-tested).
584
- - **Dedicated SVG assets**: `assets/tianshu-mcp-icon.svg` (app icon), `assets/tianshu-mcp-banner.svg` (wide banner).
585
- - New `scripts/probe-traework.mjs mode <Work|Code|Design>` subcommand (real-machine diagnostics/verification).
586
- - New bilingual release notes `docs/release-v0.1.5.md` / `.en.md`.
587
-
588
- ### Changed
589
-
590
- - **TraeWork execution order**: measurement showed the three modes **each keep an independent project binding** —
591
- switching modes replaces the input bar's project with whatever that mode last used.
592
- Order is now: ensure instance → wait for UI → new session → switch to target mode → bind project inside that mode → switch model → send.
593
- - After binding, both mode and project are re-verified; any mismatch **fails loudly** (never silently develops in the wrong mode).
594
- - meta block now exposes `model` / `mode` for Tianshu to read back.
595
- - `package.json`: `license` changed from `MIT` to `Apache-2.0` (matching the repository `LICENSE` file);
596
- added `repository` / `homepage` / `bugs`; `files` now includes `assets`.
597
- - README.md / README.en.md fully rewritten: stack badges, SVG banner (above the icon), language isolation
598
- (the Chinese README references Chinese docs only; the English README references English docs only).
599
-
600
- ### Fixed
601
-
602
- - **Rework feedback race** (pre-existing; intermittent under load): the terminal snapshot is written first, so a caller's
603
- immediate `rework_task(feedback)` could be erased by the previous run's `delete meta.reworkFeedback`, leaving the rework
604
- round without feedback. Now the feedback is consumed and cleared atomically when `startTask` begins.
605
- Added regression test `test/integration/rework-feedback-race.test.ts`.
606
- - **`projectBasename` cross-platform**: it used `path.basename` (which does not split backslashes on POSIX), failing
607
- Linux/macOS CI; now it splits explicitly on both `\` and `/`.
608
-
609
- ### Testing
610
-
611
- - Total tests **153 → 167** (14 new mode-related cases).
612
- - Real-machine end-to-end: `mode=Work` / `mode=Code` / `mode=Design` all completed
613
- "switch mode → bind project → send → create file → auto-verification passed".
614
-
615
- ---
616
-
617
- ## [0.1.4] — 2026-09-08
618
-
619
- ### Added
620
-
621
- - TraeWork GUI driver over CDP: `traework` moved from `unsupported` to `driver=gui` / `status=ready`.
622
- - Capabilities: launch/reuse instance → new session → bind project folder (dropdown first, restricted computer-use
623
- native dialog as fallback) → optional model selection → read-back-verified send → poll to completion →
624
- auto-verify → repair-plan file + same-session rework on failure.
625
- - Safety: reuse the user's instance by default, never kill a process tree, verify the command line before terminating;
626
- computer-use is limited to TraeWork's folder picker.
627
- - `AgentAdapter` gained an optional `run()` execution surface; the orchestrator branches on `adapter.run`
628
- (CLI agents still use spawn).
629
- - Profile gained `driver` (`spawn` / `gui`) and a `gui` section; `run_task` gained a `model` parameter.
630
- - New `src/agents/traework/**` (CDP client, selector table, launcher, session/input/model/reply modules, restricted computer-use).
631
- - On verification failure a repair-plan file `rework-<taskId>-r<N>.md` is generated (task dir + project `.tianshu-mcp`)
632
- and its filename is referenced in the rework message.
633
-
634
- ### Changed
635
-
636
- - `docs/adapter-matrix.md` T1 conclusion corrected from `unsupported` to "integrated (driver=gui)".
637
- - formatter now passes cancel-source fields (`abortSource`, …) through to `query_task`'s meta block.
638
-
639
- ### Fixed
640
-
641
- - Unified timeout terminal state: normal timeouts now also land `failed(timeout)` plus exactly one `timeout_killed` event, in fixed order.
642
- - Stabilized the `shutdown` test polling.
643
-
644
- ### Testing
645
-
646
- - Total tests **72 → 153** (new TraeWork unit/integration cases).
647
- - Real-machine end-to-end: `run_task(agentId=traework, model=GLM-5.3, autoVerify=true)` drove TraeWork to create a file and passed acceptance.
648
-
649
- ---
650
-
651
- ## [0.1.3] — 2026-09-08
652
-
653
- ### Fixed
654
-
655
- - **S1** No-reason cancel was mis-recorded as `interrupted`: added independent `cancelRequestedAt` / `abortSource` fields;
656
- cancel intent no longer depends on the optional `reason` (5 regression tests).
657
- - **S2** Unified timeout terminal state (shared with 0.1.4).
658
- - **S3** Tracked pre-dirty net-diff attribution: pre-existing dirty files are excluded by content hash when unchanged;
659
- unchanged staged/unstaged files are no longer reported as agent changes (4 regressions).
660
- - **S4** `verify_task(taskId)` persists real-task metadata (`reportRound` / `verificationSource` /
661
- `latestVerificationVerdict`, keeping `agentId`); single-source MCP version (`sync-version` injection).
662
- - **S5** `projects.json` official Zod schema + last-known-good for `config`/`profiles`/`projects` + content-sha256
663
- hot-reload invalidation (fixed corrupt JSON being treated as missing and reset).
664
-
665
- ### Changed
666
-
667
- - **S6** CI/Release `npm ci` retry corrected (stop on success / 3 attempts / attempt counter);
668
- Vitest v3 upgrade (0 audit vulnerabilities); plain-text status markers (emoji scan test).
669
-
670
- ### Testing
671
-
672
- - Total tests **53 → 72**.
673
-
674
- ---
675
-
676
- ## [0.1.2] — 2026-09-08
677
-
678
- ### Changed
679
-
680
- - Build no longer ships source maps (no `.map`, tarball ≈ 69.9 KB).
681
-
682
- ### Testing
683
-
684
- - Total tests **53**.
685
-
686
- ---
687
-
688
- ## [0.1.1] — 2026-09-07
689
-
690
- ### Added
691
-
692
- - **Release after the R1–R5 fixes**:
693
- - **R1** Cancel/interrupt state persistence (`cancel_requested → cancelled`, `cancelReason`/`finishedAt`/`errorType`
694
- persisted, restart-recoverable, idempotent, bounded shutdown).
695
- - **R2** Call-level `taskTimeoutMs` precedence fix + cross-platform process-tree termination
696
- (POSIX process-group SIGTERM→SIGKILL, Windows `taskkill /T /F`).
697
- - **R3** Git baseline participates in diff (boundary at `baseline.head`; agent commits do not lose changes;
698
- dirty-worktree hash attribution).
699
- - **R4** Verification tool parameters and report-round semantics (`round=0` valid, manual verify does not overwrite
700
- reports, `extraChecks` append + `checksMode=replace`, `optional` does not affect verdict, `baselineRef` validated).
701
- - **R5** Removed hardcoded agent paths (`{LOCALAPPDATA}` placeholders + platform-standard candidates);
702
- mtime hot reload for `config`/`profile`/`projects`.
703
- - **R6** Cross-platform CI matrix (Windows/macOS/Linux × Node 20/22) and Release version consistency
704
- (tag/input = `package.json` = tarball), plus tarball content checks.
705
- - **R7** npm published `tianshu-mcp@0.1.1` + `npx -y` raise with 8 tools connected.
706
- - **R8** Bilingual docs synced (including 4 English topic docs).
707
-
708
- ---
709
-
710
- ## [0.1.0] — 2026-09-07
711
-
712
- ### Added
713
-
714
- - First usable release: **M1 core engine + stub-agent end-to-end**.
715
- - 8 MCP tools: `run_task` / `query_task` / `list_tasks` / `get_task_report` / `cancel_task` / `verify_task` /
716
- `rework_task` / `get_profiles`.
717
- - `TaskManager` state machine / per-project serial queue / global concurrency gate / cancel (kill tree) / event-stream persistence.
718
- - Acceptance engine: git baseline & diff, default check-set derivation, command runner, code analysis,
719
- `report.md` / `report.json`.
720
- - fix-loop auto rework + `needs_attention`; skill self-install.
721
- - Stub-agent 3 playbooks (good / fix-on-first / never) integration tests + protocol tests — **53/53 green**.
722
-
723
- ---
724
-
725
- [Unreleased]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.4.1...HEAD
726
- [0.4.1]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.4.0...v0.4.1
727
- [0.4.0]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.4...v0.4.0
728
- [0.3.4]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.3...v0.3.4
729
- [0.3.3]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.2...v0.3.3
730
- [0.3.2]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.1...v0.3.2
731
- [0.3.1]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.0...v0.3.1
732
- [0.3.0]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.2.0...v0.3.0
733
- [0.2.0]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.10...v0.2.0
734
- [0.1.10]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.9...v0.1.10
735
- [0.1.9]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.8...v0.1.9
736
- [0.1.8]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.7...v0.1.8
737
- [0.1.7]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.6...v0.1.7
738
- [0.1.6]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.5...v0.1.6
739
- [0.1.5]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.4...v0.1.5
740
- [0.1.4]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.3...v0.1.4
741
- [0.1.3]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.2...v0.1.3
742
- [0.1.2]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.1...v0.1.2
743
- [0.1.1]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.0...v0.1.1
744
- [0.1.0]: https://github.com/lanlan0811/tianshu-mcp/releases/tag/v0.1.0
1
+ # Changelog
2
+
3
+ All notable changes to `tianshu-mcp` are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ Chinese version: [CHANGELOG.md](CHANGELOG.md)
8
+
9
+ ---
10
+
11
+ ## [Unreleased]
12
+
13
+ ### Planned
14
+
15
+ - More external AI-Agent adapters (a new agent = one profile + an optional adapter file).
16
+ - TraeWork executable discovery and native-dialog driving on macOS (currently fail-closed).
17
+ - Optional project-level skill seeding (by default nothing is written into target repos).
18
+ - Cancel/rework/new-project matrices for the Codex and ZCode GUI drivers on macOS (both remain `research` on darwin).
19
+ - Best-effort stop of a GUI-side pending session (via a temporary CDP connection) when cancelling
20
+ a task in the `needs_user` state.
21
+ - Real-machine verification of project-less dispatch on macOS (this round covers Windows 10 only).
22
+ - ZCode's **automatic import of an unregistered project** cannot complete on Windows: the native-panel script relies on `SetForegroundWindow` to bring the dialog forward before activating its address bar, but a child process of a background MCP server is refused by Windows, so the address-bar Edit never appears and the script spins until its deadline (measured: 56s, then classified by `budget.check()` as an exhausted setup budget). PowerShell's stdout is also block-buffered through a pipe, so killing the process loses the buffer and not a single `native:` stage reaches the log, misdirecting diagnosis. Workaround: add the target directory to the ZCode project list manually first; the fix direction is to grab the foreground with `AttachThreadInput` inside the script, or to use a supported ZCode registration entry point.
23
+ - Cross-round verdict-flip circuit breaking for AI content validation (this round covers it with caching plus sampling; reconsider if hardware data still shows churn), cross-task cache sharing, and reference-image/design-diff comparison.
24
+
25
+ ---
26
+
27
+ ## [0.5.4] — 2026-09-16
28
+
29
+ **Visual acceptance phase 2: AI visual content validation (issue #13)** — alongside the existing objective pixel/spec checks, a new **optional, off-by-default** content-check dimension that validates whether the content of an image or page screenshot matches an expectation you declare explicitly. Judgement is fully delegated to a local command you supply (the MCP never reads, stores, or forwards credentials), it warns only by default, and it debounces with majority sampling plus a task-level cache. See the [v0.5.4 release notes](docs/release-v0.5.4.en.md).
30
+
31
+ ### Added
32
+
33
+ - **Content-check configuration surface**: `visual.content` (global command and budget), `visual.contents[]` (image content rules), `pages[].content` (page semantics), and `pages[].pixel` (defaults to `true`; `false` means a semantic-only page that is exempt from the baseline requirement and pixel comparison but must declare `content`). Everything is off by default and requires an explicit opt-in; declaring rules without enabling them, a missing effective command/template, an unknown placeholder, a byte-egress placeholder without the `allowRemote` opt-in, `samples × timeoutMs` exceeding `limits.roundTimeoutMs`, and derived-id collisions are all rejected at the schema layer.
34
+ - **Command contract**: a placeholder template (`<image:path>` / `<expect:file>` / `<image:base64:file>`) plus strict JSON on the last stdout line (`{passed, confidence?, reason}`). The expectation travels through a temporary file, avoiding command-line escaping and length limits and keeping it out of the process command line and system audit logs; temporary files are deleted in `finally` after each sample. Per rule you may override `command`/`argsTemplate`/`cwd`/`env`/`samples`/`allowRemote`.
35
+ - **Judgement debouncing**: serial sampling within an item plus a majority vote (split votes yield `uncertain`) and an optional confidence gate (`minConfidence`); a task-level input-hash cache whose key covers the image digest, expectation, command string, the **command's absolute path and binary digest**, argument template, cwd, environment-value digest (no plaintext), `allowRemote`, `samples`, and `minConfidence`. Upgrading your CLI invalidates it automatically; when the command's identity cannot be computed reliably nothing is cached; only completed judgements are stored.
36
+ - **Results and reports**: `VisualResult.kind` gains `"content"` and `status` gains `"uncertain"`. Content items render the expectation, sample votes, reasons, provider command, and cache hit in both the Markdown report and the offline HTML, and are annotated with "minConfidence did not apply" when the command reports no confidence. The HTML status filter gains an `uncertain` option.
37
+ - **CLI and diagnostics**: `visual content probe <project> [ruleId]` (runs a real judgement for the declared rules without writing evidence or cache) and `visual content cache clear <taskId>`; `visual doctor` gains `content command` (per-rule effective resolution plus the `allowRemote` declaration list, failing that finding when a command cannot resolve) and `content budget` (`rules × samples × timeoutMs` compared against `roundTimeoutMs` with a suggestion, never editing your configuration).
38
+
39
+ ### Fixed
40
+
41
+ - **The repair plan listed `optional:true` failures as "must fix"** (the pre-existing defect issue #13's acceptance criteria require fixing): `repair-plan.ts` filtered only on `skipped`, so warning-only failures were listed under section 2. It now also requires `!c.optional` and adds section 3.2 "warning-only items (no fix required)" listing optional check failures plus `optional:true`/`uncertain` visual items, and section 5 states explicitly that artifacts must not be faked and checks must not be relaxed to silence a warning.
42
+
43
+ ### Security
44
+
45
+ - The "zero credential management" section of [SECURITY.md](SECURITY.md) / [SECURITY.en.md](SECURITY.en.md) now covers the content-check boundary: judgement is delegated to a command you declare and the MCP reads/stores/forwards no credentials; whether images leave the machine depends on that command; and **the MCP's enforcement is contract-level only** (the byte-egress placeholder is disabled without an `allowRemote` opt-in), so it cannot stop a command from sending data out and users must confirm their command's behaviour themselves.
46
+
47
+ ### Tests
48
+
49
+ - **644 passed / 12 skipped** overall (Windows 10 x64, Node 24.18.0), 112 cases more than v0.5.3: positive/negative cases for the 10 schema checks (including the budget-consistency counterexample), an exhaustive `tallyContentVotes` suite, cache-key stability and CLI-upgrade invalidation, placeholder expansion and stdout parsing, whole-round blockers producing no result rows (one each for a global and a rule-level override command), single-item failures staying warning-only and visible, repair-plan isolation, zero-rerun cache hits, probe and cache clearing, doctor content diagnostics, verdict-attribution regressions (`uncertain` and `optional:true` never fail a round; only `blocking:true` does), and the semantic-only page recording an explicit null baseline in the frozen snapshot (unaffected by stray baseline files).
50
+ - The 12 browser-gated cases run **12/12** on Windows 10 under `TIANSHU_VISUAL_BROWSER_TEST=1`, including 2 new ones covering the `pixel:false` semantic-page exemption and "one screenshot yields both a pixel and a content item".
51
+ - Real macOS system evidence was collected by CI: the target commit's `CI` workflow is green across all 22 jobs, 6 of them `visual-browser` jobs covering macOS 15 (Apple Silicon arm64) and macOS 15 Intel (x64) across Node 20/22/24.
52
+ - What is not covered is stated plainly: no measurement against a real third-party vision CLI; and "images never leave the machine" is not verifiable at the system level. See [validation progress](docs/visual-validation.en.md).
53
+
54
+ ### Compatibility
55
+
56
+ - This is a **PATCH** release: the new capability is optional and **off by default**, and existing caller signatures, report fields, and the default behaviour of `pages`/`images` stay **backward compatible**. The one thing consumer code should note is enum growth — `VisualResult.status` gains `"uncertain"` and `kind` gains `"content"` — so anything that exhaustively switches on `status` must handle it.
57
+
58
+ ---
59
+
60
+ ## [0.5.3] — 2026-09-15
61
+
62
+ **ZCode hardware-revisit fixes (issue #12, second round)**: three defects found on hardware are fixed — GUI instances could not outlive the server on Windows, "new task" did not switch pages and everything waited silently, and send-failure attribution was misleading. See the [v0.5.3 release notes](docs/release-v0.5.3.en.md) and the [Windows 10 acceptance record](docs/zcode-issue-12-windows-evidence.en.md).
63
+
64
+ ### Fixed
65
+
66
+ - **ZCode / Codex desktop instances could not outlive the server on Windows (found on hardware)**: the `zcode` and `codex` GUI instances were spawned behind a platform branch (`detached: process.platform !== "win32"`) while `traework` already used an unconditional `detached: true`. A minimal experiment (Windows 10 / Node 24.18.0) on the same spawn shows a non-detached child's survival after the parent exits is 0 and a detached child's is 1. As a result, as soon as the MCP server (or a one-shot smoke / probe script) exited on Windows, ZCode was killed along with it and `keptInstance`'s "instance survives the server exit" was a no-op — `needs_user` told the user to "handle it in ZCode, then call continue_task" while the window was already gone. The invariant now lives in one place, `guiInstanceSpawnOptions()`, shared by all three GUI instances (`codex` even branched `unref()` by platform; that branch is gone). The execution-type children in `verify/runner`, `visual/services` and `agents/spawn` keep their platform branch because their semantics are the opposite — they must be terminable as a group.
67
+ - **"New task" reported success without switching pages, then everything waited silently (found on hardware)**: when ZCode is parked on an existing conversation, the top-bar `conversation-new-task` is a lazily mounted icon — the click is dispatched and returns `true` but the page does not switch, and a conversation page's composer does **not** mount `composer-workspace-trigger`. Both the project-less default confirmation and the project-binding wait therefore idled until their deadline and reported nothing better than `needs_user/setup_recovery` (measured: 30 seconds of dead waiting). The draft is now verified by "the project trigger is mounted" after clicking new-task; when it is not, the flow falls back to the sidebar `task-new-button` (reliable on Windows 3.11.2; that fallback previously existed only on the project branch) and only fails closed with `setup_failed` — reporting "the trigger is still not mounted" — when both entry points fail.
68
+ - **Misleading attribution for send failures (found on hardware)**: when the window is minimised or fully occluded, Chromium throttles the page (`visibilityState=hidden`) and the send button becomes unclickable even though it sits inside the viewport — `elementFromPoint` does not hit the button itself. The old message said only "the ZCode send button was not enabled or was covered within the observation window", pointing users at the button; the driver now recognises that state and reports "the ZCode window is not in the foreground" together with the instruction to bring it forward. `Page.bringToFront` was measured to be **unable** to restore an occluded Electron window, so no automatic recovery is pretended.
69
+
70
+ ### Tests
71
+
72
+ - Full suite: **532 passed / 10 skipped** (Windows 10 x64, Node 24.18.0), a net gain of 7 cases over v0.5.2: falling back to the sidebar entry when no draft is established and still dispatching, failing closed without sending when neither entry point creates a draft, attributing a send failure to "window not in the foreground" when the page is throttled, keeping the original button attribution when the page is visible, plus 2 regression cases for the GUI-instance spawn invariant (unconditional detached + unref across platforms).
73
+
74
+ ### Docs
75
+
76
+ - The [issue #12 Windows 10 acceptance record](docs/zcode-issue-12-windows-evidence.en.md) gains a "second visit (after v0.5.2)" section: results and on-site evidence for 6 hardware runs, the reproduction criteria for the new-task page-switch failure, evidence for each send-stage failure mode, and the facts that were **not** reproduced or **not** verified this round (including that the true cause of the first `send_unknown` is still undetermined and that the new send diagnostic was never reached on hardware).
77
+
78
+ ---
79
+
80
+ ## [0.5.2] — 2026-09-14
81
+
82
+ **Project-less dispatch for ZCode (issue #12)**: `run_task`'s `projectPath` is now optional, letting ZCode run tasks in its `default` workspace; the companion `allowCreateProject` can forbid automatic project import. See the [v0.5.2 release notes](docs/release-v0.5.2.en.md) and the [Windows 10 acceptance record](docs/zcode-issue-12-windows-evidence.en.md).
83
+
84
+ ### Added
85
+
86
+ - **Project-less dispatch for ZCode (issue #12)**: `run_task`'s `projectPath` is now optional. When omitted, ZCode runs the task in its `default` workspace — no directory assigned, no project registered or imported, no Git baseline, no project snapshot freeze, no project lock, no project acceptance. On success the task is marked structurally as `not_applicable: no_project` and the terminal message states "no project acceptance performed". `query_task` / `list_tasks` display such tasks normally; `verify_task` / `get_task_report` return an explicit not-applicable explanation instead of deriving a directory from cwd.
87
+ - **`allowCreateProject` (ZCode-only, optional boolean)**: omitted keeps the existing "auto-import when the target is unregistered" behaviour; explicit `false` stops dispatch **before any import side effect** when the target is unregistered, returning a recognisable `project_not_registered` reason with remediation (no native folder dialog, no project added). Other agents passing this parameter get an explicit "not supported" error rather than a silent ignore.
88
+ - **Windows 10 hardware acceptance record** (`docs/zcode-issue-12-windows-evidence{,.en}.md`): complete evidence for project-less dispatch and `allowCreateProject=false` on ZCode 3.11.2.6792, including the before/after comparison "ZCode project entries 34 → 34, 0 added / 0 removed".
89
+
90
+ ### Fixed
91
+
92
+ - **Divergent project-trigger readiness criteria (issue #12 §5)**: waiting used `exists` (element has width/height only) while clicking went through `pick` (exactly one unclipped visible node in the winning tier), so an `exists=true` / `click=false` window existed. Waiting and clicking now share one **structured probe** that distinguishes not-mounted / mounted-but-invisible-or-clipped / ambiguous / disabled / covered / ready, plus a post-click condition: the project menu must actually open, and `menu-not-open` is classified separately.
93
+ - **Error message contradicting behaviour**: "waiting for the project trigger timed out" is no longer used for early exits (multiple matches, disabled) or a menu that never opened; failure text carries `selector`, match count and minimal hit-node attributes, and diagnostics log attempt count, elapsed time and remaining budget.
94
+ - **Centralised timeout**: new `gui.projectTriggerTimeoutMs` (default 15s) replaces the two hard-coded `15_000` literals; the whole "wait → one sidebar fallback → wait" sequence shares a single deadline, retries do not reset the budget, and it is clamped by the setup-recovery budget and the task deadline.
95
+ - **`projectPath` was never opened up in the MCP schema (found on hardware)**: the handler already had the project-less branch, but `RunTaskParamsSchema.projectPath` was still required, so a real `run_task` was rejected by the SDK with `-32602 Required at projectPath`. Unit tests call the handler directly and therefore bypass `inputSchema`, which is why a green suite missed it. Changed to `AbsPath.optional()`, plus a protocol-level regression case in `test/integration/task-flow.test.ts` asserting neither `-32602` nor `Input validation error` appears.
96
+ - **No "work outside a project" switch, and the menu click was undone by toggle semantics (found on hardware)**: ZCode's "New task" inherits the previous binding, so project-less dispatch parked at `needs_user` forever; meanwhile `clickProjectTriggerAndConfirm` kept clicking the trigger even when the project menu was **already open**, closing the Radix dropdown and then polling until its deadline, misreported as "the project menu did not open". Added the `workOutsideProject` selector and `enterDefaultWorkspace()` for an explicit switch (confirmed by `workspaceBinding` read-back, not by click success), made the click check the menu state first, and made `confirmDefaultWorkspace` return immediately for "definitely bound to a project".
97
+
98
+ ---
99
+
100
+ ## [0.5.1] — 2026-09-14
101
+
102
+ Documentation and validation-evidence completion; **no runtime behaviour changes**. See the [v0.5.1 release notes](docs/release-v0.5.1.en.md) for details.
103
+
104
+ ### Added
105
+
106
+ - `npm run evidence:visual:windows` (`scripts/evidence-visual-windows.mjs`): collects the full Windows 10 local functional matrix (existing/static/command sources, port conflict that blocks without terminating another service, bounded readiness failure that cleans up the child process, local Edge isolated instance and version mismatch, missing-browser blocker), 9/9 passed.
107
+ - `docs/visual-validation-evidence/`: raw machine-readable validation records (Windows 10 matrix JSON and test output, macOS dual-architecture `environment.json`, macOS CI summaries), distributed with the package.
108
+
109
+ ### Fixed
110
+
111
+ - Stale `package-lock.json` root version: the lockfile still said `0.4.1` at the v0.5.0 release while `package.json` said `0.5.0`; both are now synced to `0.5.1`.
112
+
113
+ ### Tests
114
+
115
+ - Two additional real-browser-gated visual cases: screenshots succeed when the project path contains CJK characters and spaces; a main-document 302 redirect to a non-allowlisted origin is blocked by policy and passes once explicitly allowed. Full suite: **486 passed / 10 skipped**.
116
+ - Collected macOS 13+ platform evidence: on macOS 15 hardware runners, Intel x64 and Apple Silicon arm64 (Node 20/22/24) each passed 10 files with 51 cases.
117
+
118
+ ### Docs
119
+
120
+ - **Skill docs (`skills/tianshu-mcp/`) aligned with the code**: `SKILL.md` now lists all 11 tools with capability/approval columns (including `prepare_visual_baseline`/`approve_visual_baseline`), gives visual acceptance its own section (blockers do not trigger repair; `rework_task` re-verifies first; baseline approval and freezing), adds `setup_recovery` and the `errorType` value set to the error table, corrects agent status semantics (`traework` is always `ready`; `codex` is platform-dependent) and notes that `continue_task` only supports codex/zcode. `usage-examples.md` fixes the claim that `get_task_report` carries a meta block, removes the mis-listed `reasoningLevel` from the meta table, distinguishes the auto repair-plan location per agent (codex writes inside the project's `.zcode/plans/`; others write to the task directory), and adds the actual `list_tasks` output columns plus the visual CLI commands.
121
+ - `docs/visual-validation{,.en}.md` rewritten with full platform evidence tables (system, Node, browser version, command, result).
122
+ - Bilingual README and HANDOFF updated against the current code and commit history.
123
+
124
+ ---
125
+
126
+ ## [0.5.0] — 2026-09-14
127
+
128
+ Adds an **optional visual acceptance module** that wires screenshot comparison and static image specification checks into the "develop → verify → repair → re-verify" loop. Projects that do not enable visuals behave compatibly, and legacy reports and task snapshots remain readable. See the [v0.5.0 release notes](docs/release-v0.5.0.en.md) for the full description.
129
+
130
+ ### Added
131
+
132
+ - **Page sources**: mutually exclusive `existing` / `command` / `static`; identical service definitions share one managed instance per round; the static host rejects traversal and out-of-project symlinks; an occupied port blocks instead of reusing or terminating another service.
133
+ - **Screenshots and interaction**: `viewport` / `fullPage` / `element` modes with declarative `click` / `input` / `hover` / `scroll` / `wait` steps; a fixed readiness flow (isolated context, login state, fonts and images, disabled animations, masks, sampling); bounded full-page scrolling to trigger lazy loading.
134
+ - **Stabilization and masks**: up to 3 samples taking two adjacent identical captures; continuously changing pages, exceeded pixel budgets and unstable captures block; an unmatchable mask selector or a fully masked image never passes.
135
+ - **Pixel comparison**: unified PNG; size mismatches fail without scaling; masked regions are excluded from numerator and denominator; pixelmatch antialiasing is excluded by default; connected-component analysis outputs coordinates, areas and an annotated image, keeping at most 100 regions while recording the remaining count and overall bounds.
136
+ - **Static image specifications**: explicit file lists; encoded-format/extension consistency, existence with complete decoding, EXIF-orientation-normalized dimensions, aspect ratio, byte size, optional DPI and real-transparent-pixel detection; unsupported formats are reported explicitly.
137
+ - **Two-phase baselines**: `prepare` produces a candidate (candidate ID, digest, target paths, preview) and `approve` verifies candidate/original-baseline/configuration digests before atomically writing the official baseline and manifest; a missing baseline can only produce a candidate and never a pass; automatic repair never calls the approval entry point.
138
+ - **Rule freezing**: visual configuration and baseline digests are saved before the agent starts and checked around each round; changes require a new snapshot through the dedicated `rules review` / `rules approve` flow.
139
+ - **MCP tools**: new `prepare_visual_baseline` and `approve_visual_baseline`, both side-effecting `write` operations requiring host approval.
140
+ - **CLI**: new `tianshu-mcp visual` subcommand (`init`, `browser install`, `doctor`, `baseline prepare/approve`, `rules review/approve`, `artifacts clean`), dispatched before the stdio connection.
141
+ - **Reports and artifacts**: `VerifyReport` gains an optional `visual` field and `files.html`; the offline HTML supports status filtering, side-by-side images, opacity overlays and region location with only local artifacts, escaped text and no CDN; each round's artifacts live at `<home>/tasks/<taskId>/visual/<round>/` with rounds allocated by a unified task-level lock.
142
+ - **Blockers and recovery**: distinguishes repairable defects, environment blockers and user cancellation; visual blockers enter `needs_attention` with a re-verification-pending marker; `rework_task` re-verifies first for visually blocked tasks and only real defects consume the repair budget; both the generic and Codex-specific repair plans include visual evidence and state that baselines, thresholds and switches must not be modified to bypass failures.
143
+ - **Configuration robustness**: an invalid acceptance configuration blocks explicitly instead of falling back silently; only an explicit `checks: []` disables command checks; `extraChecks` and `checksMode=replace` never override the visual gate; `visual` strictly validates unknown fields, duplicate IDs, empty rules and conflicting options.
144
+ - **Dependencies and runtime**: pinned `puppeteer-core@24.43.1`, `@puppeteer/browsers@2.13.2`, `sharp@0.34.5`, `pixelmatch@7.2.0`; the image library is an optional dynamic dependency whose absence does not prevent startup; browsers are installed explicitly on demand with no download during npm install or MCP startup; the visual module requires Node.js >=20.3 while non-visual features retain >=20.
145
+ - **Docs and gates**: new bilingual visual acceptance guide and validation progress; CI adds a real-browser matrix (ubuntu/windows/macos-intel/macos × Node 20/22/24) plus production-package consumer acceptance; release requires a successful CI for the target commit and blocks when mirror credentials are missing.
146
+
147
+ ### Fixed
148
+
149
+ - The acceptance engine no longer silently falls back to default checks when a project configuration is invalid; it blocks explicitly with a reason.
150
+ - Manual and automatic verification share the task-level lock for report round allocation, preventing concurrency or recovery from overwriting historical evidence.
151
+ - Manual verification now lands a visually blocked task in `needs_attention` instead of misreporting `failed`.
152
+ - `rework_task` allows a visually blocked task that lacks original session location information to re-verify first instead of being rejected outright.
153
+ - The ZCode recovery budget now determines the controlling reason before aborting dependent operations, so the reason is not overwritten by downstream abort listeners.
154
+ - `TaskOrchestrator` distinguishes "cancelled" from "blocked" when a visual integrity problem appears during startup, so cancellation is no longer misrecorded as `needs_attention`.
155
+
156
+ ### Tests
157
+
158
+ - Full suite: **486 passed / 8 skipped** (Windows 10 x64, Node 24.18.0), adding visual configuration, image specification, report, baseline, budget, snapshot, service, real-browser capture, flow and repair cases.
159
+ - The 8 real-browser-gated cases pass separately with `TIANSHU_VISUAL_BROWSER_TEST=1`; the production tarball visual smoke test passes in an isolated consumer.
160
+
161
+ ---
162
+
163
+ ## [0.4.1] — 2026-09-13
164
+
165
+ Documentation release: the orchestration skill docs are aligned with the actual v0.4.0 tool
166
+ surface, and the open-source repos now credit community contributors. No code behaviour changes.
167
+
168
+ ### Docs
169
+
170
+ - **Skill docs fully aligned with the v0.4.0 tool surface** (`skills/tianshu-mcp/`, idempotently synced
171
+ into `~/.rivet/skills/tianshu-mcp/` at server startup):
172
+ - `SKILL.md` now documents the **projectPath safety gate** (absolute path + existing directory +
173
+ realpath canonicalization, rejection of the home directory and system/root directories, dirty-repo
174
+ warning), so an infrastructure rejection is not mistaken for an agent failure.
175
+ - `SKILL.md` adds a **hard-failure error-code reference** (`setup_failed`/`project_ambiguous`/
176
+ `project_mismatch`/`model_unavailable`/`model_mismatch`/`permission_unknown`/`cdp_disconnected`/
177
+ `instance_busy`/`session_lost`/`input_mismatch`/`send_unknown`/`idle_timeout` and more), stating
178
+ that hard failures never enter acceptance or auto-rework.
179
+ - `SKILL.md` covers all `needs_user` kinds, including the new `setup_recovery` (zcode initialization
180
+ recovery exhausted), plus `continue_task` state/type restrictions and the refusal semantics when the
181
+ zcode session anchor is lost.
182
+ - `SKILL.md` documents the `codex-cli` headless path (user-defined `driver=spawn` profile, `model` not
183
+ applicable, CLI ≥0.154.0 requirement), the `ready`/`research` status semantics, **default-parallel 2**
184
+ acceptance checks (`verifyConcurrency`), and the `requireChanges` zero-change gate.
185
+ - `usage-examples.md` adds: a `codex-cli` dispatch example; the **full meta-block field table** (now
186
+ including `agentEndReason`/`lastRunSignal`/`checks`/`round`/`keptInstance`/`zcodeSessionId`/
187
+ `modelProvider`/`permissionMode`/`progressSummary`); an **error-code reference table**; a project-level
188
+ `.tianshu-mcp/acceptance.json` template (with the parallel-interference warning and `requireChanges`
189
+ guidance); a `setup_recovery` recovery example; and the profile whole-key override semantics.
190
+ - **Bilingual README contributor credits**: a new "Contributors" section lists, in order of first
191
+ participation, the community members who took part through Issues and pull requests (avatar + name).
192
+
193
+ ### Other
194
+
195
+ - `package.json` version bumped to `0.4.1` (`serverInfo.version` is synced automatically at build time).
196
+
197
+ ---
198
+
199
+ ## [0.4.0] — 2026-09-13
200
+
201
+ ### Added
202
+
203
+ - `projectPath` safety gate: `run_task`/`verify_task` validate at submission (absolute path +
204
+ existing directory + realpath symlink resolution), reject the home directory itself and
205
+ system/root directories (including macOS `/private/*` realpath forms); the submission receipt
206
+ notes symlink resolution; dirty git repos get an uncommitted-changes coexistence warning.
207
+ - ZCode GUI driver supports macOS: adapts to the main process rewriting its title (relaxed port
208
+ attribution + bounded scan of the configured port range when argv hides the debug port) and
209
+ detached+unref instance persistence; the folder-panel driver is rewritten for the macOS window
210
+ form (NSOpenPanel as a standalone window + AX value write into the go-to field, immune to IME
211
+ interception). Machine-verified closed loop on 2026-09-13 (macOS arm64, ZCode 3.11.2: bind →
212
+ readback → send → run evidence → acceptance PASS → succeeded); macOS stays `research` until
213
+ the cancel/rework/new-project matrix is covered.
214
+ - Codex GUI driver supports macOS: spawns the ChatGPT.app bundle executable directly
215
+ (per-platform `activation` default spawn/msix-com) with detached+unref instance persistence;
216
+ POSIX process enumeration and SIGTERM stop; default discovery dirs on darwin; project
217
+ registration writes the shared state file (`~/.codex/.codex-global-state.json`) on darwin too;
218
+ the observation loop reconnects CDP across transient renderer hangs / target replacement
219
+ (only 5 consecutive failures count as disconnected). Machine-verified closed loop on
220
+ 2026-09-13 (macOS arm64: discover → register → bind → send → run evidence → acceptance PASS
221
+ → succeeded); macOS stays `research` until the cancel/rework matrix is covered.
222
+
223
+ ### Fixed
224
+
225
+ - zcode macOS new-task inert-button fallback: `conversation-new-task` can hit an inert home-screen
226
+ icon (click does nothing); when the project trigger misses, the flow now falls back to the
227
+ sidebar `[data-testid=task-new-button]` and retries.
228
+ - `normalizeProjectPath` resolves symlinks: macOS `/tmp`→`/private/tmp` used to fail project
229
+ path matching and degrade into a name match, falsely reporting `project_ambiguous`;
230
+ falls back to lexical normalization when realpath fails.
231
+ - zcode macOS panel failures no longer misreport `needsPermission`: the execFile message embeds
232
+ the full script text (containing the `ACCESSIBILITY_PERMISSION_REQUIRED` literal), so every
233
+ failure looked like a permission problem — the check now reads the stderr execution-error line.
234
+ - `get_profiles` now lists user-defined profiles from the data-directory `agent-profiles.json`
235
+ (previously hidden until first resolve, even though `run_task` could already use them — inconsistent discovery feedback).
236
+ - zcode-flow test stubs now cover `listDialogs`, removing a flake where real osascript/PowerShell
237
+ calls blew the `taskTimeoutMs` wall-clock budget under full-suite load.
238
+ - CDP `connect()` failure paths now dispose of the WebSocket themselves (no longer relying on
239
+ callers to disconnect); the `send()` timeout timer is unref'd.
240
+ - **Drive roots were not rejected by the `projectPath` gate** (Windows): `normPath` strips the
241
+ trailing slash (`D:\` -> `d:`), which never equals the `d:/` entries in the reject list, so the
242
+ gate was effectively a no-op for drive roots; a dedicated drive-root check now covers every
243
+ drive letter instead of relying on enumeration.
244
+ - `test/unit/project-dir-guard.test.ts` had a non-portable system-directory assertion: `/etc` and
245
+ `/usr` are POSIX paths, and on Windows they hit "directory does not exist" rather than the reject
246
+ list; the assertion is now platform-branched and verifies drive roots plus `C:/Windows` on Windows.
247
+ - `test/unit/acceptance-parallel.test.ts` cancellation case was flaky (green alone, red in a full
248
+ run): a fixed 250ms delay can precede the child spawn on slower platforms, mislabelling an
249
+ in-flight check as `skipped`; it now waits until both in-flight checks have really started.
250
+
251
+ ### Performance
252
+
253
+ - All `execFileSync`/`spawnSync` calls across GUI instance probing, discovery and registration
254
+ are now async; ready-wait loops reuse a per-tick process snapshot with a 1.5s TTL cache —
255
+ eliminating event-loop freezes during Windows polling (up to 30s per call).
256
+ - Acceptance command checks run with bounded parallelism: new `verifyConcurrency` (**⚠ default
257
+ changed from serial to 2**, range 1–4; project-level `.tianshu-mcp/acceptance.json` overrides,
258
+ 1 = fully serial — set 1 explicitly for checks that write build outputs, run with `--fix`, or
259
+ share cache directories); logs are concatenated in declaration order with unchanged format;
260
+ cancellation interrupts both in-flight and pending checks.
261
+ - Git baseline hashing is single-pass with bounded async concurrency (untracked cap 5000);
262
+ code analysis reads each file at most once, sniffing only a prefix of large files.
263
+ - `get_profiles` and task snapshot reads now use `Promise.all`.
264
+ - Test suite 267s → 51s: traework UI-layer sleeps are injectable (production defaults unchanged);
265
+ vitest split into parallel unit / serial integration projects.
266
+ - `tsconfig.build.json` no longer emits declarations — 70 `.d.ts` files dropped (140 → 71 files).
267
+
268
+ ### Documentation
269
+
270
+ - README (both languages) gains "macOS headless path: codex-cli (user profile)" — including the
271
+ revoked-certificate warning for ≤0.130.0 and a complete profile example.
272
+
273
+ ---
274
+
275
+ ## [0.3.4] — 2026-09-13
276
+
277
+ - Fix #8/#10 project-selector ambiguity, full-path binding false negatives and contaminated model readback.
278
+ - Fix #9 environment recovery without a session: send full task/context/references once and locate the session through its marker or unique delta.
279
+ - Add initialization recovery with shared deadlines, configurable budgets and a resumable `setup_recovery` state. Reconcile native side effects after timeouts and terminate helper processes on cancellation.
280
+ - Handle split model labels, hidden outgoing animation text, residual project menus trapping focus and send buttons that are not yet ready.
281
+ - Add real DOM and recovery/cancellation regressions. Windows hardware verifies cold first import, imported-project reuse and same-task recovery with actual artifacts and 2/2 acceptance checks.
282
+ - Published as a GitHub Release/tarball and to npm (`latest`). macOS has no real-device verification for this patch and the ZCode profile remains `research`.
283
+
284
+ See [release notes](docs/release-v0.3.4.en.md) and [validation evidence](docs/zcode-issue-8-10-validation.en.md).
285
+
286
+ ## [0.3.3] — 2026-09-12
287
+
288
+ Fixes issues #4 / #7 by adapting the ZCode GUI driver to the 3.11.2 model-menu and project-binding semantics, while making acceptance fail closed for zero-test and zero-change outcomes.
289
+
290
+ ### Fixed
291
+
292
+ - ZCode provider selectors now support both `group-provider` and the 3.11.2 `group-family` prefix. Model selection tries the visible model first and only expands a provider/family group as a fallback; failures include visible text and `data-testid` candidates.
293
+ - New-project import dismisses the stale workspace menu before opening Add Project and uses a bounded three-round dismiss/click/verify loop, preventing the first click from being consumed as an outside click.
294
+ - Project binding prioritizes the composer menu's `menuitemcheckbox`; the legacy sidebar item remains a compatibility fallback. Display-name matching normalizes NFKC, whitespace, and case.
295
+ - Binding read-back combines the composer trigger text with the full-path fast path, rejects known unbound placeholders, and retries the idempotent bind operation for up to two rounds.
296
+ - Built-in ZCode and TraeWork discovery paths use `{PROGRAMFILES}` / `{PROGRAMFILES(X86)}`. Environment placeholders in custom profiles are expanded case-insensitively while unknown placeholders remain unchanged.
297
+ - A mandatory test check is failed when it exits with code 0 but its output reports zero executed tests.
298
+ - Git projects now require a change relative to the pre-work baseline by default. Pure question/analysis tasks can explicitly opt out with `"requireChanges": false` in `.tianshu-mcp/acceptance.json`.
299
+
300
+ ### Tests
301
+
302
+ - Regression coverage now models ZCode 3.11.2 flat family layouts, legacy provider fallback, testid diagnostics, swallowed project clicks, composer binding and read-back retries, plus zero-test/zero-change acceptance gates.
303
+
304
+ ---
305
+
306
+ ## [0.3.2] — 2026-09-12
307
+
308
+ Fixes for issues #5 / #6: **the MCP task model was disconnected from the state of the turn inside
309
+ the Codex GUI**. The former is the completion-detection deadlock that kept reporting `running`
310
+ while Codex waited for user confirmation; the latter is `cancel_task` only aborting the MCP-side
311
+ wait loop, never stopping the in-GUI run, with a misleading description. Both share the same root
312
+ cause and are resolved together.
313
+
314
+ ### Fixed
315
+
316
+ - **Waiting-for-user detection (issue #5)**:
317
+ - `judgeCodexPoll` gains a stall fallback: while the stop button stays visible and the
318
+ conversation hash is unchanged for `gui.stallTimeoutMs` (default 5 minutes), the task
319
+ transitions to `needs_user` (`needsUserKind=user_confirmation`) instead of deadlocking in
320
+ `running` until the overall timeout; the stall timer resets as soon as content changes again.
321
+ - New configurable UI detection `gui.selectors.userGate` (e.g. the embedded-checkout page or
322
+ approval cards): when configured and matched, transitions to `needs_user` immediately.
323
+ Unset by default (disabled) — no unverified selectors are built in.
324
+ - Tightened the `stopButton` selector: removed the `aria-label*="取消"` over-match (the Cancel
325
+ button on waiting-for-user screens used to be mistaken for a running signal).
326
+ - **Recovery path (issue #5 fallout)**: `continue_task` now supports codex —
327
+ - `user_confirmation`: after the user completes the action in the Codex window, resume by
328
+ re-attaching as an observer of the in-GUI run (no message is sent); if the turn already
329
+ finished before resuming, the task is still judged `succeeded` correctly;
330
+ - `login_required`: after login, re-checks the environment and re-dispatches the task brief
331
+ (fresh session + project binding + full initial prompt);
332
+ - zcode recovery behaviour is unchanged; other agents are rejected explicitly.
333
+ - **Cancel actually stops the GUI (issue #6)**:
334
+ - `cancel_task` no longer succeeds on request alone for GUI agents: it first best-effort clicks
335
+ the in-app stop button over CDP, then waits (bounded by `gui.cancelWaitMs`, default 15s) for
336
+ the GUI to become idle before settling `cancelled`; if the stop could not be confirmed the
337
+ terminal message states "GUI 内运行未确认停止…" (the in-GUI run may still be going);
338
+ - process-tree termination for CLI agents is unchanged;
339
+ - cancelling from `needs_user` now notes that a pending session may remain in the GUI
340
+ (no CDP connection exists at that point — documented limitation).
341
+ - **Re-dispatch anti-overlap guard (issue #6 chain risk)**: when dispatching, if the managed
342
+ instance still has an unstopped run, MCP first tries to stop it; if it cannot, the dispatch
343
+ fails hard with `instance_busy`, preventing old and new turns from overlapping inside the same
344
+ app (observed in the wild when re-dispatching right after a cancel).
345
+ - The startup log no longer hardcodes the tool count as `8`; it reports the actual registry size
346
+ (`TOOL_DEFS.length`, currently 9).
347
+
348
+ ### Changed
349
+
350
+ - Tool descriptions match actual semantics: `cancel_task` distinguishes CLI (kill process tree)
351
+ from GUI (best-effort stop click + bounded wait); `continue_task` no longer claims to be
352
+ ZCode-only.
353
+ - `GuiProfile` gains two configurable options, `stallTimeoutMs` (default 300000) and
354
+ `cancelWaitMs` (default 15000), both overridable via agent-profiles.json.
355
+ - Skill docs (SKILL.md §4/§5, usage-examples.md §7) document the codex `user_confirmation` /
356
+ `login_required` recovery flows, GUI cancel semantics and the new options.
357
+
358
+ ---
359
+
360
+ ## [0.3.1] — 2026-09-12
361
+
362
+ Post-v0.3.0 housekeeping for docs and release automation: **no source-level behavior changes**.
363
+ The focus is a full rewrite of the self-installed skill docs plus GitHub/Gitee release-body
364
+ composition and link fixes.
365
+
366
+ ### Changed
367
+
368
+ - **Skill docs (`skills/tianshu-mcp/`) fully rewritten to match the actual v0.3.0 tool surface**:
369
+ - Corrected the `codex` description from "headless CLI" to the ChatGPT desktop GUI adapter
370
+ (MSIX + COM activation + CDP); documents the required `model`, optional `reasoningLevel` /
371
+ `planDoc` / `designSystem`, and that `mode` is not supported;
372
+ - Documented the `run_task` `context` parameter and the send-time validation of path references
373
+ inside task/context; corrected the `autoFixRounds` default precedence
374
+ (call argument > codex 5 / zcode 2 > server default 0);
375
+ - Added usage for `list_tasks`, `query_task(tailLines)`, `get_task_report(round)` and
376
+ `verify_task` (`extraChecks` / `checksMode` / `baselineRef`) plus the four-level acceptance
377
+ command precedence;
378
+ - Documented the four `needs_user` kinds and meta fields such as `needsUserKind` /
379
+ `pendingQuestion` / `errorType` / `reportRound` / `verificationSource`;
380
+ - Added `continue_task` to the approval list; replaced emoji status markers with plain text
381
+ (PASS / warning) in the usage examples.
382
+ - **Release automation fixes (exposed by the v0.3.0 tag)**:
383
+ - The release body is now composed bilingually from `docs/release-v<version>.md` and `.en.md`,
384
+ with in-document relative links rewritten to tag-absolute links; a missing doc fails the
385
+ workflow loudly instead of producing a shell-only body;
386
+ - `Full Changelog` resolves the previous tag via `git describe` into a `compare/<prev>...<tag>`
387
+ link instead of degrading to a commits link;
388
+ - The body's `CI` link resolves the CI run for the same SHA instead of pointing at the Release run;
389
+ - Gitee releases are automated in `release.yml`: `scripts/gitee-release.mjs` idempotently
390
+ creates/updates the mirrored release (requires the `GITEE_TOKEN` secret; skipped loudly when unset).
391
+ - `.gitignore` now ignores npm pack artifacts and local temporary verification directories.
392
+ - Added the missing `[0.1.10]` / `[0.2.0]` / `[0.3.0]` / `[0.3.1]` compare links at the bottom of
393
+ this file and its Chinese counterpart.
394
+
395
+ ---
396
+
397
+ ## [0.3.0] — 2026-09-12
398
+
399
+ The Codex desktop app now runs through a **GUI driver**: a new `codex-gui` adapter uses MSIX COM activation
400
+ plus CDP to drive the ChatGPT desktop app through the full loop (locate install → launch GUI → bind/create
401
+ project → pick model and reasoning level → send instructions → run detection → verify → auto-repair).
402
+
403
+ ### BREAKING CHANGES
404
+
405
+ - **`agentId=codex` now executes via the desktop GUI instead of the headless CLI**: a new `driver=gui` +
406
+ `adapter=codex-gui` + `activation=msix-com`, with the previous **`codex exec` headless path removed**.
407
+ After upgrading, `run_task(agentId="codex")` launches and drives the Codex desktop window rather than a
408
+ headless child process. To keep headless execution, add a separate `driver=spawn` profile
409
+ (`argsTemplate: ["exec", "<prompt:arg>", "--skip-git-repo-check", "--sandbox", "workspace-write"]`) as
410
+ documented in `docs/agent-profiles.en.md`.
411
+ - This path requires the Codex desktop app (MSIX store package) to be installed; CLI-only environments are
412
+ no longer directly supported.
413
+
414
+ ### Added
415
+
416
+ - `codex-gui` adapter (`src/agents/codex/**`): Appx-first install discovery (scan fallback taking the newest
417
+ version), MSIX COM activation with a dedicated `user-data-dir` and dynamic debug port, plus CDP attach and
418
+ target convergence (excluding the overlay secondary window).
419
+ - Task parameters: `reasoningLevel` (low/medium/high, bilingual), `planDoc`, `designSystem`.
420
+ - Model and reasoning level: models are `menuitemradio` candidates while **reasoning strength is a slider**
421
+ (0–4: 轻度/中/高/极高/极高), set precisely with arrow keys and read back for verification; level
422
+ comparison is exact to avoid matching "高" against "极高".
423
+ - **Automatic project registration**: a target directory not yet registered on the Codex side is written
424
+ directly into Codex project state (idempotent, backup-before-write, atomic write, only while the
425
+ MCP-managed instance is stopped), so it takes the stable bound-project path instead of the brittle native
426
+ folder dialog; on failure it falls back to UI creation.
427
+ - Verification and repair: reuses the existing AcceptanceEngine (defaults derived from `package.json`, with
428
+ weak-verification labelling); on failure the MCP generates an in-project
429
+ `.zcode/plans/codex-fix-r<N>.md` (one per round, never overwritten) and cites it in the repair instruction,
430
+ up to 5 rounds by default (`defaultAutoFixRounds`).
431
+ - Run detection: the stop button is the authoritative running signal, and text stability counts as completion
432
+ evidence only after it; without a running signal it fails open to `idle_timeout` while keeping the instance
433
+ (never a false completion).
434
+ - `scripts/probe-codex.mjs` hardware diagnostic script; 67 Codex unit tests plus integration coverage of the
435
+ verify-fail → generated plan → repair-pass loop.
436
+ - Docs: `docs/codex-gui-cdp.en.md`, `docs/codex-windows-smoke.en.md` (including the round-2 real business task
437
+ acceptance) and their Chinese counterparts.
438
+
439
+ ### Changed
440
+
441
+ - `GuiProfile` gains `activation` / `userDataDir` / `appxPackageName` / `permissionMode` / `fixPlanDir`;
442
+ existing `spawn` profiles are unaffected.
443
+ - `ExecutableDiscovery` gains `appxPackageName` / `installRelativeExe` / `scanRoots` / `scanPattern`.
444
+
445
+ ### Fixed (exposed by hardware testing)
446
+
447
+ - The model trigger mis-matched the sibling permission chip (4 chips share `aria-haspopup`; only the model chip
448
+ lacks `aria-label`).
449
+ - Reasoning strength was clicked like a menu item and could never be set (it is actually a slider).
450
+ - Menus/popovers only open on **trusted** mouse events (DOM `.click()` is ignored).
451
+ - A transient empty model read during toolbar re-render after binding was treated as a "model mismatch".
452
+ - Model/reasoning trigger selectors now exclude the top menu bar and the mode switcher.
453
+ - Cold-start readiness budget widened to 150s (registration stops the instance first; cold start measured ~85s).
454
+ - CI: fixed a `normalizeDir` assertion that depended on the host platform, which failed on ubuntu/macos.
455
+ - Fixed integration tests polluting real Codex project state by not injecting `ensureRegistered`.
456
+
457
+ ### Verification
458
+
459
+ - Windows 10 x64 hardware: full loop for a registered project, and the verify-fail → generated plan →
460
+ repair-pass loop; an unregistered project completed the full loop after automatic registration.
461
+ - Real business task: drove Codex to build a "Fruit Ninja" mini-game in HTML+CSS+JS (`GPT-5.6 Sol` with
462
+ reasoning strength "高"); the artifacts passed acceptance and were verified playable in a headless browser
463
+ (score rises, lives decrement, Game Over and restart work, no JS exceptions).
464
+ - macOS unverified: the built-in Codex GUI status is `research` and is excluded from readiness.
465
+
466
+ ---
467
+
468
+ ## [0.2.0] — 2026-09-11
469
+
470
+ ### Added
471
+
472
+ - Dedicated `zcode-gui` Electron CDP adapter with data-driven Windows/macOS discovery, dynamic ports, product/process checks, and a global serial lock.
473
+ - Exact ZCode project binding, guarded native folder pickers, `provider/model`, Full Access read-back, and idempotent sending.
474
+ - Paused `needs_user` state and approval-gated `continue_task` for original-session answers and environment rechecks after instance, login, or permission handling.
475
+ - Multi-signal liveness, progress events, UI preservation, default auto-verification, and two same-session repair rounds. Repair plans stay in MCP task storage.
476
+ - `scripts/probe-zcode.mjs`, fake-CDP/state/path/model tests, and bilingual documentation.
477
+
478
+ ### Safety and compatibility
479
+
480
+ - GUI profiles support an explicit `adapter`; legacy `driver="gui"` profiles retain TraeWork behavior.
481
+ - The built-in ZCode profile remains `research` until both real platform loops pass.
482
+ - No private `app-server`, credential access, automatic user-instance termination, or fixed screen coordinates.
483
+
484
+ ### Fixed and verified
485
+
486
+ - Fixed ZCode read-back for dynamic model labels, transient renderer load/reload, delayed new-session registration, and stale session-ID contamination.
487
+ - `AskUserQuestion` continuation now selects and submits an exact accessible option in the original session; zero or ambiguous matches fail closed.
488
+ - Windows 10 x64 passed three hardware loops: real file development, same-session repair after a controlled failure, and `continue_task` after a model question. macOS hardware evidence remains pending.
489
+
490
+ ---
491
+
492
+ ## [0.1.10] — 2026-09-10
493
+
494
+ ### Fixed
495
+
496
+ - **Fixed stdio log pollution (issue #1)**: the unified logger previously sent only ERROR to
497
+ `console.error` while INFO/WARN/DEBUG went to `console.log`, sharing stdout with MCP JSON-RPC
498
+ messages and breaking handshakes or tool calls in strict stdio clients. All levels passing the
499
+ threshold now go to stderr, leaving stdout for valid MCP messages only.
500
+ - Log file appending, timestamps, level tags and the `<data dir>/logs/server.log` path are unchanged;
501
+ a startup failure is still reported on stderr.
502
+
503
+ ### Added
504
+
505
+ - New `scripts/check-stdio.mjs` strict stdio smoke: a real child process validates the complete
506
+ stdout/stderr byte stream, allowing only newline-delimited, schema-valid MCP JSON-RPC messages on
507
+ stdout; empty lines, non-JSON lines, parser errors, or trailing fragments at exit fail the run.
508
+ It covers six scenarios: first start, second start with matching skills, `--no-skill-install`,
509
+ a corrupt `config.json`, logs during a stub task, and clean EOF shutdown.
510
+ - New `npm run check:stdio` and `npm run check:stdio:src` scripts.
511
+
512
+ ### Tests
513
+
514
+ - New `test/unit/log.test.ts`: real-child-process checks for the four log levels' channels, default
515
+ INFO filtering, threshold-filtered file logging, and UTF-8 content (4/6 failed before the fix; see
516
+ `docs/m2-evidence/issue1-old-impl-log-test-failure.txt`).
517
+ - CI's three-platform matrix now includes Node 24; the build step runs the strict stdio check instead
518
+ of an EOF-exit-only smoke.
519
+ - CI `pack-check` and Release install the freshly built tarball into a clean consumer directory, read
520
+ the installed bin dynamically, and reuse the same strict stdio check; Release adds `lint` and the
521
+ installed-package protocol gate, failing before a draft is created.
522
+ - ESLint enables `no-console` (allowing `error` only) for `src/**/*.ts` to prevent new direct stdout writes.
523
+
524
+ ---
525
+
526
+ ## [0.1.9] — 2026-09-09
527
+
528
+ ### Fixed
529
+
530
+ - Fixed premature TraeWork completion while the model was still thinking but the DOM stayed unchanged for about 36 seconds.
531
+ The stop button and loading task tail are now authoritative running signals and override completion marks; stable rounds now
532
+ start an idle timer, which defaults to ten minutes before returning `idle`.
533
+ - Fixed permanently pending `Runtime.evaluate` calls after a CDP WebSocket disconnect. Close/error rejects all pending requests,
534
+ each CDP command has a 15-second default timeout, and task cancellation is observed within about one second.
535
+ - Only `completion_mark` / `ask_user` release an instance launched by this module. Idle, timeout, cancellation, and CDP loss retain
536
+ it, with `agentEndReason` / `keptInstance` exposed in task metadata.
537
+ - Fixed a shutdown race where an orchestrator still collecting its baseline could remain `queued` and be mislabeled as a user
538
+ cancellation. User cancellation is now determined only from structured cancellation intent.
539
+
540
+ ### Added
541
+
542
+ - Polling emits a progress event visible through `query_task` every 30 seconds by default.
543
+ - Added `gui.idleTimeoutMs`, `gui.cdpSendTimeoutMs`, `gui.progressIntervalMs`, and five overrideable liveness selectors.
544
+
545
+ ### Testing
546
+
547
+ - Added liveness truth-table, CDP timeout/disconnect convergence, selector-expression, and fake-CDP instance-retention regressions.
548
+ - Windows/macOS/Linux × Node 20/22 and tarball gates remain covered.
549
+
550
+ ---
551
+
552
+ ## [0.1.8] — 2026-09-08
553
+
554
+ ### Fixed
555
+
556
+ - **Atomic-write concurrency defect** (the real cause of intermittent CI failures): the temp filename in
557
+ `writeJsonAtomic`/`writeTextAtomic` was `<target>.<pid>.tmp`, so concurrent writes to the same target in one
558
+ process shared one temp file - the first to finish renames it away and the next throws `ENOENT`; on Windows a
559
+ concurrent rename can also throw `EPERM`. Symptom: `rework_task` intermittently returned an `undefined` meta
560
+ (hit on CI windows/Node 20). Fixed by a random temp suffix plus backoff-retry on transient rename errors.
561
+
562
+ ### Testing
563
+
564
+ - New `test/unit/atomic-write.test.ts` (3 cases: concurrent JSON/text writes all succeed, no leftover temp files).
565
+
566
+ ---
567
+
568
+ ## [0.1.7] — 2026-09-08
569
+
570
+ ### Fixed
571
+
572
+ - **Project-folder binding still failed** (v0.1.6 did not fully resolve it; field report: the native dialog
573
+ appeared but the edit box was empty and confirm was clicked anyway):
574
+ - **Root cause**: the MCP passes a `normPath()`-normalized path (lowercase drive + forward slashes, e.g.
575
+ `d:/Trae项目/AI游戏/象棋`), which the **native Windows picker rejects** — measured: read-back matched, yet the dialog
576
+ stayed open after confirm. Fix: convert via the new `toNativeWindowsPath()` to `D:\a\b`.
577
+ - `WM_GETTEXT` **read-back verification** after writing; on mismatch re-locate and retry (up to 3 times);
578
+ if it still mismatches, **never click confirm** and fail loudly.
579
+ - The hwnd detected after the footer click is **passed into the write script**; after clicking, success
580
+ requires that hwnd to be gone.
581
+ - **Auto-close stale dialogs** (left over from a previous failure) before binding.
582
+ - Confirm button now also requires its rect to be in the lower half of the dialog.
583
+ - The dialog script's full trace (HWND/READBACK) is written to the task log.
584
+
585
+ ### Testing
586
+
587
+ - Total tests **172 → 181** (unit incl. path normalization and atomic-write concurrency; integration incl. stale-dialog cleanup).
588
+ - Machine-verified: a new Chinese project `D:\Trae项目\AI游戏\象棋` (absent from the dropdown)
589
+ passed end-to-end through the native dialog; `五子棋` and the ASCII project `ts-bind-test` regressed green.
590
+
591
+ ---
592
+
593
+ ## [0.1.6] — 2026-09-08
594
+
595
+ ### Fixed
596
+
597
+ - **Project-folder binding got stuck / reported "waiting for native dialog timed out"** (field report; the adapter was not broken):
598
+ - `clickDropdownFooter` used to trust `element.click()`'s return value, but the native popup may never
599
+ appear → it now **confirms the dialog actually appeared**, otherwise it logs a dropdown DOM snapshot and fails loudly.
600
+ - Dialog detection polled from Node every 800 ms while PowerShell cold start is ~4.5–6 s, so a 15 s budget
601
+ allowed only ~2 probes → now it polls **inside a single PowerShell call** (400 ms interval) with a 30 s budget.
602
+ - **CJK paths were corrupted** (measured: `D:\Trae项目\ts-bind-test` became `D:Traes-bind-test`):
603
+ SendKeys/clipboard are mangled by the console code page → the path is now written via Win32
604
+ **`WM_SETTEXT`**, which is fully reliable for CJK.
605
+ - **The confirm click hit a file-list row**: `AutomationId="1"` is not unique (rows also use 0/1/2…) →
606
+ now located by **AutomationId=1 AND ControlType=Pane**, then clicked by bounding rect.
607
+ - PowerShell output was garbled for Chinese → the script now emits **ASCII-only** and Node maps it back
608
+ via `localizeDialogMessage()`.
609
+
610
+ ### Added
611
+
612
+ - **Non-Work binding fallback**: when binding fails in Code/Design, the driver **falls back to Work once**,
613
+ switches back to the target mode, and re-verifies the project is still bound; only if both attempts fail
614
+ does it report an error including the reason from each mode.
615
+ - Machine-verified: for a project **absent from the dropdown** (`D:\Trae项目\ts-bind-test`),
616
+ `run_task(agentId=traework, mode=Code)` passed end-to-end — native dialog wrote the path → confirm clicked →
617
+ project entered TraeWork's list (`solo-lite.local-project-folders` 22→23) → task sent → auto-verification `succeeded`.
618
+
619
+ ### Changed
620
+
621
+ - `docs/traework-cdp.md` / `.en.md`: 7 new pitfall entries; added the "dropdown entries ≠ project map" fact and the fallback note.
622
+
623
+ ### Testing
624
+
625
+ - Total tests **167 → 172** (new dialog message-mapping/platform-branch unit tests + Code→Work fallback integration test).
626
+
627
+ ---
628
+
629
+ ## [0.1.5] — 2026-09-08
630
+
631
+ ### Added
632
+
633
+ - **TraeWork panel mode switching**: `run_task` gained a `mode` parameter supporting `Work` / `Code` / `Design`.
634
+ - Resolution order: explicit `mode` parameter > task-text detection > keep `Work`.
635
+ - Text detection handles mixed Chinese/English phrasing ("switch to Code mode", "use design mode", "工作模式", "代码模式", "设计模式", …).
636
+ - New `gui.modeSwitch` profile switch (default `true`).
637
+ - New pure functions `detectModeFromText` / `resolveMode` (unit-tested).
638
+ - **Dedicated SVG assets**: `assets/tianshu-mcp-icon.svg` (app icon), `assets/tianshu-mcp-banner.svg` (wide banner).
639
+ - New `scripts/probe-traework.mjs mode <Work|Code|Design>` subcommand (real-machine diagnostics/verification).
640
+ - New bilingual release notes `docs/release-v0.1.5.md` / `.en.md`.
641
+
642
+ ### Changed
643
+
644
+ - **TraeWork execution order**: measurement showed the three modes **each keep an independent project binding** —
645
+ switching modes replaces the input bar's project with whatever that mode last used.
646
+ Order is now: ensure instance → wait for UI → new session → switch to target mode → bind project inside that mode → switch model → send.
647
+ - After binding, both mode and project are re-verified; any mismatch **fails loudly** (never silently develops in the wrong mode).
648
+ - meta block now exposes `model` / `mode` for Tianshu to read back.
649
+ - `package.json`: `license` changed from `MIT` to `Apache-2.0` (matching the repository `LICENSE` file);
650
+ added `repository` / `homepage` / `bugs`; `files` now includes `assets`.
651
+ - README.md / README.en.md fully rewritten: stack badges, SVG banner (above the icon), language isolation
652
+ (the Chinese README references Chinese docs only; the English README references English docs only).
653
+
654
+ ### Fixed
655
+
656
+ - **Rework feedback race** (pre-existing; intermittent under load): the terminal snapshot is written first, so a caller's
657
+ immediate `rework_task(feedback)` could be erased by the previous run's `delete meta.reworkFeedback`, leaving the rework
658
+ round without feedback. Now the feedback is consumed and cleared atomically when `startTask` begins.
659
+ Added regression test `test/integration/rework-feedback-race.test.ts`.
660
+ - **`projectBasename` cross-platform**: it used `path.basename` (which does not split backslashes on POSIX), failing
661
+ Linux/macOS CI; now it splits explicitly on both `\` and `/`.
662
+
663
+ ### Testing
664
+
665
+ - Total tests **153 → 167** (14 new mode-related cases).
666
+ - Real-machine end-to-end: `mode=Work` / `mode=Code` / `mode=Design` all completed
667
+ "switch mode → bind project → send → create file → auto-verification passed".
668
+
669
+ ---
670
+
671
+ ## [0.1.4] — 2026-09-08
672
+
673
+ ### Added
674
+
675
+ - TraeWork GUI driver over CDP: `traework` moved from `unsupported` to `driver=gui` / `status=ready`.
676
+ - Capabilities: launch/reuse instance → new session → bind project folder (dropdown first, restricted computer-use
677
+ native dialog as fallback) → optional model selection → read-back-verified send → poll to completion →
678
+ auto-verify → repair-plan file + same-session rework on failure.
679
+ - Safety: reuse the user's instance by default, never kill a process tree, verify the command line before terminating;
680
+ computer-use is limited to TraeWork's folder picker.
681
+ - `AgentAdapter` gained an optional `run()` execution surface; the orchestrator branches on `adapter.run`
682
+ (CLI agents still use spawn).
683
+ - Profile gained `driver` (`spawn` / `gui`) and a `gui` section; `run_task` gained a `model` parameter.
684
+ - New `src/agents/traework/**` (CDP client, selector table, launcher, session/input/model/reply modules, restricted computer-use).
685
+ - On verification failure a repair-plan file `rework-<taskId>-r<N>.md` is generated (task dir + project `.tianshu-mcp`)
686
+ and its filename is referenced in the rework message.
687
+
688
+ ### Changed
689
+
690
+ - `docs/adapter-matrix.md` T1 conclusion corrected from `unsupported` to "integrated (driver=gui)".
691
+ - formatter now passes cancel-source fields (`abortSource`, …) through to `query_task`'s meta block.
692
+
693
+ ### Fixed
694
+
695
+ - Unified timeout terminal state: normal timeouts now also land `failed(timeout)` plus exactly one `timeout_killed` event, in fixed order.
696
+ - Stabilized the `shutdown` test polling.
697
+
698
+ ### Testing
699
+
700
+ - Total tests **72 → 153** (new TraeWork unit/integration cases).
701
+ - Real-machine end-to-end: `run_task(agentId=traework, model=GLM-5.3, autoVerify=true)` drove TraeWork to create a file and passed acceptance.
702
+
703
+ ---
704
+
705
+ ## [0.1.3] — 2026-09-08
706
+
707
+ ### Fixed
708
+
709
+ - **S1** No-reason cancel was mis-recorded as `interrupted`: added independent `cancelRequestedAt` / `abortSource` fields;
710
+ cancel intent no longer depends on the optional `reason` (5 regression tests).
711
+ - **S2** Unified timeout terminal state (shared with 0.1.4).
712
+ - **S3** Tracked pre-dirty net-diff attribution: pre-existing dirty files are excluded by content hash when unchanged;
713
+ unchanged staged/unstaged files are no longer reported as agent changes (4 regressions).
714
+ - **S4** `verify_task(taskId)` persists real-task metadata (`reportRound` / `verificationSource` /
715
+ `latestVerificationVerdict`, keeping `agentId`); single-source MCP version (`sync-version` injection).
716
+ - **S5** `projects.json` official Zod schema + last-known-good for `config`/`profiles`/`projects` + content-sha256
717
+ hot-reload invalidation (fixed corrupt JSON being treated as missing and reset).
718
+
719
+ ### Changed
720
+
721
+ - **S6** CI/Release `npm ci` retry corrected (stop on success / 3 attempts / attempt counter);
722
+ Vitest v3 upgrade (0 audit vulnerabilities); plain-text status markers (emoji scan test).
723
+
724
+ ### Testing
725
+
726
+ - Total tests **53 → 72**.
727
+
728
+ ---
729
+
730
+ ## [0.1.2] — 2026-09-08
731
+
732
+ ### Changed
733
+
734
+ - Build no longer ships source maps (no `.map`, tarball ≈ 69.9 KB).
735
+
736
+ ### Testing
737
+
738
+ - Total tests **53**.
739
+
740
+ ---
741
+
742
+ ## [0.1.1] — 2026-09-07
743
+
744
+ ### Added
745
+
746
+ - **Release after the R1–R5 fixes**:
747
+ - **R1** Cancel/interrupt state persistence (`cancel_requested → cancelled`, `cancelReason`/`finishedAt`/`errorType`
748
+ persisted, restart-recoverable, idempotent, bounded shutdown).
749
+ - **R2** Call-level `taskTimeoutMs` precedence fix + cross-platform process-tree termination
750
+ (POSIX process-group SIGTERM→SIGKILL, Windows `taskkill /T /F`).
751
+ - **R3** Git baseline participates in diff (boundary at `baseline.head`; agent commits do not lose changes;
752
+ dirty-worktree hash attribution).
753
+ - **R4** Verification tool parameters and report-round semantics (`round=0` valid, manual verify does not overwrite
754
+ reports, `extraChecks` append + `checksMode=replace`, `optional` does not affect verdict, `baselineRef` validated).
755
+ - **R5** Removed hardcoded agent paths (`{LOCALAPPDATA}` placeholders + platform-standard candidates);
756
+ mtime hot reload for `config`/`profile`/`projects`.
757
+ - **R6** Cross-platform CI matrix (Windows/macOS/Linux × Node 20/22) and Release version consistency
758
+ (tag/input = `package.json` = tarball), plus tarball content checks.
759
+ - **R7** npm published `tianshu-mcp@0.1.1` + `npx -y` raise with 8 tools connected.
760
+ - **R8** Bilingual docs synced (including 4 English topic docs).
761
+
762
+ ---
763
+
764
+ ## [0.1.0] — 2026-09-07
765
+
766
+ ### Added
767
+
768
+ - First usable release: **M1 core engine + stub-agent end-to-end**.
769
+ - 8 MCP tools: `run_task` / `query_task` / `list_tasks` / `get_task_report` / `cancel_task` / `verify_task` /
770
+ `rework_task` / `get_profiles`.
771
+ - `TaskManager` state machine / per-project serial queue / global concurrency gate / cancel (kill tree) / event-stream persistence.
772
+ - Acceptance engine: git baseline & diff, default check-set derivation, command runner, code analysis,
773
+ `report.md` / `report.json`.
774
+ - fix-loop auto rework + `needs_attention`; skill self-install.
775
+ - Stub-agent 3 playbooks (good / fix-on-first / never) integration tests + protocol tests — **53/53 green**.
776
+
777
+ ---
778
+
779
+ [Unreleased]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.4.1...HEAD
780
+ [0.4.1]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.4.0...v0.4.1
781
+ [0.4.0]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.4...v0.4.0
782
+ [0.3.4]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.3...v0.3.4
783
+ [0.3.3]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.2...v0.3.3
784
+ [0.3.2]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.1...v0.3.2
785
+ [0.3.1]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.3.0...v0.3.1
786
+ [0.3.0]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.2.0...v0.3.0
787
+ [0.2.0]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.10...v0.2.0
788
+ [0.1.10]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.9...v0.1.10
789
+ [0.1.9]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.8...v0.1.9
790
+ [0.1.8]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.7...v0.1.8
791
+ [0.1.7]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.6...v0.1.7
792
+ [0.1.6]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.5...v0.1.6
793
+ [0.1.5]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.4...v0.1.5
794
+ [0.1.4]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.3...v0.1.4
795
+ [0.1.3]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.2...v0.1.3
796
+ [0.1.2]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.1...v0.1.2
797
+ [0.1.1]: https://github.com/lanlan0811/tianshu-mcp/compare/v0.1.0...v0.1.1
798
+ [0.1.0]: https://github.com/lanlan0811/tianshu-mcp/releases/tag/v0.1.0