Commit Graph

9795 Commits

Author SHA1 Message Date
SunnyShu
796b6fcdcf fix(agents): drop orphaned thinking blocks when NO_REPLY text leaves an assistant message with only thinking content (#99620) (#99772)
* fix(agents): drop silent reasoning-only replay turns

Prevent NO_REPLY cleanup from leaving signed reasoning that merges into the next assistant tool-use turn and bricks strict-provider sessions.

Related: #99620

Co-authored-by: SunnyShu <shu.zongyu@xydigit.com>

* docs: refresh transcript hygiene map

Regenerate the docs map after documenting silent reasoning-only replay cleanup.

Co-authored-by: SunnyShu <shu.zongyu@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-21 00:34:15 -07:00
Peter Steinberger
40f28f8e81 feat(nodes): make computer.act eligibility capability-based for desktop nodes (#112107) 2026-07-21 00:04:04 -07:00
Peter Steinberger
c5254f13ee refactor(cli)!: remove automatic gateway→embedded fallback from openclaw agent (#112074)
A Gateway timeout or closed connection now fails the command with an
actionable stderr hint instead of silently re-running the whole turn
embedded under a fresh gateway-fallback-* session. The silent fallback
could double-execute side effects (the Gateway may still finish an
accepted turn), returned context-free answers to --session-key callers,
and ran with the CLI host's local config. --local remains the only
embedded execution path.

Also deletes the resultMetaOverrides plumbing (the fallback was its only
writer) and the fallback marker fields added in #111645.
2026-07-20 23:30:37 -07:00
Peter Steinberger
b4e27f8b3d refactor: move provider transports into packages/ai behind a typed host port (#111669)
* refactor(ai): invert plugin coupling behind the transport host port

* fix(ai): queue custom transport registrations until the host is configured

* refactor(ai): remove relocated transport sources from src/agents

* fix(ai): source core stream types from canonical packages and fix tarball fixtures

* fix(ai): invert plugin transport host wiring

* fix(ai): harden managed transport projection

* test(ai): register synchronous stream in transport mock

* fix(ai): lazily install transport runtime host

* fix(ai): preserve completion compat detection
2026-07-20 23:26:00 -07:00
Peter Steinberger
be5e427f56 feat(dashboard): plugin-declared widget data bindings and action verbs (#112083)
* feat(dashboard): add plugin capability declarations

* docs(dashboard): describe plugin capabilities

* fix(plugins): preserve registry map cloning

* fix(dashboard): make plugin grant ids unambiguous

* fix(dashboard): align generated plugin grant ids

* chore(boards): internalize verb ids and refresh protocol snapshots
2026-07-20 22:43:04 -07:00
Peter Steinberger
78b49f3a05 docs: refresh stale cua-driver claims (cross-platform prerelease, real MCP tool names) 2026-07-20 22:18:21 -07:00
Peter Steinberger
6ef6c9a15d fix(onboard): verify imported and local inference (#112028) 2026-07-20 21:35:22 -07:00
Peter Steinberger
d9cf85fa43 fix(cli): correct optional plugin guidance (#112019) 2026-07-20 21:31:30 -07:00
Jason (Json)
8968e955f7 fix(plugins): restore external runtime imports (#112021)
* fix(plugins): restore external runtime imports

* fix(plugins): support synthetic runtime builds

* test(plugins): type synthetic runtime plan
2026-07-20 21:45:23 -06:00
Peter Steinberger
2bb6b870aa fix: preserve Codex-bound conversation history across session rotation (#112016)
* fix: preserve Codex conversation bindings

* test: harden Codex live gateway stress

* chore: refresh plugin SDK API baseline

* test: tighten restart recovery fixtures

* test: complete restart recovery recorder fixture

* fix: keep plugin command authorization fail closed

* fix: restore private queue source imports

* fix: keep private SDK imports inside core

* fix: keep speech core on private SDK paths

* fix: stage private SDK exports for live tests

* fix: preserve plugin-bound gateway history

* fix: block transcript writes after binding races

* test: complete live stage helper contracts

* test: align binding mocks with current types

* fix: preserve compiler OOM diagnostics

* chore: move release notes to PR context
2026-07-20 19:42:56 -07:00
Peter Steinberger
b61619e03c fix(gateway): dev mode suppresses ambient channel env auto-configuration (#112011)
Channel plugins declare package env triggers in manifests, and ambient
environment variables count as "channel configured". A dev gateway
(gateway run --dev) inherits the operator's shell, so real channel
credentials silently configured channels and could connect development
instances to live services (observed with reef and a Telegram-range
connection during isolated stress testing).

Dev mode now drops presence signals whose only sources are env or
manifest-env across activation planning, auto-enable, autostart, health
recovery, readiness, reloads, and startup warnings. Explicit
channels.<id> config still works, --dev-ambient-channels restores the
old behavior, and startup logs the suppressed channel ids once. Non-dev
gateways are unchanged.
2026-07-20 19:28:07 -07:00
Peter Steinberger
64607ba63d feat: show cloud workspace conflicts in the Control UI (#111329)
* feat(ui): surface cloud workspace conflicts with staged-ref guidance

* fix(ui): satisfy workspace conflict CI checks

* fix(ui): reject terminal controls in conflict paths

* chore: keep release notes out of the PR

* fix(ui): satisfy conflict path lint

* fix(ui): retain cloud conflicts after reclaim

* fix(ui): keep child conflict badges visible

* test(ui): cover cloud conflict recovery in browser

* fix(ci): rotate poisoned dependency snapshot

* fix(ui): keep nested cloud conflicts discoverable

* docs(changelog): note cloud conflict UI

* fix(ui): restore conflict UI budget headroom
2026-07-20 19:27:19 -07:00
Peter Steinberger
e3488e1d73 fix(setup): preserve invalid config during baseline setup (#112010) 2026-07-20 19:15:51 -07:00
Jason (Json)
7b683b0792 fix(bootstrap): let users name new agents (#112009) 2026-07-20 20:12:59 -06:00
Peter Steinberger
3d841472bd fix(cli): align configure and channel wizard behavior (#111720) 2026-07-20 18:22:57 -07:00
Peter Steinberger
f06b6be182 feat(macos): manage Gateway profiles and multiple windows (#111986)
* feat(macos): manage gateway profiles and windows

* fix(macos): preserve gateway settings localization

* fix(deps): update axios past security advisory
2026-07-20 18:10:02 -07:00
Josh Avant
33720886c8 fix(agents): keep sender-scoped tools in delegated runs (#110345)
* fix(agents): preserve requester policy across delegation

* fix(agents): keep policy types internal

* test(codex): cover delegated policy forwarding

* fix(agents): harden delegated policy contract

* fix(agents): preserve split-owner completion policy

* fix: version delegated requester snapshots

* fix: refresh delegated policy protocol artifacts
2026-07-20 19:42:06 -05:00
Omar Shahine
e27e2d08fd feat(policy): check authored message routing (#111087)
* feat(policy): check authored message routing

* fix(policy): normalize routing probe comparisons

* Policy: keep routing evidence types internal

* Docs: refresh policy map

---------

Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
2026-07-20 17:31:29 -07:00
Peter Steinberger
49ff6a4497 fix(protocol): classify system agents in rosters (#111920)
* fix(protocol): classify system agents in rosters

* fix(ci): align agent kind client gates

* fix(ci): keep roster filtering in startup bundle

* chore(ui): remove superseded roster module

* style(android): satisfy agent kind test formatting

* style(linux): format merged agent capability assertion

* fix(config): reject reserved system agent ids

* chore(i18n): refresh native source inventory

* style(android): format agent kind surfaces

* fix(gateway): preserve configured agent ownership
2026-07-20 16:57:04 -07:00
Peter Steinberger
7cafe35bd5 fix(onboard): never silently remap an existing fleet's workspaces (#111787)
* fix(onboard): preserve agent workspaces on rerun

* fix(onboard): preserve first-run workspace setup
2026-07-20 16:16:04 -07:00
Peter Steinberger
a52eb2134b feat(apps): connect multiple gateways simultaneously (#111932)
* feat(apps): support simultaneous gateways

* fix(apps): satisfy multi-gateway checks

* chore(apps): refresh multi-gateway baselines

* style(android): format gateway fleet code
2026-07-20 13:06:29 -07:00
Peter Steinberger
ba3711bb82 feat(linux): render widgets in Quick Chat (#111933) 2026-07-20 11:56:03 -07:00
Shakker
49aa383dd7 fix: consume ClickClack v1 setup claim contract (#111927)
Support ClickClack v1 setup claim URLs for split-origin and path-mounted deployments while preserving legacy setup flows and private transport overrides.

Refs #111919.
Prepared head SHA: c13ce82e38
Co-authored-by: Shakker <165377636+shakkernerd@users.noreply.github.com>
Reviewed-by: @shakkernerd
2026-07-20 18:50:30 +01:00
Peter Steinberger
324fd4fe6e refactor(channels): delete all media-placeholder consumer awareness (#111891)
Final sweep of the media-placeholder program: with all eleven producers
migrated, the consumer regexes are dead input and are hard-deleted —
media-understanding token un-mixing (bodies are pure user text now),
the persisted-user-turn placeholder drop, the session-memory strip, and
the inbound-event mediaPlaceholder field with its replacement branch
(an intentional removal of shipped SDK surface per the program's
hard-delete decision: plugins still minting placeholder bodies render
them as literal text until updated). formatMediaPlaceholderText remains
the single owner of the <media:kind> vocabulary, used only for
text-only carriers. Legacy tokens in pre-migration history remain
ordinary text.
2026-07-20 09:31:51 -07:00
Peter Steinberger
96ffdf15c7 docs(web): user guide for session dashboards (#111834)
* docs(web): user guide for session dashboards

* docs: format dashboards page
2026-07-20 08:23:14 -07:00
Peter Steinberger
154a49a78b feat(dashboard): widget capabilities — net CSP, host tools, hardened shared sandbox (#111687)
* feat(boards): enforce widget capability grants

* feat(ui): expose dashboard widget capabilities

* test(dashboard): align rebased gateway contracts

* refactor(dashboard): finish capability alignment

* chore: internalize unused board sandbox exports

* test(dashboard): bind grants to widget instances

* fix(dashboard): close widget authority lifetime gaps

* refactor(ui): preserve modular widget frame ownership

* test(ui): preserve explicit MCP App lease refresh

* test(ui): use shared dashboard sandbox server

* fix(ui): settle widget requests on reconnect

* fix(ui): retry transient widget document loads

* refactor(dashboard): document WebRTC egress residual

* fix(dashboard): clear landing checks
2026-07-20 06:54:44 -07:00
Peter Steinberger
8bec61bab1 fix(cli): reject unknown models in config set (#111571)
* fix(cli): validate configured model references

* fix(cli): cover dependent model references

* fix(cli): reject malformed model references

* test(cli): satisfy model validation gates

* fix(cli): harden model validation drafts

* fix(cli): preserve model runtime ownership

* fix(cli): validate expanded model references

* fix(cli): close model validation gaps

* fix(cli): preserve model alias ownership

* fix(cli): secure model validation context

* fix(cli): redact expanded model references

* fix(cli): validate inherited agent catalogs

* fix(cli): align canonical model resolution

* fix(cli): scope inherited catalog validation

* fix(cli): compare resolved model snapshots

* fix(cli): cover model dependency transitions

* fix(cli): isolate model env validation

* fix(cli): redact dependent model checks

* fix(cli): compare agent model identity

* fix(cli): validate expanded model removal

* fix(cli): defer unresolved fallback validation

* fix(cli): preserve authored model changes
2026-07-20 03:31:03 -07:00
Peter Steinberger
7fe1d70a50 fix(mcp): prevent custom server config races and parsing errors (#111761)
* fix(mcp): harden custom server management

* fix(ui): keep config patch types private
2026-07-20 02:34:13 -07:00
Peter Steinberger
473f2aca33 fix(gateway): honor session title model routing (#111757)
Route automatic dashboard titles through the effective session model and auth profile while preserving explicit cross-provider utility ownership and the existing generic title fallback.
2026-07-20 02:19:57 -07:00
Peter Steinberger
9056c43368 docs(gateway): add client-building and embedding guides (#111726)
* docs(gateway): add client-building and embedding guides

* docs(gateway): harden package rollout guidance
2026-07-20 02:12:52 -07:00
Peter Steinberger
fd081d6521 fix(ui): keep Codex commentary visible after runs (#111648)
* fix(ui): keep Codex commentary visible

* fix(codex): preserve commentary transcript ordering

* fix(ui): preserve commentary retention opt-out
2026-07-20 02:10:56 -07:00
Peter Steinberger
343cfba638 fix(clickclack): private API base for gated hostnames and single discussion-provider registration (#111724)
* fix(clickclack): split API base and refresh discussion provider

* chore: regenerate bundled channel config metadata and docs map for the apiBaseUrl key
2026-07-20 01:27:13 -07:00
Peter Steinberger
248726fafd feat(anthropic): import Claude Desktop custom groups (#111644)
* feat(anthropic): import Claude Desktop custom groups

* fix(anthropic): resolve Claude Desktop groups from LevelDB entries

Group discovery regexed whole decompressed blocks, so matches were not
attributable to a Local Storage value and byte order decided the winner.
On a real 5.4MB store that mislabelled 59 of 159 sessions, surfacing a
mojibake label spliced out of Snappy copy-record bytes.

Parse SSTable entries properly instead: prefix-delta keys bounded by the
restart array, newest internal sequence per user key (honoring deletions),
and record scanning confined to a single value. Values are normalized so
Chromium's UTF-16 form scans like Latin-1, and unflushed WAL writes keep
precedence over SSTables.

Prod LOC grows ~77; it buys structural correctness in place of ordering
luck, and folds the old index-only walk into one shared entry decoder.

Verified against the live store: 159 assignments, 0 mislabelled versus an
independent entry-level ground truth, 0 control-character labels.

* fix(ui): sort custom session groups ahead of project groups

Custom groups were pushed into the section list as encountered, so their
position depended on roster order rather than the documented behavior;
the existing test only passed because its fixture happened to be ordered
that way. Collect custom and project groups separately and concatenate,
and assert the guarantee with a reversed-input case.

* fix(anthropic): widen LevelDB fixture key type for test typecheck

The prefix-delta helper assigned a Buffer into a Buffer-typed accumulator
whose generic argument differed, which tsgo rejects in the test lane.

* chore(anthropic): drop release-owned changelog edit from the PR

CHANGELOG.md is generated at release time, so a normal PR must not carry
an entry. The release-note context lives in the feature commit message and
the PR body instead.
2026-07-20 00:30:37 -07:00
Peter Steinberger
46ceb21b89 fix(control-ui): keep OpenClaw in settings (#111686) 2026-07-20 00:00:23 -07:00
Peter Steinberger
250e636ffd fix(onboard): reject invalid setup options before writes (#111680)
* fix(onboard): validate setup options before mutation

* fix(onboard): keep flow helper type local
2026-07-19 23:05:23 -07:00
Peter Steinberger
bc76bb8933 feat(agents): agent-controlled session status, attention, and TTL in the sessions tool (#111583)
* feat(agents): agent-controlled session status, attention, and TTL in the sessions tool

* feat(protocol): sessions.patch agent status fields and curated attention icon ids

* chore(protocol): regenerate bindings for agent-status patch fields, unexport internal cap

* chore(sessions): unexport internal agent-status TTL default
2026-07-19 21:01:09 -07:00
Peter Steinberger
200653bd60 fix(gateway): generate dashboard titles despite sender metadata (#111613)
* fix(gateway): keep sender identity out of session titles

* docs(changelog): note dashboard session title fix

* test(gateway): type dashboard sender fixture

* docs: keep session title release note in PR
2026-07-19 20:26:28 -07:00
Peter Steinberger
6d39d3cf0b fix(onboard): preserve gateway settings on rerun (#111569)
* fix(onboard): preserve gateway config on rerun

* fix(onboard): scope remote secrets to endpoint

* fix(onboard): honor rerun override boundaries

* fix(onboard): secure inherited tailscale auth

* fix(onboard): honor explicit token auth

* fix(onboard): enforce funnel auth on rerun

* fix(onboard): preserve env password on rerun
2026-07-19 20:18:34 -07:00
Peter Steinberger
7d4dccf959 improve(swarm): close out wait, phase, and worker follow-ups (#111605)
* fix(codex): support full swarm wait budgets

* feat(ui): bucket swarm dots by phase

* docs(swarm): document flat worker patterns

* fix(codex): configured per-tool timeout still wins over swarm wait default

* fix(codex): outer swarm-wait watchdog outlives the 600s budget (cap + grace)

* fix(ui): order swarm phase buckets by observation rank

* fix(ui): repair rank-order widget test — proper lit render container, untangle sibling assertions

* fix(ui): implicit swarm phase assignment only on child creation events

* test(ui): split swarm activity integration coverage
2026-07-19 20:11:54 -07:00
Peter Steinberger
e0b1a39d2a improve(i18n): generate native locales after merge (#111557)
* ci(i18n): move native locale generation post-merge

* fix(i18n): allow generated Android companions
2026-07-19 15:42:41 -07:00
Peter Steinberger
bcbbf28093 docs(plugin-sdk): migrate retained SDK contracts (#111535)
* refactor(plugin-sdk): finish retained public demotions

* test(plugin-sdk): tighten surface budgets

* fix(plugin-sdk): retain static tool metadata contract

* fix(plugin-sdk): keep retained exports pending

* fix(plugin-sdk): satisfy registry lint

* docs(plugin-sdk): document retained consumer seams
2026-07-19 15:00:45 -07:00
Marcus Castro
b887cd01d8 fix(whatsapp): use canonical media primitives (#107017)
* feat(media): forward outbound image optimization

* feat(media): support bounded Opus transcoding

* refactor(whatsapp): reuse canonical outbound media helpers

* refactor(whatsapp): reuse canonical base64 validation

* chore(plugin-sdk): refresh API baseline
2026-07-19 18:54:14 -03:00
Peter Steinberger
5420c5c409 feat(clickclack): session discussions — bound channels, side agent, lifecycle sync (#111503)
* feat(clickclack): add session discussions

* chore: remove release-owned changelog entry

* refactor(clickclack): split discussion service workflows

* fix(clickclack): satisfy plugin surface gates

* fix: narrow routing peer in inbound test and refresh docs map
2026-07-19 14:47:14 -07:00
Peter Steinberger
171a3852ba fix: install exact app recommendations and retry failures (#111518)
* fix(onboard): preserve recommendation install retries

* fix(onboard): preserve bootstrap recommendation retries

* fix(onboard): commit recommendation outcomes after config

* fix(onboard): guard recommendation state transitions

* fix(onboard): reconcile durable skill installs

* docs(clawhub): clarify search publisher contract
2026-07-19 14:10:50 -07:00
Peter Steinberger
13ed8b5aa1 perf(state): cap the per-agent SQLite handle cache with LRU eviction (#111411)
* perf(state): cap the per-agent SQLite handle cache with LRU eviction

Multi-tenant hosts open one WAL database per agent (~3 file descriptors
each); the process-local handle cache was unbounded, so large fleets
exhausted descriptors. Cache hits now refresh LRU recency, and cache-miss
opens evict the oldest non-transactional handle before constructing the
new one, capped at 64 open handles. Eviction closes the process-local
handle only; registry rows and durable data are untouched and evicted
databases reopen transparently on next access.

* fix(state): fleet-wide introspection reads stop opening writable agent databases

Live testing an 81-agent gateway surfaced three full-fleet sweeps that
opened every agent's SQLite database writable (schema ensure + registry
write transaction per open): the 60s health snapshot's per-agent session
summaries, usage-cost cache reads behind the gateway usage endpoints, and
the zalouser doctor detector that ran from every CLI startup. Each sweep
churned the new bounded handle cache and saturated the event loop.

Session listing gains a readonly non-registering variant (SDK exposes it
as an additive readOnly flag on listSessionEntries); health and usage
reads use it, with transient-lock tolerance owned by the health caller.
The zalouser detector gates on the channel/credentials actually existing,
collects once per pass, and detection reads go readonly while migration
apply stays writable. The usage refresh queue's flat 50ms busy retry
becomes exponential backoff capped at 5s, and refreshing summaries retain
their cache timestamp so the 30s TTL gates fleet rescans.

* perf(state): make per-agent handle eviction and reopen cheap

Eviction only works if reopen is cheap. Reopens after eviction previously
repeated full first-open work; ensureOpenClawAgentSchema takes BEGIN
IMMEDIATE and the registry upsert writes the shared state DB, so reopens
blocked in synchronous busy waits (observed 14-22s event-loop stalls with
reconcile workers holding write transactions). Owner/schema validation and
registration now run once per path per process with invalidation on
quarantine and disposal; the read-only integrity guard still runs on every
physical open. Eviction closes with a PASSIVE WAL checkpoint instead of
TRUNCATE, which waits on readers; orderly dispose keeps TRUNCATE so
sidecars are flushed before unlink.

* ci: regenerate plugin-SDK API baseline, drop prod test-seam exports, mock readonly accessor

The additive readOnly flag on the SDK listSessionEntries changed the
declaration surface, so the generated API baseline is regenerated via the
sanctioned script. Knip forbids production exports consumed only by tests:
the usage-cache testApi export is removed outright and the refresh-queue
seam moves behind an env-gated global exposed by a test-support module.
health.plugins.test's full session-accessor mock gains the newly imported
readonly listing.
2026-07-19 13:58:01 -07:00
Peter Steinberger
1a574923cb fix(onboard): honor remote flags in interactive setup (#111517)
* fix(onboard): honor interactive remote flags

* fix(onboard): clear credentials for changed gateway

* fix(onboard): validate remote URL before probe

* test(onboard): mark synthetic remote tokens

* test(onboard): avoid literal credential fixtures

* refactor(onboard): name remote probe auth role

* refactor(onboard): keep remote probe seed canonical

* test(onboard): type remote URL validator mock
2026-07-19 13:25:46 -07:00
Marvinthebored
22c336c0b4 fix(plugins): load active generation after upgrades (#111141)
* fix(plugins): load newest managed generation when a prior install lingers

An upgrade writes a plugin's new version into a distinct managed project
directory (an `__openclaw-generation__` dir) without removing the previous one.
The persisted install record keeps pointing at the older, still-present
directory, so `mergeRecoveredManagedNpmRecord` falls through to returning the
persisted record and the runtime imports the stale version even though the newer
generation is installed. `isUnavailableManagedNpmInstallRecord` only self-heals
when the persisted path is gone, so an upgrading install (both directories
present) is not covered — `plugins inspect <id> --runtime` reports the old
version and `install`/`update` appear to silently no-op.

- Recovery now selects the highest-version record per plugin id across the
  legacy flat dir and any generation dirs, instead of whichever project root
  sorts last (generation-dir suffixes are hashes, so on-disk order is unrelated
  to version).
- When the recovered managed install is a strictly newer version at a different
  path, repoint to it, reusing the metadata merge the unavailable-path branch
  uses. The repoint is gated to persisted records that live inside the managed
  npm root, so intentional custom/outside npm installs are left untouched.

This is a recovery-layer self-heal, so it also repairs installs that already
diverged from an earlier upgrade.

Refs #107228

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(plugins): honor active managed generations

Recover ambiguous managed installs by package recency only when no usable active ledger path exists, and let doctor retire non-authoritative generations safely.

Co-authored-by: Peter Lindsey <peter@lindsey.jp>

* test(plugins): use shared temp cleanup

* fix(plugins): compare active paths per platform

* fix(plugins): use managed install timestamps

* test(plugins): timestamp managed project roots

* test(plugins): exclude retired legacy recovery

* refactor(plugins): keep recovery candidate private

---------

Co-authored-by: Peter Lindsey <peter@lindsey.jp>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-19 12:50:35 -07:00
Peter Steinberger
06480d767c feat(dashboard): stitch session dashboards end-to-end — live provider, show_widget pin, board commands (#111218)
* feat(dashboard): pin canvas widgets through board domain

* feat(control-ui): wire session dashboards end to end

* fix(control-ui): preserve direct reset confirmation

* fix(control-ui): localize dashboard default tab

* test(dashboard): satisfy changed typecheck gate

* fix(dashboard): satisfy changed lint gate

* fix(dashboard): harden pinned widget lifecycle

* fix(dashboard): use extracted mock normalizer

* test(dashboard): reconcile hardened board admission tests

* fix(dashboard): align grant and canvas protocol requests

* fix(dashboard): preserve refresh and pin invariants

* fix(boards): treat missing board tables as empty on read-only paths

* fix(boards): accept read-only handles in board table probe

* fix(control-ui): preserve virtual board widget types

* fix(dashboard): align view types with protocol

* fix(dashboard): keep resolved board view typed

* chore(canvas): drop test-only html read wrapper

* chore(release): defer dashboard note generation

* fix(protocol): align board widget put params type

* fix(control-ui): preserve queued reset approval

* fix(control-ui): gate dashboard pinning capability

* chore(test): isolate dashboard capability fixture

* fix(control-ui): refresh dashboard pin affordance
2026-07-19 12:36:54 -07:00
Peter Steinberger
31e52dc5c5 feat(gateway): allow explicit operator.admin in device auto-approval with critical audit finding (#111509) 2026-07-19 12:05:04 -07:00
Peter Steinberger
163a6c6e16 fix(agents): declare visible-session constraints upfront in sessions_spawn (#111502) 2026-07-19 11:42:05 -07:00