Use non-null assertion for resolveBlock since TypeScript cannot track
the async reassignment across the setTimeout boundary.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Reset AbortController in MockSchedulerService after cancelTask so
subsequent triggerTask calls receive a fresh signal. Replace setInterval
with a self-scheduling setTimeout loop for liveness checks in TaskWorker
to prevent overlapping DB queries when a check takes longer than the
polling interval.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
The static cancel() now reads task settings from the DB and computes
the next_run_start_at, so cancelled tasks get picked up again on their
normal schedule. Also stops the liveness check polling immediately on
first detection of a cancelled task.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
* feat: split MCP actions into per-plugin servers
Add mcpActions.servers config to create multiple MCP server endpoints
scoped by plugin source, with per-server include/exclude filtering.
Add mcpActions.tools for global tool description overrides.
Signed-off-by: benjdlambert <ben@blam.sh>
* feat: namespace tool names, use filter rules for server scoping
- Tool names now use action ID (plugin:name) by default, opt out
via mcpActions.namespacedToolNames
- Removed pluginSources from server config, use filter.include
with id glob patterns instead
- Removed tool description overrides (deferred to followup)
- Added server key validation for route safety
Signed-off-by: benjdlambert <ben@blam.sh>
* docs: update README for filter-based server scoping
Signed-off-by: benjdlambert <ben@blam.sh>
* feat: drop SSE routes for split servers
Signed-off-by: benjdlambert <ben@blam.sh>
* fix: handle empty servers config, fix test name
Signed-off-by: benjdlambert <ben@blam.sh>
---------
Signed-off-by: benjdlambert <ben@blam.sh>
Adds the ability to cancel currently running scheduled tasks via a new
cancelTask method on the SchedulerService interface. For global (distributed)
tasks, the database lock is released and a periodic liveness check detects
the lost ticket and aborts the task function's AbortSignal. For local tasks,
the abort signal is triggered directly. Also adds a REST endpoint at
POST /.backstage/scheduler/v1/tasks/:id/cancel.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Switch from real timers to fake timers so state transitions are
deterministic. The test previously relied on a ~100ms real-time window
between the 1000ms buildingTimeout and the 1100ms mock sync delay,
which was too tight for slow CI machines to observe reliably.
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
* chore(deps): update dependency react-aria-components to v1.16.0
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
* fix(ui): fix selectedKey type mismatch in Tabs component
Change `selectedId` initialization from `null` to `undefined` to
match React Aria's `selectedKey` prop type (`Key | undefined`).
Signed-off-by: Johan Persson <johanopersson@gmail.com>
---------
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Johan Persson <johanopersson@gmail.com>
The 'abandons a wait after the timeout expires' test relied on real
setTimeout calls with tight margins (~50ms) between barrier timeouts
and tick delays. On loaded CI machines, timer coalescing could cause
both to fire in the same event loop turn, making the test flaky.
Switched all createBarrier tests to jest.useFakeTimers() with
advanceTimersByTime() for deterministic timer control, removing
the real-timer tick helper entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor