Commit Graph

4418 Commits

Author SHA1 Message Date
Yuval Dinodia
c17a81b470 fix(plugins): roll back cleared runtime registrations when an activating reload aborts (#103812)
* fix(plugins): roll back cleared runtime registrations when an activating reload aborts

loadOpenClawPlugins clears the process-global agent-harness, plugin-command,
compaction, detached-task, interactive-handler, embedding, memory-embedding,
and memory stores up front on an activating load and only re-registers them at
the end via activatePluginRegistry. The body has a finally with no catch, so a
throw during discovery or manifest load (a corrupted or half-written plugin
manifest mid-upgrade) leaves the previously active registry marked active while
its runtime stores are gone process-wide; the gateway reload driver only logs
and swallows the error.

Snapshot the process-global stores before the clear with the existing
snapshotPluginProcessGlobalState helper and restore them on any throw before
activation. clearActivatedPluginRuntimeState moves next to the snapshot and
restore helpers it pairs with in plugin-registration-transaction.ts, which
already owns atomic plugin registration state and imports from every module the
clear touches; loader.ts re-exports it so existing callers are unchanged.

* fix(plugins): make reload rollback activation-safe

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 18:11:16 -07:00
Peter Steinberger
6c2973dee4 feat(ui): automatic session attention states in the sidebar (#111035)
* feat(ui): automatic session attention states in the sidebar (question, approval, failed run)

* test(ui): split attention presentation and read-marker cases under line budgets

* fix(ui): restore precise chat-pane test-support signatures
2026-07-18 17:43:59 -07:00
Peter Steinberger
b4187ced90 feat: add live-validated Zoom meeting guest plugin (#111048)
* feat(zoom-meetings): add browser guest transport

* fix(zoom-meetings): type reusable refresh result

* test(meeting-bot): bind reusable refresh callback

* chore(zoom-meetings): use existing plugin label

* chore(zoom-meetings): defer changelog to release

* test(zoom-meetings): cover node setup through public host
2026-07-18 17:17:26 -07:00
xingzhou
9b42782f76 fix(plugins): agent runs hang when tool-result middleware never settles (#110731)
* fix(plugins): prevent tool-result middleware from freezing runs

* test(plugins): cover middleware timeout policy

* test(plugins): provide hook context in timeout test

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 17:11:59 -07:00
Ted Li
10f5a7ac58 fix(groq): keep default Llama agent turns within TPM limit (#104904)
* fix(groq): recover oversized requests safely

* fix(groq): clear parallel tool aliases on fallback

* fix(groq): require provenance-aware host

* fix(groq): preserve configured request budgets

---------
authored-by: @MonkeyLeeT
Co-authored-by: Colin <colin@solvely.net>
2026-07-18 20:00:12 -04:00
Peter Steinberger
264a7b0d12 refactor(channels): consolidate manifest descriptors (#110985) 2026-07-18 23:18:28 +01:00
cxbAsDev
7bf263b8b6 Bound plugin bundle command file reads with size cap (#110594)
* Bound bundle command file reads with size cap

* fix: use buffer.toString for readRegularFileSync result

* fix: log oversized bundle command file diagnostic instead of silent skip

The catch block now captures the error and emits a console.warn with the file path and error detail, so upgrades do not silently remove oversized installed commands.

* test: verify oversized bundle command file is skipped and siblings continue

PR #110594: Add focused regression coverage:
- Test: an oversized bundle command markdown file (>1 MB) is skipped via catch + continue
- Test: normal sibling command files still load correctly
- Verifies console.warn diagnostic is emitted for the oversized file

* refactor(plugins): log rejected bundle commands

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* style(plugins): format bundle warning

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 23:03:00 +01:00
Peter Steinberger
5fe8d6a852 fix(gateway): clients can identify authorization failures (#110925)
* fix(gateway): structure authorization errors

* test(gateway): align authorization contracts

* fix(gateway): regenerate protocol bindings

* fix(gateway): preserve optional scope errors

* fix(gateway): report complete pairing scopes

* style(gateway): format protocol exports
2026-07-18 22:02:28 +01:00
Peter Steinberger
09a64f7ab0 feat(models): make per-agent allowlists explicit (#110888) 2026-07-18 21:42:05 +01:00
Peter Steinberger
5fdb0cd24e feat(chat): switch between session transcript branches from the chat header (#110857)
* feat(chat): switch between session transcript branches from the chat header

* fix(chat): type fixes and protocol regen for branch switcher CI
2026-07-18 20:06:36 +01:00
Peter Steinberger
88e5af7097 feat(ui): interleaved sidebar zone with custom session icons and drag ordering (#110682)
* feat(ui): custom session icons with agent-drawable SVG and nav-parity pinned rows

* wip: slice-2 interleaved sidebar zone (pre-review)

* fix(ui): trim icon exports, bypass protocol barrel in startup bundle, regen Swift protocol client

* fix(ui): preserve unknown-agent zone entries on writes, prune entries on any unpin

* fix(ui): reset keeps unloaded session slots; enforce SVG byte cap on canonical form

* fix(ui): archiving a pinned session retires its sidebar zone slot

* fix(ui): persist drag-pinned zone slot only after the pin patch lands

* fix(ui): recompute drop insertion against freshest zone order on pin ack

* fix(ui): consume self-drop events before the zone bailout

* docs(ui): note the non-sidebar unpin pruning contract on pruneSidebarSessionEntry

* refactor(ui): extract pure session-tree projection; drop unused zone type export
2026-07-18 17:13:09 +01:00
Peter Steinberger
3fd3ad8301 fix(ci): restore plugin prerelease validation (#110787)
* test: align plugin prerelease assertions

* test: remove stale vitest import
2026-07-18 17:00:15 +01:00
Peter Steinberger
0acece4591 feat(chat): rewind and fork a session from a message bubble (#110660)
* feat(chat): rewind and fork a session from a message bubble

* docs(web): document chat rewind and fork bubble actions

* fix(chat): lint cleanups, protocol regen, and test splits for rewind/fork CI

* fix(ui): fit chat rewind disabled styles inside the startup CSS budget
2026-07-18 14:46:34 +01:00
Peter Steinberger
9710a1339e refactor(canvas): promote inline-widget hosting and show_widget to core (#110475)
* refactor(canvas): promote inline widgets to core

* docs(agents): note discord show_widget ownership at core registration

* ci: retrigger after GitHub scheduling outage

* fix(canvas): satisfy dead-code and test type checks
2026-07-18 14:40:45 +01:00
Peter Steinberger
9d97e10efe refactor: move non-session runtime journals to SQLite (#109427)
* refactor: migrate runtime JSONL state to SQLite

* chore: refresh SQLite migration validation

* fix: preserve safe audit migration order

* fix: sanitize retired audit archives safely

* fix: satisfy SQLite storage architecture gates

* fix: serialize plugin doctor state migrations

* fix: bound memory event SQLite projections

* fix: rotate memory event projections safely

* fix: preserve imported event retention age

* fix: harden memory event export projection

* fix: canonicalize memory event migrations

* fix: harden legacy journal migrations

* fix: report unsafe legacy journal paths

* fix: preserve journal ownership during migration

* fix: keep legacy file imports doctor-only

* fix: align SQLite audit CI coverage

* refactor: keep state helpers module-private

* fix: harden legacy state migration recovery

* fix: reconcile SQLite state audit migration

* test: use neutral audit redaction fixtures

* fix: close SQLite migration recovery gaps

* refactor: split audit migration recovery helpers

* test: prove completed audit pads stay out of backups

* fix: preserve audit record ordinals across blank lines

* fix: align SQLite audit CI contracts

* build: package SQLite audit E2E entries

* fix: preserve audit ordinals in backup snapshots
2026-07-18 11:42:14 +01:00
cxbAsDev
2e21d53c84 fix(plugins): bound plugin manifest metadata file reads (#110036)
* fix(plugins): bound plugin manifest metadata file reads

* fix(plugins): use correct Error type check in oversized manifest catch

readRegularFileSync throws a plain Error (not RangeError) when the file
exceeds maxBytes. Change the catch-block type check from RangeError to
Error to properly detect oversized plugin manifests and emit the
subsystem warning.

* test(plugins): exercise valid oversized manifests

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 11:22:30 +01:00
Peter Steinberger
a068d38b66 refactor(plugins)!: remove experimental workspaces plugin (#110416)
* refactor(plugins)!: remove experimental workspaces plugin

* fix(doctor): remove retired workspaces plugin state

* refactor(doctor): settle retired-workspaces cleanup before legacy-state detect

* chore(i18n): leave workflow-owned locale artifacts to the locale refresh

* ci: retrigger after GitHub scheduling outage
2026-07-18 10:56:37 +01:00
cxbAsDev
35754a63cc fix(plugins): bound marketplace manifest file reads (#101774)
* fix(plugins): bound marketplace manifest file reads

* fix(plugins): distinguish oversized marketplace manifest from other read failures

* fix(plugins): follow symlinked marketplace manifests while bounding reads

* test(plugins): cover oversized symlinked marketplace manifest target
2026-07-18 10:34:00 +01:00
Dan Scarafoni
f40a30bb72 fix(plugins): recurring plugin-scheduled jobs silently deleted after first post-boot agent turn (#107752)
* fix(agents): skip runtime plugin reload when a registry is already active

ensureRuntimePluginsLoaded rebuilt and activated a replacement plugin
registry on every call site invocation (agent turns, cron isolated-agent
runs, the gateway prewarm sidecar). Activating a replacement retires the
active registry and runs its plugin host cleanup, which cron.remove()s
persistent plugin-scheduled session turns before the replacement's async
re-registration catches up — silently deleting the cron row with only a
low-level 'cron service unavailable' WARN. Plugins using
api.session.workflow.scheduleSessionTurn for recurring jobs lose their
schedule on the next agent turn after boot.

Guard with getActiveRuntimePluginRegistry(): when a registry is already
active every caller's request is satisfied, so return before building a
replacement.

* fix(agents): make active-registry reuse compatibility-aware, not presence-only

The original guard (1de432a9) returned early whenever ANY registry was
active, without checking whether it was actually compatible with this
call's workspace, plugin scope, config, or runtime mode. A later call
requesting a different workspace could silently keep an unrelated
workspace's registry active instead of loading its own — a correctness
and workspace-isolation issue (caught in upstream review, PR #107752).

Fix: compute workspaceDir/startupPluginIds/loadOptions first, then check
getLoadedRuntimePluginRegistry({loadOptions, workspaceDir, requiredPluginIds})
before deciding to skip — reusing the existing loader cache-key
compatibility rules (workspace, config, runtime subagent mode, required
plugin IDs) that already govern normal cache-hit reuse elsewhere. Only
skips the reload when an active registry is genuinely compatible; still
loads a fresh one otherwise.

Tests: replaced the presence-only regression test with three cases —
compatible-registry reuse (skip), incompatible/different-workspace (still
loads), and startup-scoped plugin IDs passed through to the compatibility
check. All 5 acceptance criteria from the review verified locally:
runtime-plugins.test.ts, active-runtime-registry.test.ts,
standalone-runtime-registry-loader.test.ts, and the full cron lane
(33 files / 460 tests, including run.runtime-plugins.test.ts) all green;
pnpm build completes clean (5m14s, no errors).

* fix(plugins): preserve live scheduled turns

Scope dynamic scheduler cleanup to the retiring registry owner and keep runtime workflow APIs callable while their registry remains pinned and live.\n\nCo-authored-by: Dan Scarafoni <dan@poweredbyzon.com>

* test(plugins): prove recurring cron ownership

* chore(plugin-sdk): refresh api baseline

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 09:21:50 +01:00
Dave Morin
4b3ee5e7eb feat: let agents remember across private conversations (#100140)
* feat(memory): remember across private conversations

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>

* chore(docs): regenerate config baseline

* fix(memory): restore recall configuration wiring

* fix(memory): scope recall transcript indexing

* test(memory): repair conversation recall fixtures

* test(memory): split session visibility coverage

* style(memory): format type imports

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 08:21:43 +01:00
Shakker
006d6556b8 refactor: expose selected plugin payload checks 2026-07-18 07:13:45 +01:00
Vito Cappello
cd1ab40632 fix: gateway boots when a configured plugin payload is broken (#110239)
* fix: quarantine broken plugins during gateway startup

* fix(plugins): preserve degraded boot on package read errors

* fix(gateway): emit quarantine diagnostic once

* fix(gateway): refresh plugin quarantine every boot

* fix(gateway): harden plugin payload quarantine

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* fix(ci): satisfy plugin quarantine checks

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

---------

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 03:50:50 +01:00
Peter Steinberger
d8f2645c2c refactor(memory-wiki): move compiled cache to plugin state (#110167)
* feat(plugin-sdk): prepare memory prompts asynchronously

* refactor(memory-wiki): move compiled cache to plugin state

* fix(plugin-sdk): export memory prompt preparer type

* refactor(plugin-sdk): keep prompt preparer type private

* test(memory-wiki): isolate compiled cache state

* chore(memory-wiki): satisfy changed gates

* fix(memory): preserve prepared prompts across context engines

* docs(plugin-sdk): refresh API baseline

* fix(memory): revalidate prepared prompt ownership

* fix(codex): propagate sandboxed memory context

* test(memory-wiki): seed durable vault identity

* refactor(memory-wiki): keep cache lifecycle internal

* fix(memory-wiki): harden compiled cache publication

* style(memory-wiki): format cache lifecycle changes

* test(memory-wiki): support extension test lib target

* style(memory-wiki): remove redundant catch

* refactor(memory-wiki): keep vault generation helper private
2026-07-18 03:05:03 +01:00
Patrick Erichsen
f9b860fc84 feat(plugins): order featured catalog by recency (#110273) 2026-07-17 18:06:13 -07:00
Peter Steinberger
ec8f6e5e03 feat(browser): add secure per-tab copilot panel (#109817)
* feat(browser): add copilot security contracts

* fix(gateway): expose verified client identity to handlers

* feat(browser): add secure per-tab copilot panel

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* refactor(browser): separate copilot gateway hint custody

* fix(browser): preserve legacy pairing parse shape

* fix(browser): harden copilot lifecycle custody

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): enforce copilot lifecycle boundaries

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* style(browser): format copilot sources

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): preserve copilot consent revocation

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* refactor(browser): split copilot custody owners

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(browser): normalize websocket array buffers

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* chore(protocol): regenerate Swift gateway models

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* refactor(browser): model copilot runtime entrypoints

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): honor extension build boundaries

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(gateway): assert targeted chat delivery

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(gateway): cover targeted delivery calls

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): declare copilot build dependencies

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(ci): clear browser copilot gate failures

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(ci): cover copilot lint exclusion

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): gate copilot on relay custody

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(browser): bound copilot relay frames

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

---------

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>
2026-07-18 01:00:23 +01:00
Peter Steinberger
601ffa2530 refactor(channels): move inbound turn execution into core (#110095)
* refactor(channels): centralize turn execution lifecycle

* refactor(extensions): adopt core channel turn plans

* test(channels): ratchet modern dispatch ownership

* chore(channels): drop stale max-lines exemption

* fix(channels): allow async delivery error cleanup

* test(channels): await async delivery cleanup

* test(channels): await delivery error callbacks

* fix(channels): preserve delivery error contract

* fix(plugin-sdk): preserve channel inbound declarations

* test(channels): exercise core delivery plans

* fix(channels): await delivery error cleanup

* fix(channels): preserve async cleanup contract

* refactor(channels): trim dispatch boilerplate

* fix(channels): mask observe-only dispatch results

* refactor(channels): delete unused dispatch exports

* fix(msteams): preserve resolver config overrides

* refactor(channels): keep Teams turn config internal

* test(plugins): drop retired Teams runtime export guard
2026-07-18 00:55:46 +01:00
qingminlong
07d97f6e8d fix(plugins): hide bundle commands when frontmatter uses on (#105013)
* fix(plugins): honor on frontmatter for bundle commands

* fix(plugins): honor bundle command invocation policy

Co-authored-by: qingminlong <qing.minlong@xydigit.com>

* test(plugins): tighten bundle command policy coverage

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 00:18:16 +01:00
Peter Steinberger
781913025b improve: stream native sessions as hosts finish (#110211)
* perf: stream native session catalogs by host

* fix: satisfy session catalog CI contracts

* fix: retain changed-session refresh timing

* fix: keep catalog refresh helpers private
2026-07-17 23:59:57 +01:00
tzy-17
34fec1d82b fix(plugins): handle NaN from Date.parse in catalog rollback detection (#109742)
* fix(plugins): handle NaN from Date.parse in catalog rollback detection

isHostedCatalogSignedFeedRollback compared generatedAt timestamps using
Date.parse without checking for NaN. An invalid date string in the
candidate feed would produce NaN < validNumber === false, silently
accepting the candidate instead of treating it as a potential rollback.

Now, if the candidate's generatedAt is invalid, we conservatively treat
it as a rollback. If the current feed's generatedAt is invalid, we
treat the candidate as newer (not a rollback).

* fix(plugins): handle NaN from Date.parse in snapshot store monotonic rollback

isMonotonicRollback in official-external-plugin-catalog-snapshot-store.ts
had the same NaN comparison bug as isHostedCatalogSignedFeedRollback:
Date.parse(candidate.generatedAt) < Date.parse(current.generatedAt)
returns false when either timestamp is invalid, silently accepting a
candidate that should be rejected as a rollback.

Mirror the catalog.ts fix: if the candidate's generatedAt is invalid,
conservatively treat it as a rollback; if the current snapshot's
generatedAt is invalid, treat the candidate as newer (not a rollback).

Export __testing for isMonotonicRollback and add five regression tests
covering newer/older sequence, equal-sequence timestamp comparison, and
both invalid-timestamp branches.

* fix(plugins): export rollback guards directly instead of __testing wrapper

The knip production deadcode scan flags __testing as an unused export
because test files are not entry points in that mode. Export
isHostedCatalogSignedFeedRollback and isMonotonicRollback as named
exports instead of wrapping them in __testing objects. Both are already
called from production code, so knip will see them as used.

* fix(plugins): keep rollback guards as internal functions, remove unit tests

The knip production deadcode scan flags any export that is only
referenced by test files as unused, even if the function is called
within the same source file. Both isHostedCatalogSignedFeedRollback
and isMonotonicRollback are internal helpers called from production
code in the same module, so exporting them solely for test access
triggers the check-dependencies CI gate.

Revert both functions to private (non-exported) and remove their
direct unit tests. The NaN-handling fix is still validated by the
existing catalog snapshot integration tests that exercise rollback
detection through the public API.

* fix(plugins): remove stray blank line before max-lines disable comment

* fix(plugins): validate catalog feed timestamps

* fix(plugins): validate recovered catalog sequence

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-07-17 15:18:51 -07:00
Peter Steinberger
e5f258c306 fix: remove stale script test export (#110133) 2026-07-17 22:58:34 +01:00
xingzhou
0a868179e4 fix(session): stop repeated restart recovery after retry budget (#96230)
* fix(session): bound restart recovery across gateway restarts

Co-authored-by: Mason Huang <masonxhuang@proton.me>

* style(session): format restart recovery changes

* fix(session): fence recovery notice state

* test(session): align internal recovery types

* test(session): type recovery completion fixture

* style(session): satisfy recovery lint rules

* test(plugin-sdk): split recovery boundary coverage

* test(plugin-sdk): use tracked recovery temp dirs

* fix(session): preserve stale admission errors

* fix(session): close recovery lifecycle races

* fix(session): rotate rejected recovery dispatch ids

* fix(session): enforce recovery quarantine boundaries

* fix(session): close restart recovery exhaustion gaps

* fix(session): preserve recovery command narrowing

* test(session): type restart recovery fixtures

* fix(session): enforce restart recovery quarantine

* fix(session): close restart recovery races

* fix(session): type recovery lifecycle state

* fix(session): enforce recovery ownership fences

* fix(session): fence recovery lifecycle completion

* fix(session): quarantine cross-process recovery

* fix(session): retire stale recovery ownership

* fix(session): restore rejected recovery admission

* fix(session): preserve restored recovery target

* fix(session): retry pending recovery races

* fix(session): preserve concurrent recovery aborts

* fix(session): quarantine recovery lifecycle state

* fix(session): settle exact recovery delivery fences

* fix(session): keep recovery restoration internal

* fix(session): close recovery admission races

* fix(session): retry durable recovery rollback

* fix(session): guard cached recovery settlement

* fix(session): close recovery ownership gaps

* fix(session): resume after delayed recovery rollback

* fix(session): finalize unrecoverable restart state

* fix(session): retry admitted recovery restoration

* fix(session): preserve recovery cleanup guarantees

* fix(session): restore failed terminal settlement

* chore(plugin-sdk): refresh API baseline

* fix(session): close recovery owner retry races

* test(session): type recovery owner fixture

* refactor(session): remove obsolete owner validator

* fix(session): preserve explicit abort recovery

---------

Co-authored-by: Mason Huang <masonxhuang@proton.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 15:36:09 +01:00
Peter Steinberger
b319493a52 improve: let Code Mode use declared tool result shapes (#109813)
* feat(agents): add Code Mode output contracts

* perf(agents): defer untrusted tool schemas

* chore(plugin-sdk): refresh API baseline

* fix(agents): preserve deferred schema markers

* fix(agents): preserve policy-blocked tool results

* fix(agents): preserve nullable output contracts

* fix(agents): reject policy blocks from success contracts

* fix(agents): preserve output contracts through normalization

* test(agents): type normalized tool fixtures

* fix(agents): validate catalog results before projection

* fix(agents): keep result snapshots internal

* fix(agents): fail closed on unrenderable unions

* fix(agents): preserve empty result markers

* test(agents): keep result fixture discriminator literal

* test(agents): use native own-property check
2026-07-17 14:46:37 +01:00
Peter Steinberger
4ef4323db9 fix: keep memory SecretRef failures agent-scoped (#109977)
* test: normalize Copilot token fixture

* test: normalize Copilot auth fixtures

* test: use explicit Copilot placeholders

* test: use neutral Copilot fixture host

* refactor: clarify Copilot embedding auth values

* refactor: keep Copilot profile result intact

* test: normalize embedding credential fixtures

* fix: isolate memory SecretRef owners

* refactor: isolate memory secret collection
2026-07-17 14:44:03 +01:00
Peter Steinberger
7835c03930 test(release): align plugin validation expectations (#110012) 2026-07-17 14:36:12 +01:00
Peter Steinberger
a291cf7296 test(release): align prerelease scan contracts 2026-07-17 13:43:12 +01:00
Kyle Klouzal
e316e1c440 feat(discord): show subagent progress (#95604)
* feat(discord): show subagent progress

Co-authored-by: Kyle Klouzal <kklouzal@users.noreply.github.com>

* fix(discord): serialize progress cleanup ownership

Co-authored-by: Kyle Klouzal <kklouzal@users.noreply.github.com>

* test(discord): type progress state fixtures

* refactor(discord): split subagent progress state

* fix(discord): persist terminal progress outcomes

* fix(discord): narrow persisted cleanup rows

* refactor(discord): keep progress internals private

* perf(discord): preserve lazy progress loading

* chore(plugin-sdk): refresh API baseline after rebase

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Kyle Klouzal <kklouzal@users.noreply.github.com>
2026-07-17 12:02:33 +01:00
wangmiao0668000666
bd7b0ad85f fix(plugins): remove abort listener when channel runtime context is disposed (#109708) 2026-07-17 10:11:21 +01:00
Peter Steinberger
6ac15970a7 feat(onboarding): unified empty-state with provider icons, websites, and recommended installs (#109681)
* feat(onboarding): unify setup recommendations

* fix(control-ui): proxy model setup icons

* fix(onboarding): refresh landing artifacts

* chore(ui): sync translated i18n catalogs

* chore(ui): keep generated locale artifacts on the refresh workflow
2026-07-17 01:01:06 -07:00
Peter Steinberger
0e792b6de3 refactor(channels): centralize inbound orchestration and remove internal compat (#109716)
* refactor(channels): centralize inbound turn orchestration

* refactor(runtime): remove stale compatibility paths

* chore(guards): reject internal deprecated API use

* refactor(channels): simplify core turn planning

* chore(guards): keep deprecated checks boundary-focused

* refactor(memory): keep modern config off compat barrel

* fix(msteams): preserve feedback learning

* test(channels): align modern inbound fixtures

* refactor(channels): finish modern inbound migration

* refactor(channels): tighten core inbound kernel

* fix(channels): preserve turn assembly narrowing

* test(sdk): keep runtime mock binding immutable

* test(matrix): isolate read policy runtime

* test(msteams): mock canonical reply factory

* test(slack): mock core inbound turn dispatch

* test(telegram): inject core session recorder

* test(signal): inject core session recorder

* test(googlechat): assert canonical inbound routing

* test(synology-chat): align core turn fixture

* fix(sdk): preserve direct DM runtime compat

* refactor(channels): own inbound envelope compat in core

* refactor(channels): trim inbound dispatch seams

* refactor(channels): remove redundant async wrappers

* test(synology-chat): type canonical dispatcher mock

* refactor(channels): remove remaining dead compat seams

* chore(sdk): refresh API baseline after rebase

* fix(channels): preserve direct DM identity metadata
2026-07-17 00:56:46 -07:00
Peter Steinberger
765bb37364 feat(setup): stream provider prepare progress to every surface (#109764)
* feat: stream provider preparation progress

* fix(android): refresh gateway method constants
2026-07-17 00:55:04 -07:00
Abner Shang
a33ddc9dc5 fix(openai): close OAuth callback prompts cleanly (#89491)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 23:58:41 -07:00
Peter Steinberger
c13925b387 fix(webhooks): keep routes cold when SecretRefs are unavailable (#109715)
* fix(webhooks): isolate unresolved route secrets

* chore(plugin-sdk): refresh API baseline

* docs(secrets): refresh credential surface
2026-07-16 23:56:59 -07:00
Yuval Dinodia
73cf9a8bed fix(plugins): plugins.deny is bypassed by a mixed-case manifest id (#109237)
* fix(plugins): canonicalize manifest plugin ids to lowercase

Plugin config policy lists (plugins.deny, plugins.allow, plugins.entries)
are lowercase-normalized through normalizePluginId, but a plugin's
self-declared manifest id was only trimmed, never lowercased. A plugin
publishing "id": "Malicious-Scraper" therefore never matched an operator
denylist entry of "malicious-scraper" and fell through to default
activation, loading its hooks, channels, secret integrations, and tools.
The same gap let a mixed-case spelling evade the core reserved-id check.

Canonicalize the id at the manifest parse boundary where
PluginManifestRecord.id is minted, so every downstream policy consumer
compares against the same canonical form.

* test(plugins): prove mixed-case deny at gateway startup

* test(plugins): assert denied gateway record is absent

* test(plugins): materialize allowed secret fixture

* fix(plugins): compare a derived policy key instead of rewriting manifest identity

Manifest ids stay exactly as declared. Deny, allow, and per-entry checks now
compare a lowercase policy key derived at each enforcement boundary, matching
the lowercase-normalized config lists.

The previous approach lowercased PluginManifestRecord.id at the parse boundary.
That id is also matched against the plugin runtime export id, and a mismatch is
a hard load failure, so an existing plugin declaring the same mixed-case id in
both its manifest and its runtime export would stop loading after upgrade.

The Gateway fixture now declares a mixed-case manifest id with a matching
mixed-case runtime export, covering that upgrade case, and drops the allowlist
that previously scoped discovery by a lowercase id and masked the denylist
behavior under test.

* fix(plugins): close mixed-case policy gaps

* test(plugins): use tracked policy fixture temp dir

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 23:13:13 -07:00
Peter Steinberger
e873a7f955 refactor(memory): move QMD coordination to SQLite (#109636)
* refactor(memory): move QMD coordination to SQLite

* chore: keep release notes in PR body

* chore: annotate lease SQLite primitive
2026-07-16 22:01:34 -07:00
Peter Steinberger
a77c0770ff refactor(speech-core): share TTS request pre-resolution across discord and voice-call (#109640) 2026-07-16 21:47:06 -07:00
Ayaan Zaidi
16c14e5bbf feat(channels): expose the turn-adoption lifecycle seam
Replace the bare onTurnAdopted callback and queuedFollowupLifecycle with one
turnAdoptionLifecycle surface (onSettled guaranteed via finally; adoption-loss
aborts queued steering turns without transcript replay), threaded through the
turn kernel and agent runner, exposed to plugins via
runtime.state.openChannelIngressDrain and the channel-outbound SDK barrel,
with surface budgets re-measured against the narrowed baselines (#108656).
2026-07-17 10:12:54 +05:30
ooiuuii
7641aa80c2 fix: plugins update rewrites config for install-record-only updates (#98422)
* Avoid config rewrites for plugin index updates

* Preserve config freshness for records-only plugin updates

* Validate records-only plugin update config

* fix(plugins): reload index-only updates

Co-authored-by: luyifan <al3060388206@gmail.com>

* chore(protocol): refresh generated clients

Co-authored-by: luyifan <al3060388206@gmail.com>

* fix(gateway): wire plugin refresh handler

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 21:38:45 -07:00
Patrick Erichsen
6083268612 feat(plugins): consume hosted listing metadata (#109629) 2026-07-16 21:22:25 -07:00
Patrick Erichsen
55bb6cfa2e feat(control-ui): proxy plugin catalog icons (#109510) 2026-07-16 20:31:27 -07:00
Patrick Erichsen
bd2bf34b41 feat: carry Featured state into Control (#109418)
* feat: consume live featured catalog state

* fix(plugins): honor hosted curation for published bundled plugins

* fix(plugins): accept package-less trusted ClawHub provenance
2026-07-16 20:27:07 -07:00