Commit Graph

81 Commits

Author SHA1 Message Date
Peter Steinberger 0777ddace8
perf: split more targeted test lanes 2026-04-04 06:05:24 +01:00
Peter Steinberger 55812eaf14
fix: throttle vitest under local contention 2026-04-04 05:50:46 +01:00
Peter Steinberger 22e6225dd0
perf: split hooks, tui, and extension lanes 2026-04-04 05:38:47 +01:00
Peter Steinberger c7cb43cac9
perf: split more scoped vitest lanes 2026-04-04 05:26:32 +01:00
Peter Steinberger 32ba917079
perf: split infra, tooling, and provider test lanes 2026-04-04 04:39:47 +01:00
Peter Steinberger bb1cc84d50
test: default vitest root projects to threads 2026-04-04 04:37:08 +01:00
Peter Steinberger af94a3a89b
test: use native vitest root projects 2026-04-04 04:01:32 +01:00
Peter Steinberger e941d425ac
perf: split acp and ui vitest lanes 2026-04-04 02:08:45 +01:00
Peter Steinberger 2b900b576c
refactor: modernize vitest projects config 2026-04-03 17:20:30 +01:00
Vincent Koc 4e60653959
fix(test): default local Vitest to one worker (#60281) 2026-04-03 21:18:12 +09:00
Peter Steinberger 685ef52284
refactor: simplify test workflow helpers 2026-04-03 13:00:00 +01:00
Peter Steinberger a2077b28ef
refactor: trim vitest wrapper layers 2026-04-03 12:52:14 +01:00
Peter Steinberger 9ef5d85e40
refactor: remove custom test planner runtime 2026-04-03 12:45:13 +01:00
samzong 37ab4b7fdc
[Feat] Add ClawHub skill search and detail in Control UI (#60134)
* feat(gateway): add skills.search and skills.detail RPC methods

Expose ClawHub search and detail capabilities through the Gateway protocol,
enabling desktop/web clients to browse and inspect skills from the registry.

New RPCs:
- skills.search: search ClawHub skills by query with optional limit
- skills.detail: fetch full detail for a single skill by slug

Both methods delegate to existing agent-layer functions
(searchSkillsFromClawHub, fetchSkillDetailFromClawHub) which wrap
the ClawHub HTTP client. No new external dependencies.

Signed-off-by: samzong <samzong.lu@gmail.com>

* feat(skills): add ClawHub skill search and detail in Control UI

Add skills.search and skills.detail Gateway RPC methods with typed
protocol schemas, AJV validators, and handler implementations. Wire
the new RPCs into the Control UI Skills panel with a debounced search
input, results list, detail dialog, and one-click install from ClawHub.

Gateway:
- SkillsSearchParams/ResultSchema and SkillsDetailParams/ResultSchema
- Handler calls searchClawHubSkills and fetchClawHubSkillDetail directly
- Remove zero-logic fetchSkillDetailFromClawHub wrapper
- 9 handler tests including boundary validation

Control UI:
- searchClawHub, loadClawHubDetail, installFromClawHub controllers
- 300ms debounced search input to avoid 429 rate limits
- Dedicated install busy state (clawhubInstallSlug) with success/error feedback
- Install buttons disabled during install with progress text
- Detail dialog with owner, version, changelog, platform metadata

Part of #43301

Signed-off-by: samzong <samzong.lu@gmail.com>

* fix(skills): guard search and detail responses against stale writes

Signed-off-by: samzong <samzong.lu@gmail.com>

* fix(skills): reset loading flags on query clear and detail close

Signed-off-by: samzong <samzong.lu@gmail.com>

* fix(gateway): register skills.search/detail in read scope and method list

Add skills.search and skills.detail to the operator READ scope group
and the server methods list. Without this, unclassified methods default
to operator.admin, blocking read-only operator sessions.

Also guard the detail loading reset in the finally block by the active
slug to prevent a transient flash when rapidly switching skills.

Signed-off-by: samzong <samzong.lu@gmail.com>

* fix(skills): guard search loading reset by active query

Signed-off-by: samzong <samzong.lu@gmail.com>

* test: cover ClawHub skills UI flow

* fix: clear stale ClawHub search results

---------

Signed-off-by: samzong <samzong.lu@gmail.com>
Co-authored-by: Frank Yang <frank.ekn@gmail.com>
2026-04-03 19:30:44 +08:00
Peter Steinberger e0c4458a2f
test: add lighter extensions vitest setup 2026-04-03 11:37:41 +01:00
Peter Steinberger 55e43cbc7f
test: isolate bundled plugin coverage from unit 2026-04-03 10:58:44 +01:00
Kris Wu 7027dda8cd
fix(ui): prevent premature compaction status update on retry (#55132)
Merged via squash.

Prepared head SHA: e7e562f982
Co-authored-by: mpz4life <32388289+mpz4life@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-04-01 13:38:51 -07:00
Peter Steinberger 8e0ab35b0e
refactor(plugins): decouple bundled plugin runtime loading 2026-03-29 09:10:38 +01:00
fuller-stack-dev 83808fe494
fix: wire control-ui steer and redirect (#54625) (thanks @fuller-stack-dev)
* feat(ui): wire /steer slash command to sessions.steer RPC

* feat(ui): wire /steer (soft inject) and /redirect (hard restart) slash commands

* test: use generic subagent names in steer/redirect tests

* fix(ui): exempt steer/redirect from busy-queue and guard sessions.list failures

* fix(ui): skip 'all' wildcard in steer/redirect target resolution

* test: register slash-command-executor test in vitest config

* fix(ui): restrict steer target to subagent keys and active sessions

Address two review issues in resolveSteerTarget:

P2: Replace resolveKillTargets with a dedicated resolveSteerSubagent
that matches only on subagent key suffix or label, not agent id.
This prevents false-positive targeting when the first word collides
with an agent id (e.g. "/steer main refine plan").

P1: Filter out ended sessions (endedAt set) so stale subagents with
reused names are not targeted.

* fix(ui): use shared generateUUID for steer idempotency key

* fix: restore telegram test to upstream state (merge artifact)

* fix(ui): track redirected run so Abort works and concurrent sends are blocked

* fix(ui): skip run tracking when /redirect targets a subagent session

* fix(ui): block idle steer runs

* fix(ui): dedupe steer slash command

* fix(ui): show pending steer state

* fix: wire control-ui steer and redirect (#54625) (thanks @fuller-stack-dev)

* fix: tighten steer target resolution (#54625) (thanks @fuller-stack-dev)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-03-29 10:15:58 +05:30
Peter Steinberger 23772bb785 test: exclude topology fixtures from vitest collection 2026-03-28 13:49:16 +00:00
Peter Steinberger 09f2832670 test: split contract seams from unit lane 2026-03-27 16:28:23 +00:00
Peter Steinberger eebce9e9c7
refactor: move memory host into sdk package 2026-03-27 04:12:04 +00:00
Peter Steinberger 00aedb3414
refactor: split claude cli history import pipeline 2026-03-26 22:12:16 +00:00
Tak Hoffman ab37d8810d
test: introduce planner-backed test runner, stabilize local builds (#54650)
* test: stabilize ci and local vitest workers

* test: introduce planner-backed test runner

* test: address planner review follow-ups

* test: derive planner budgets from host capabilities

* test: restore planner filter helper import

* test: align planner explain output with execution

* test: keep low profile as serial alias

* test: restrict explicit planner file targets

* test: clean planner exits and pnpm launch

* test: tighten wrapper flag validation

* ci: gate heavy fanout on check

* test: key shard assignments by unit identity

* ci(bun): shard vitest lanes further

* test: restore ci overlap and stabilize planner tests

* test: relax planner output worker assertions

* test: reset plugin runtime state in optional tools suite

* ci: split macos node and swift jobs

* test: honor no-isolate top-level concurrency budgets

* ci: fix macos swift format lint

* test: cap max-profile top-level concurrency

* ci: shard macos node checks

* ci: use four macos node shards

* test: normalize explain targets before classification
2026-03-25 18:11:58 -05:00
Peter Steinberger 23a4932997
refactor: share channel card selectors and layout 2026-03-24 21:44:28 -07:00
Peter Steinberger 7909236bd1 perf: add vitest test perf workflows 2026-03-23 04:41:38 +00:00
Peter Steinberger d0f5e7cb2d
test: simplify vitest runner pools 2026-03-22 16:22:09 -07:00
Val Alexander 36c6d44eca
feat(ui): add multi-session selection and deletion (#51924)
* feat(sessions): implement multi-session deletion and selection functionality

- Added `deleteSessionsAndRefresh` function to handle deletion of multiple sessions.
- Updated session state management to track selected session keys.
- Enhanced UI to support bulk actions for selected sessions, including delete and unselect options.
- Refactored related tests to accommodate new multi-session deletion logic.
- Improved responsiveness of sessions table with new CSS rules for mobile layouts.

* feat(sessions): add page deselection functionality and enhance error handling

- Implemented `onDeselectPage` method to allow deselecting specific pages in the session view.
- Updated `deleteSessionsAndRefresh` to handle multiple deletion errors, storing them in an array and displaying a consolidated error message.
- Enhanced tests to verify the new deselection behavior and updated error handling for session deletions.
2026-03-21 18:33:05 -05:00
Tak Hoffman 16e055c083
restore extension-api backward compatibility with migration warning 2026-03-20 13:27:30 -05:00
Josh Avant 8e132aed6e
Hardening: refresh stale device pairing requests and pending metadata (#50695)
* Docs: clarify device pairing supersede behavior

* Device pairing: supersede pending requests on auth changes
2026-03-19 18:26:06 -05:00
clay-datacurve 7b61ca1b06
Session management improvements and dashboard API (#50101)
* fix: make cleanup "keep" persist subagent sessions indefinitely

* feat: expose subagent session metadata in sessions list

* fix: include status and timing in sessions_list tool

* fix: hide injected timestamp prefixes in chat ui

* feat: push session list updates over websocket

* feat: expose child subagent sessions in subagents list

* feat: add admin http endpoint to kill sessions

* Emit session.message websocket events for transcript updates

* Estimate session costs in sessions list

* Add direct session history HTTP and SSE endpoints

* Harden dashboard session events and history APIs

* Add session lifecycle gateway methods

* Add dashboard session API improvements

* Add dashboard session model and parent linkage support

* fix: tighten dashboard session API metadata

* Fix dashboard session cost metadata

* Persist accumulated session cost

* fix: stop followup queue drain cfg crash

* Fix dashboard session create and model metadata

* fix: stop guessing session model costs

* Gateway: cache OpenRouter pricing for configured models

* Gateway: add timeout session status

* Fix subagent spawn test config loading

* Gateway: preserve operator scopes without device identity

* Emit user message transcript events and deduplicate plugin warnings

* feat: emit sessions.changed lifecycle event on subagent spawn

Adds a session-lifecycle-events module (similar to transcript-events)
that emits create events when subagents are spawned. The gateway
server.impl.ts listens for these events and broadcasts sessions.changed
with reason=create to SSE subscribers, so dashboards can pick up new
subagent sessions without polling.

* Gateway: allow persistent dashboard orchestrator sessions

* fix: preserve operator scopes for token-authenticated backend clients

Backend clients (like agent-dashboard) that authenticate with a valid gateway
token but don't present a device identity were getting their scopes stripped.
The scope-clearing logic ran before checking the device identity decision,
so even when evaluateMissingDeviceIdentity returned 'allow' (because
roleCanSkipDeviceIdentity passed for token-authed operators), scopes were
already cleared.

Fix: also check decision.kind before clearing scopes, so token-authenticated
operators keep their requested scopes.

* Gateway: allow operator-token session kills

* Fix stale active subagent status after follow-up runs

* Fix dashboard image attachments in sessions send

* Fix completed session follow-up status updates

* feat: stream session tool events to operator UIs

* Add sessions.steer gateway coverage

* Persist subagent timing in session store

* Fix subagent session transcript event keys

* Fix active subagent session status in gateway

* bump session label max to 512

* Fix gateway send session reactivation

* fix: publish terminal session lifecycle state

* feat: change default session reset to effectively never

- Change DEFAULT_RESET_MODE from "daily" to "idle"
- Change DEFAULT_IDLE_MINUTES from 60 to 0 (0 = disabled/never)
- Allow idleMinutes=0 through normalization (don't clamp to 1)
- Treat idleMinutes=0 as "no idle expiry" in evaluateSessionFreshness
- Default behavior: mode "idle" + idleMinutes 0 = sessions never auto-reset
- Update test assertion for new default mode

* fix: prep session management followups (#50101) (thanks @clay-datacurve)

---------

Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
2026-03-19 12:12:30 +09:00
Tak Hoffman 2de28379dd
Plugins: remove public extension-api surface (#48462)
* Plugins: remove public extension-api surface

* Plugins: fix loader setup routing follow-ups

* CI: ignore non-extension helper dirs in extension-fast

* Docs: note extension-api removal as breaking
2026-03-16 15:51:08 -05:00
Peter Steinberger 59940cb3ee refactor(plugin-sdk): centralize entrypoint manifest 2026-03-16 02:11:18 +00:00
Peter Steinberger bc5054ce68 refactor(google): merge gemini auth into google plugin 2026-03-16 01:19:32 +00:00
Nimrod Gutman e2dac5d5cb
fix(plugins): load bundled extensions from dist (#47560) 2026-03-15 21:16:27 +02:00
scoootscooob 439c21e078
refactor: remove channel shim directories, point all imports to extensions (#45967)
* refactor: remove channel shim directories, point all imports to extensions

Delete the 6 backward-compat shim directories (src/telegram, src/discord,
src/slack, src/signal, src/imessage, src/web) that were re-exporting from
extensions. Update all 112+ source files to import directly from
extensions/{channel}/src/ instead of through the shims.

Also:
- Move src/channels/telegram/ (allow-from, api) to extensions/telegram/src/
- Fix outbound adapters to use resolveOutboundSendDep (fixes 5 pre-existing TS errors)
- Update cross-extension imports (src/web/media.js → extensions/whatsapp/src/media.js)
- Update vitest, tsdown, knip, labeler, and script configs for new paths
- Update guard test allowlists for extension paths

After this, src/ has zero channel-specific implementation code — only the
generic plugin framework remains.

* fix: update raw-fetch guard allowlist line numbers after shim removal

* refactor: document direct extension channel imports

* test: mock transcript module in delivery helpers
2026-03-14 03:43:07 -07:00
Peter Steinberger bffce8ea4f
fix(ui): harden avatar fallback regressions 2026-03-13 03:46:30 +00:00
Peter Steinberger 4656317770
fix(ui): resolve control chat avatar fallback 2026-03-13 03:42:11 +00:00
Gustavo Madeira Santana 7a2f5a0098 Plugin SDK: add full bundled subpath wiring 2026-03-04 02:35:12 -05:00
Gustavo Madeira Santana 802b9f6b19 Plugins: add root-alias shim and cache/docs updates 2026-03-04 01:20:48 -05:00
Gustavo Madeira Santana 1278ee9248 plugin-sdk: add channel subpaths and migrate bundled plugins 2026-03-03 22:07:03 -05:00
Igal Tabachnik a4850b1b8f
fix(plugins): lazily initialize runtime and split plugin-sdk startup imports (#28620)
Merged via squash.

Prepared head SHA: 8bd7d6c13b
Co-authored-by: hmemcpy <601206+hmemcpy@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-03-03 19:58:48 -05:00
Peter Steinberger 3a08e69a05 refactor: unify queueing and normalize telegram slack flows 2026-03-02 20:55:15 +00:00
SidQin-cyber 15226b0b83 fix(gateway): persist streamed text when webchat final event lacks message
When an agent streams text and then immediately runs tool calls, the
webchat UI drops the streamed content: the "final" event arrives with
message: undefined (buffer consumed by sub-run), and the client clears
chatStream without saving it to chatMessages.

Before clearing chatStream on a "final" event, check whether the stream
buffer has content. If no finalMessage was provided but the stream is
non-empty, synthesize an assistant message from the buffered text —
mirroring the existing "aborted" handler's preservation logic.

Closes #31895
2026-03-02 19:54:26 +00:00
Peter Steinberger 4d89548e59 fix(ui): inherit default model fallbacks in agents overview (#25729)
Land PR #25729 from @Suko.
Use shared fallback-resolution helper and add regression coverage for default, override, and explicit-empty cases.

Co-authored-by: suko <miha.sukic@gmail.com>
2026-02-25 01:28:17 +00:00
Tak Hoffman 9e1a13bf4c
Gateway/UI: data-driven agents tools catalog with provenance (openclaw#24199) thanks @Takhoffman
Verified:
- pnpm install --frozen-lockfile
- pnpm build
- gh pr checks 24199 --watch --fail-fast

Co-authored-by: Takhoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-02-22 23:55:59 -06:00
Peter Steinberger 9789dfd95b fix(ui): correct usage range totals and muted styles 2026-02-17 03:04:00 +01:00
Peter Steinberger c1655982d4 refactor: centralize pre-commit file filtering 2026-02-16 03:42:11 +01:00
Peter Steinberger ba84b12535 fix: harden pre-commit hook against option injection 2026-02-16 03:23:45 +01:00
Peter Steinberger b6f2c3b746 test: fix coverage scope 2026-02-15 04:06:11 +00:00