Repository navigation
fix(goal): expire pause controls across resumed turns - #1
Merged
new-Beginner merged 32 commits intoNov 6, 2026
Merged
Conversation
The 34px icon left room for a type badge but not for the name: at the previous default width a tile had about 40px of text and truncated after three characters. Every source now renders the same 48px rounded square, the badge is gone, and the name owns the whole line under the icon. The window opens at 900 DIP and refuses to go below 800, which is the narrowest width where an eight-column row still fits the icon and a readable name. The trade-off is explicit: a plugin and an application look identical until one is opened, and the hover title is the only place that still names the source.
The spec still described a type badge, a square/round split and a 560 minimum width. It now states the two-part tile, the 48px shape, the 800/900 width floor and default, and that telling a plugin from an application is a deliberate non-goal covered only by the hover title. The ADR records the same trade-off in its consequences, and E2E-268 gains a same-name step so the behaviour is checkable by hand.
Brings the tile change onto the current base; no conflicts, the merge is purely additive against the launcher files.
A Markdown link whose destination names a real directory failed in two independent places (issue vastsa#2113): - normalizeMarkdownFilePath waived no heuristics for drive-anchored destinations, so an extension-less directory fell out of normalization and rehype-sanitize stripped the href as an unknown c: scheme — the anchor rendered with no target at all. A link destination is an explicit reference (the rule markdownLinkFileTarget already applies), so normalization now keeps the same acceptance and encodes the path. - resolveChatFileRef required a regular file at every tier, so the open flow reported a missing file for a path that exists. Exact references can now name a directory inside the managed roots when the caller passes allowDirectory: the match carries target "directory" and the chat open flow browses it in the file manager. Shorthand and fuzzy completion never set the flag, so a directory named like a file keeps answering nothing (the pinned contract), and directories outside the managed roots stay outside the ADR 0339 file contract. Explicit Markdown links and tool-arg chips set the flag; the bundled file manager already reveals a directory location by expanding its ancestors, so no plugin change is needed.
The bundled File Manager answered a host location that names a directory by dispatching fm.read, which refuses directories (INVALID_PATH "path is a directory") — the PR review reproduced this against the shipped handler, so the chat open flow produced a tab whose tree was collapsed and whose reader had failed. Rebuild the vendored view with a directory-aware receiver (Desktop hotfix 0.9.1-pi.2, the 73d8932 convention — no minified JavaScript is edited by hand; the patch carries the source change and the provenance record carries the new checksums): - classifyHostOpenTarget (views-src/src/lib/hostOpen.ts) reads the target's identity from the already-loaded parent listing; a missing listing stays conservative and keeps the file path. - applyHostOpen expands a classified directory, loads its entries and shows the tree instead of collapsing it over an unreadable preview; ordinary files keep their exact previous flow. - failureMessage translates the production directory rejection into a localized message for references outside the managed roots (scratch), which stay un-browsable — containment unchanged, main.js untouched. Boundary tests execute the shipped main.js: reads refuse directories in both addressing modes, lists answer directories and refuse files, and ordinary files read as before. The Electron journey drives the real view over the real plugin process for primary, sibling-root and scratch directory locations plus ordinary-file behavior. The rebuilt view is byte-reproducible from the pinned integration commit with the two checked-in patches applied.
…grid feat(plugin-launcher): one 48px rounded tile per item and a wider panel
With the Count badge and the Activity rail both enabled, a project header rendered the same running and permission-waiting figures twice: the rail's numeric readout is documented as the badge's stand-in, yet both call sites gated it on the rail switch, so turning the rail on duplicated the counts side by side. `resolveSidebarRunningAffordances` now owns that exclusivity rule as `railCount`, and the local and remote headers render the readout from it, so one figure appears once per group while each sub-switch still hides only its own affordance. The sidebar IA spec, its zh-CN mirror, and the E2E-266 expectation record the ownership rule.
The first CI run of the directory journey exposed a first-frame race the review repro did not: the host location is released as soon as the project group is applied, which can precede the root listing, so the classifier read an absent listing, answered unknown, and the open fell back to the file read — exactly the failure this hotfix removes. The receiver now loads the parent listing (loadDirectory is idempotent, so an already-loaded parent costs no extra channel call) before asking what the location names; a listing that then lacks the entry still falls back to the file path and reports accurately.
…icate fix(sidebar): print one running count per project header
The journey's preload stub omitted pi.fs, so the real handleHello threw on its bare-typeof openInBrowser probe and the view mounted without the workspace — the directory scenario then timed out on an empty tree. Add the fs surface the hello answers on, and the setSettings write the sibling-root switch issues.
The model menu hid everything beyond three recent models behind an "Other models" disclosure, then dumped every provider into one long list. Finding a model meant expanding and scrolling. The menu now pairs a source rail (Recent, then each provider with its model count) with a pane listing the chosen source's models, so every configured model is one click away. Search spans all providers and dims sources without matches. The pane height is fixed by the tallest source so switching or typing never resizes the menu, and the reasoning slider sits in its own footer.
Two-pane Composer model picker with a source rail.
Two CI runs failed on the same bare timeout, so the journey no longer fails blind: the preload records every bridge call (channel, verdict, result head) and exposes the log to the page, a preload crash is carried as its own diagnostic, waits extend to 15s, and a scenario that never reaches its expectation dumps the full page state — rows, selection, banners, body sample, channel log — into the probe line.
The bridge:false failure modes are preload crashes, and the one diagnostic that names them was exposed to the page but never read back. readState now returns __preloadError alongside the channel log.
The preload crash finally named itself: main.js requires its sibling ./remote-workspace.js, and the fixture staged main.js alone, so the require failed, the bridge never mounted, and every scenario timed out on the no-bridge empty state. Stage both runtime files.
The journey's channel log pinned the real defect: both root listings had answered with the directory entry before the read was dispatched, so the miss was not the first-frame race but the read-back — directories state reaches dirsRef through a render, and the open chain's microtask continuation still saw the previous map, so the classifier answered unknown and the flow fell back to the file read. loadDirectory now returns the entries it saw (cached hits included) and the receiver classifies against that value directly.
…asoning The first two-pane picker read heavy: colored monogram tiles in the source rail, a filled slab on the current row, and a dot-rail reasoning slider that did not match the compact rows around it. The rail is now text only with one marker that slides between sources, the model pane slides in from the direction of the move, and the current row gets a drawn check instead of a fill. Search becomes a flush header with a clear button, and Escape clears a typed search before closing. Reasoning is a segmented track in the footer with a raised pill; the native range still owns keyboard, drag and accessibility, and the D458 column geometry is unchanged (D685). The reasoning layout fixture was missing recentEntries, so the Electron geometry check could not open the menu; it now runs and covers the segmented control.
Refine the Composer model picker: text rail, segmented reasoning control.
The locale check requires the Chinese decisions log to keep the English table shape, so the new D685 row needs its translated counterpart.
Keep Electron alive between scenarios and assert actual file-read calls. The editor DOM is mounted even without a file, and a nested managed root keeps its primary-relative address.
Include the new presentation component and real directory prompt parser in the existing isolated transcript harnesses so unrelated message regressions remain covered.
Validate the directory receiver and repaired journey against the current target branch.
…-redesign feat(composer): two-pane model picker with a text rail and segmented reasoning
…e-layout-20261106 fix(composer): show pasted folders above prompt text
Include the landed composer fixes and picker changes before validating the directory link candidate.
fix(chat): open explicit directory links in the file manager
Keep the repair candidate based on current main while preserving the\nexisting Goal branch history. The lifecycle fix is a separate commit\nso its small behavioral diff can be reviewed independently.
Scope pause steering to the current validated closeout through a replaceable system section, rather than append-only prompt content. Restore legacy controls as inert history without rewriting saved data. Cover warm resume, cold legacy replay and compaction while preserving real user constraints, tool access checks and bounded handoff behavior.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs vastsa#1999
第一阶段最小修复
目标分支是 vastsa#1999 的
feat/autonomous-goal-9ba23a,不是 main。以原 PR 最新 head6ae2428dd2f039bd30109a2a1817e4a33853d84b为输入,保留其完整历史,不重写或直接推送该分支。实际修复:c36aeb321a4949711bf756c8885d4fc68cb806d5:10 文件 +167/-22,其中生产源码仅 5 文件 +24/-7;其余为必要回归和两处规范同步。
goal_pause系统分段,按当前已验证 GoalTurn 的 closeout 状态合成;新 claim、普通 Agent 工作和移除后的转换不继承旧暂停命令。复用现有分段覆盖/清空机制,不新增数据库或协议字段。基线同步单独提交
879268855是无手工冲突解决的自动合并基线,纳入最新 maind4f5c10f371c373485342a59a5b364356189f70f。vastsa#1999 尚未包含这批 main 提交,因此整体比较页也会显示既有主干变更;请用上面的 c36aeb3 单独提交审阅本次最小修复。基线同步与行为修复没有混在同一个提交。必要验证
check:pr-base通过。c36aeb321a4949711bf756c8885d4fc68cb806d5,main 为d4f5c10f371c373485342a59a5b364356189f70f。Rust 源码与原 feat(goal): add durable autonomous goals with attached controls vastsa/PI-Desktop#1999 候选相同,复用同源码 release Host(SHA25663128f6a68953eefd51eeb7dfdec747166064b247a06a363c6e73ab3c511b960),没有重装依赖。按快速、最小范围要求,未运行全仓测试/构建、跨平台套件、
verify:ui:*、真实提供商请求或发布安装。没有操作真实问题会话,也没有上传私有报告、原始日志或数据库。远程 Checks 以新 PR 的实际结果为准,不以 vastsa#1999 旧 head 的 CI 代替。