22 Commits
Author SHA1 Message Date
YHH 493736c685 Merge pull request #14152 from lancy69/fix/14126-minimal-image-capability
fix(composition): allow lightweight mode without image capability
2026-10-23 05:39:10 -07:00
Lancy 46f6adebbb fix(composition): make lightweight image capability optional 2026-10-22 15:09:42 +08:00
SivanCola c2a485ebc5 feat(studio): add grouped preset module multiselect
Problem: Preset modules could only be added one at a time, with two different actions both labeled Add module.

Root cause: A native single-choice picker shared its label with manual blank-ID insertion, and catalog choices did not carry source provenance.

Fix: Add a shared searchable grouped checkbox picker, authoritative catalog provenance, batch selection and parameter-safe draft updates. Keep manual IDs under an explicit advanced entry and document selection semantics.

Verification: 219 frontend tests, typecheck, production build, census, owning Go packages including boot and builtin, focused Desktop preset/composition tests, vet, lint, make check and documentation checks passed. Browser checks covered themes, responsive layouts and save/reopen with MockHub.
2026-10-21 12:15:04 +08:00
SivanCola 073079d675 feat(composition): load preset resources on demand
Problem: selecting a custom preset captures unused skill templates and
extension packages and waits for optional MCP startup.

Root cause: resource snapshot creation also served as the runtime permission
model, making selection cost scale with installed resource payload.

Fix: add live capability-grant bindings while preserving legacy snapshots.
Resolve current skill/MCP/extension/hook/command authority at use, defer
optional startup, retain stable provider contracts, and fence new event
and archive formats from older readers. Use lightweight status summaries
and per-instance extension call leases for safe concurrent replacement.

Verification: root and Desktop suites, full boot/builtin suites, affected
storage/controller/frontend tests, lifecycle race checks, frontend interaction
tests and typecheck, lint/vet/check, actionlint, and Windows cross-compilation.
Twenty-sample real switch measurements include build, persist and publication;
64 MiB unused templates remain outside the binding and stay below the local
500 ms P95 target. Native Windows execution is delegated to hosted CI.
2026-10-20 18:49:01 +08:00
SivanCola a3dab1bff1 fix(compositions): check retained hook credentials at argument boundaries
Problem: Windows CI rejects the retained-hook source-deletion fixture as a
credential-bearing launch before reaching its restoration assertions.

Root cause: credential projection scans the complete quoted shell string as a
generic value, splitting a Windows drive colon inside a quoted file argument.
That creates an unmatched quote and falsely marks the command as sensitive.

Fix: reduce shell launches to static arguments before credential inspection,
preserve exec and legacy argv launches, and continue refusing literal token and
header arguments or shell forms that cannot be reduced safely. Keep source
commands and retention/restoration semantics unchanged.

Verification: regression reproduces both quoted Windows path failures before
the fix, while exec/legacy argv and token/header refusal cases stay covered.
Focused retention/security regressions and their race run pass; full builtin
and boot tests, gofmt, vet, lint and changed-file checks pass locally.
2026-10-20 01:37:50 +08:00
SivanCola b5a8cfd299 fix(compositions): enforce filesystem boundaries and portable retention tests
Problem: CodeQL reported new path and allocation alerts, and Windows repeatedly
failed the retained-hook restoration test.

Root cause: Checked selectors were still passed onward as raw request values;
some generated paths and capacity hints did not expose their bounds at the IO
owner. The HTTP DTO also carried an internal inherited binding. The hook fixture
fed Windows backslashes through Bash resource parsing.

Fix: Resolve import/export selections to registered values, forward checked
relative names for resume/migration, and guard the generated session slug before
joining it to state storage. Use rooted declaration/resource reads and copies,
bound resource reads, and avoid unchecked capacity addition. Pass inherited
bindings outside the wire DTO. Normalize and quote the hook fixture path, including
spaces, while retaining source-deletion and exact-binding assertions.

Verification: Hosted alert locations reproduced locally with the path-injection
and allocation queries; before/after query results and the base scan are retained
separately. Boundary regressions fail on the original head and pass with the fix.
Owning HTTP, store, config, hook, sidecar, plugin, specification and encoding suites;
full builtin/boot tests; gofmt, vet, lint and changed-file checks. Hosted Windows
and CodeQL results remain required for exact-head acceptance.
2026-10-20 01:11:52 +08:00
SivanCola 8df4882d16 fix(studio): restore opt-in visibility for the mode picker
Problem: The composer exposed the new mode picker to users who had not opted in,
contrary to the maintainer's product-visibility decision.

Root cause: Removing the persistent visibility preference also removed its
settings/search action and the RunLine mounting gate.

Fix: Restore the original on/off storage key and default-off behavior. Add the
switch and concise explanation to Persona management, restore settings search
and the action, and gate both mounting and catalog reads. Preserve card defaults,
catalog/editor design, persona copy and current conversation bindings. Failed
storage writes retain the previous choice and report an error.

Verification: Missing/disabled/unknown and toggle regressions fail before the
fix. Focused Chinese/English navigation, persistence, storage-failure and binding
tests pass. Full frontend: 729 files / 5,857 tests; build/typecheck, UI census and
ten identical fixture reports; gofmt, vet, lint, make check, builtin and boot
suites. Browser visual acceptance remains unavailable under the URL policy.
2026-10-20 00:35:37 +08:00
SivanCola 5211538354 feat(studio): give built-in personas warmer names and descriptions
Problem: Built-in preset names and descriptions read like configuration modes
rather than collaborators, and their relationship to Harness prompts was unclear.

Root cause: Technical copy was reused across the catalog, composer and persona
editor without explaining the existing short-identity prompt adaptation.

Fix: Rename the built-ins to Everyday partner and Lightweight partner, update
their bilingual descriptions and guidance, and derive the unbound picker label
from its canonical catalog definition. Keep IDs, persona bytes and selections
unchanged, retain historical translations, refresh revision metadata and document
the pinned official Harness reference and native prompt boundary.

Verification: Frontend 729 files / 5,852 tests and production build/typecheck;
contract, store and HTTP suites; gofmt, vet, lint, changed-file check, builtin and
boot suites. Fix a discovered worktree test race by waiting for the asynchronous
checkout state instead of the creation title shared by initial and checkout
phases. Browser visual acceptance remains unavailable under the URL policy.
2026-10-20 00:25:41 +08:00
SivanCola 17327b4875 feat(studio): add preset cards and explicit new-task defaults
Problem: Built-in presets use flat rows, choosing a future task mode requires
repetition, and persona fields are hidden behind an advanced disclosure.

Root cause: Management navigation and new-task launch intent have no shared
explicit preference; the editor groups basic persona fields with identifiers.

Fix: Match the selected two-column card hierarchy with badges, IDs, descriptions
and separate details, usage and copy actions. Persist an explicit built-in card
choice in a new machine-local key and inject it through the local/remote open
owners only for new tasks. Explicit request choices override it; restoring
history keeps its binding. Existing server preferences alone remain inert.
Expose both persona textareas, runtime context, scope and ID directly, rename
settings navigation to Persona, and keep literal persona fields authoritative.

Verification: Full frontend suite plus real MockHub launch effects, blank-pane
reuse, local/remote history, explicit overrides, storage compatibility/refusal,
cross-window refresh and independent footer actions. Production build/typecheck,
UI census/fixtures, format, vet, lint, changed-file and builtin/boot checks.
Browser-rendered visual comparison remains blocked by the URL policy, as
recorded in design-qa.md.
2026-10-20 00:15:23 +08:00
SivanCola 805d9d189a feat(studio): separate preset catalog and editor views
Problem: Preset browsing, creation and the Standard persona were mixed in one
long Settings page, hiding the save flow and exposing configuration too early.

Root cause: Catalog selection and editable drafts shared one inline surface,
without an owner-level guard for Settings navigation.

Fix: Follow the selected full-content editor reference. Group the catalog by
scope; open a separate editor with common fields first, expandable capabilities
and advanced options, and a persistent Cancel/Save footer. Preserve literal
persona bytes, revision checks, import/export/delete and session bindings.
Guard dirty exits across return, Settings close, category and search paths.
Keep pending saves mounted and reject stale import results. Reusable switches
declare button type so toggles cannot accidentally submit the editor form.

Verification: Full frontend suite: 727 files, 5843 tests; focused editor,
navigation, pending/refused save, import ownership and binding regressions;
production build, typecheck, UI census and fixture verification; root format,
vet, lint, changed-file checks and builtin/boot suites. Browser visual acceptance
remains blocked by the local URL security gate and is recorded in design-qa.md.
2026-10-19 23:41:23 +08:00
SivanCola b9d4dbadcc fix(studio): show the Agent mode picker by default
Problem: the mode picker required a separate settings toggle before users
could discover or use it.
Root cause: both the picker and its run-status row depended on a persistent
visibility preference unrelated to the conversation's selected mode.
Fix: render the picker directly, remove the retired setting, preference state,
search entry and action, and update the bilingual documentation. Standard
remains the default; displaying the catalog never selects a composition.
Verification: failing-first tests for absent and disabled legacy preferences;
default Standard with a saved Minimal preference; picker, settings, remote-open
and settings-search interaction suites; frontend typecheck, full suite, census,
fixture verification and build; browser preview; go vet, make lint, make check,
builtin tools and boot assembly tests.
2026-10-19 23:07:18 +08:00
SivanCola 2e2b316d86 fix(studio): address composition UI review and host archive uploads
Problem: repeated New session reset a blank pane's mode, copied built-in
descriptions ignored the window language, and identifier fields missed theme
styles. The picker was always visible and native archives were parsed in the
renderer. Unrelated transitions also repositioned every open popup.

Root cause: pane reuse resolved an unrequested default; editor styles depended
on a container the identifier row did not share; interface opt-in was missing;
archive transport carried parsed objects; placement had no anchor scope.

Fix: change a reused pane only for an explicit selection and preserve focus on
refusal, translate built-in copies, share field tokens, add a default-off local
picker switch that preserves bindings and the original hidden-state layout,
upload opaque files to the existing host decoder with typed localized errors,
keep the prior JSON envelope, and scope transitions to each popup's anchor or
container. Show catalog unavailability and wrap the editor components.

Verification: failing-first regressions; format/vet/lint/make check; all 228
root Go packages, required builtin/boot, HTTP/storage races and exact-binding
archive transport tests; Desktop/SDK; 691 frontend files and 5608 tests,
typecheck/build/census; 12 browser and eight Electron renderer scenes across
languages/themes/widths; Electron units (176 pass, one existing skip).
No authority, schema, safety policy or verification threshold is widened.
2026-10-18 23:06:07 +08:00
SivanCola 38609899ae fix(composition): preserve edit authority and mandatory safety policy
Problem: ungranted HTTP clients could mutate presets or switch compositions,
and empty hook selections could remove configured safety guards. A paired
remote pane could also borrow the host credential, and a selected native
extension could override the host's denied read.

Root cause: preset routes bypassed request-scoped edit grants, proxying erased
device authority, and frozen automation was treated as the whole safety policy.

Fix: gate preset mutations before store/admission access, refuse paired preset
writes before remote credential forwarding, overlay current authorized guards
outside retained automation, update their shared runner on live edits, resolve
hook inspection/save/approval/reload against one home, and mark bound runtime
packages tighten-only. Preserve ordinary unbound extension behavior, immutable
bindings, optional retained automation and the accepted Standard/Minimal UI.

Verification: failing-first HTTP, proxy and real boot/provider regressions;
format, vet, lint, make check, full root and required builtin/boot suites;
affected package and focused boot races; Desktop/SDK; frontend 689 files/5598
tests, typecheck/build and census; browser eight/Electron renderer four scenes;
Electron units. Correct an inherited mod fixture's premature teardown using
the existing durable-idle notification, with 20 independent process runs.
No test threshold, approval gate or product Close behavior is weakened.
2026-10-18 22:03:15 +08:00
SivanCola db1401cb5b merge: preserve remote composition selection with current Studio
Problem: Studio's shared remote-open lifecycle conflicts with the composition
callback, and the HTTP adapter omits the selected composition from its body.

Root cause: composition selection was carried by an App-local path rather than
the shared open-ordering owner and the transport serialization boundary.

Fix: merge exact Studio 5b1c282fed, extend
useOpenRemotePane and SseHub with the selection, preserve newest-open ordering,
duplicate-click coalescing and refusal cleanup, and keep editor styles with
their existing catalog stylesheet without widening the shared CSS budget.
Align the child-effort effect assertion with Studio's concrete dispatch model
and effort reporting while retaining provider, refusal and transcript checks.
Keep Standard/Minimal cards, the mode-only left trigger and right run state,
default-off semantics and all existing source/workspace authorization gates.

Verification: failing-first remote Hook/HTTP body regressions; format, vet,
lint, make check, full root and required builtin/boot tests; affected package
and focused boot races; Desktop/SDK Go; frontend typecheck, 689 files/5598 tests
and build; census fixtures; browser eight and Electron renderer four scenes;
Electron unit suite (176 pass, one existing skip). Local review/security review
does not replace maintainer approval or hosted CI.
2026-10-18 21:05:02 +08:00
SivanCola d5cee35e81 merge: preserve composition authority across current Studio session moves
Problem: current Studio conflicts in the state-root inventory and adds a move
path that strips the system message containing an immutable composition binding.
That could silently reopen a bound conversation with ordinary capabilities.

Root cause: cross-project adoption intentionally omits project instructions and
permissions, but the new mover did not distinguish immutable composition metadata
from an ordinary system prompt.

Fix: normally merge exact Studio0363720bd. Retain both rules and agent-presets
state roots. Refuse bound conversations in the common MoveSession owner before
copy/delete, preserve the source, and project the typed refusal with bilingual
HTTP wording. Keep ordinary unbound moves, ACP authentication/new-conversation
contracts, directory grants, exact dispatch inheritance and the accepted mode UI.
The preceding source-authority fix remains intact.

Verification: failing-first store and HTTP move tests now refuse blank/started
bound moves and retain the original. All226 root packages pass: mandatory2 plus
the inventoried other224; boot340.765s. Affected race suites pass. The full boot
race invocation previously reached its10minute aggregate limit; final evidence
uses one compiled source snapshot and four disjoint groups covering all753
tests exactly once, without raising the timeout. Static gates, Desktop/SDK,
frontend675files5489tests/typecheck/build/census and browser8/native4 scenes pass.
Local review/security review recorded separately from required maintainer review.
2026-10-18 18:34:12 +08:00
SivanCola 78e164b54c fix(composition): refuse project-controlled launch overrides
Problem: selecting a repository preset could change an already authorized MCP
server's package arguments or destination and reuse its executable authority or
credentials. The same provenance issue applies to extension args and env.

Root cause: composition parameter validation checked shape and credential
references but did not distinguish repository declarations from personal ones.
Pinning an executable does not authorize the program selected by its arguments.

Fix: enforce source authority in the shared contract. Project MCP/extension
parameters allow only supported timeouts. Validate declarations, imports, old
revisions, and both definition/resolved halves of retained executable bindings.
Keep structural history validation separate so legacy unsafe bindings remain
readable without regaining execution. Align Mock save/import, document the source
table in both languages, and add the release note. Preserve Standard/Minimal,
unbound defaults, persona, additional directories and exact dispatch bindings.

Verification: failing-first boot tests prove changed args start a subprocess and
changed URL contacts another endpoint before the fix; both now refuse before
startup. User positive controls, scope/parameter table, store/revision/old-record
and event-log history tests pass. Format/vet/lint/makecheck, required builtin/boot,
full root, contract/store/sessionstore/serve/ACP race, Desktop/SDK Go and frontend typecheck/build pass;
671 frontend files / 5472 tests pass. Local review/security review recorded;
maintainer approval and new-head hosted CI remain separate requirements.
The full boot race invocation reached its existing aggregate 10-minute limit
as another test started; disjoint test-list groups are used to finish the whole
inventory without raising that timeout or skipping tests.
2026-10-18 17:42:48 +08:00
SivanCola c6a421a97f merge: integrate landed persona and current Studio contracts
Problem: Agent compositions still carried the persona prerequisite diff and
missed newly added session lifecycle contracts on Studio.

Root cause: the branch predated the landed persona, ACP additional directories
and project-dispatch assembly paths. Combining their independent additions
also exceeded existing file/scalar-state budgets.

Fix: normally merge Studio 896552483 after verifying #13588 actually landed.
Resolve the Persona/composition imports and keep one ACP SessionParams owner.
Clone vetted extra directories through composition switches. Pass the exact
private binding into dispatched runtime assembly; reject cross-workspace
bindings before opening, and reject fresh assembly errors without a history
fallback. Ordinary unbound dispatch remains unchanged. Extract the command
catalog and Mock memory projection, and place the MCP guard with catalog
refresh state. No budget baseline is raised.

Keep Standard/Minimal cards, the left mode-name-only picker, right run status,
default-off/unbound Standard behavior and the landed user-config persona.
Update bilingual behavior/API documentation and release notes.

Verification: format, vet, lint, make check, required builtin/boot tests, full
root count1 atomic-coverage tests, the complete CI race package group, Desktop
and SDK suites; frontend typecheck/build and 667 files / 5443 tests. Electron
unit176 pass with one existing skip. Browser8 and Electron4 controlled rendering
scenes cover locale/theme/width, selection, mode cards, locked/new flows and
left/right layout. Real HTTP requests match landed Studio byte-for-byte with
user persona29139 bytes and empty persona29110 bytes, with fixed probe PATH.
ACP/dispatch regressions fail before propagation and pass afterward. Local
review and security review cover MCP contracts and dispatch/ingress authority.

Known local gate: make coverage-gate reports the untouched macOS computer
package at88.2 below89.8. The exact command on landed Studio reproduces the
same result and uncovered lines. No floor is lowered; hosted Linux gates
remain required. Hosted results for this new head are reported separately.
2026-10-18 15:23:19 +08:00
SivanCola f3930c0c7f fix(composition): require explicit selection for session presets
Problem: default selections bound every new session and migrated the user's
persona, changing the ordinary path and making downgrade impossible.

Root cause: entry points manufactured a selection, persona settings were
adapted into the preset store, and blank unbound rewrites were not persisted.

Fix: keep unselected and Standard sessions unbound, preserve the user persona,
require explicit non-Standard selection, and restore durable state on failed
publication from either origin. Reuse the corrected persona parent, preserve
Standard/Minimal cards and the compact unified picker, and remove committed
composition captures. Freeze both skill discovery paths without copying locks.

Verification: root Go suite, vet, lint, make check, Desktop/SDK suites, Electron
unit tests and focused frontend suites pass. Real Build HTTP bytes match the
persona parent; its original reader can continue a new unbound transcript.
Project authorization, rollback and skill discovery regressions pass.
2026-10-18 09:45:52 +08:00
SivanCola 525d397009 feat(studio): offer Standard and Minimal Agent modes
Problem: the shipped catalog and composer exposed more mode choices and status
badges than the requested Standard/Minimal workflow needs.

Fix: ship two native compositions, with a full-configuration Standard mode
and a terminal/image Minimal mode using a concise persona. Preserve retained
bindings and report retired defaults explicitly. Separate built-in cards from
custom presets, keep only the mode name in the trigger, and place run status
at the right. Keep source/lock details in the accessible label and menu.

Verification: gofmt, go vet, make lint/check, required boot/builtin tests,
complete root and Desktop Go suites, frontend typecheck/build and 5,343 tests.
Provider-boundary and custom read-only fixtures retain capability-denial
coverage. Browser checks cover light/dark, 1440px/390px and locked controls.
2026-10-18 00:28:15 +08:00
SivanCola f2e2f1f460 feat(studio): unify Agent presets in the composer status row
Problem: Session composition controls competed with task actions in the
bottom toolbar, and the adjacent ellipsis did not explain how to manage
presets.

Root cause: Composition selection and management were rendered as separate
controls below the input. Floating menu placement also missed fold changes
published after window resize and the end of layout transitions.

Fix: Place one Agent presets menu beside the run status, show sources and
capability notes, and group management below a separator. Preserve locked
bindings and explicit new-conversation actions. Reuse the existing Picker
with per-choice action identities, disabled-row keyboard navigation and
current-state semantics; refresh shared floating anchors after reflow.
Update bilingual guides, release notes and before/after screenshot evidence.

Verification: All 633 frontend test files / 5,225 tests pass, including
selection/management, keyboard focus, pending/failure, lock/new-session,
source identity and responsive positioning regressions. Typecheck,
production build, gofmt, go vet, make lint, make check, and required
boot/builtin suites pass. Browser light/dark, wide/390px and resize recovery
were verified with synthetic fixtures.
2026-10-18 00:01:26 +08:00
SivanCola 9717c4ff2c fix(session): preserve composition admission and idle handoffs
Problem: an admitted turn could fail before adding its user message and unlock
its composition. Controller-owned continuations could strand ACP config changes,
and MCP disconnect could remove code needed by a subsequent reconnect.

Root cause: the started latch followed message insertion, ACP drained only its
own prompt returns, and connection cleanup owned session package resources.

Fix: durably latch composition admission before executing or acknowledging a
turn and refuse work while the latch is pending. Notify owners at real idle
transitions and drain ACP changes through its existing serialization domain.
Separate transport state from package lifetime, retain script sibling bundles,
exclude VCS metadata, reject linked transcript exports and freeze late tool names.
Add ACP exact-binding/history tests, actual old-reader evidence, bilingual notes
and the complete light/dark wide/390px before-and-after screenshot set.

Verification: deterministic async/sync admission and failed-save regressions,
ten staged background-continuation/config-switch runs, real MCP reconnect cycles,
shared lifecycle race tests, package coverage, vet, lint and repository checks.
Frontend full suite and independent Desktop/SDK/Electron suites remain green.

Refs: #13613
2026-10-17 19:36:35 +08:00
SivanCola 4fe345ec44 feat(studio): bind immutable Agent compositions to sessions
Problem: Studio persona settings cannot select an independent tool and module
combination for each conversation, or preserve that combination across reloads.

Root cause: discovery and runtime construction follow mutable shared configuration
without a versioned session composition or a shared admission boundary.

Fix: introduce versioned scoped definitions, retained resources and authoritative
session bindings. Assemble isolated runtime selections, enforce tool ceilings,
pin MCP contracts, and share the lifecycle gate with first-prompt admission.
Expose independent HTTP, CLI, ACP and Studio management and selection controls,
with migration, native import/export, diagnostics and read-only history recovery.

Verification: composition mechanism tests, provider-wire cache tests, lifecycle
rollback tests, sensitive-boundary regressions, frontend typecheck and all 5,219
frontend tests; gofmt, vet, lint and repository checks. Browser light/dark wide
and 390px screenshots and real Electron backend interactions are included.

Refs: #13588
2026-10-17 19:09:49 +08:00