Draft
Conversation
Contributor
tsmarvin
commented
Mar 2, 2026
- In progress refactor - restart development initial commit
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: tsmarvin <57049894+tsmarvin@users.noreply.github.com>
refactor: Fix formatting inconsistencies flagged in PR review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: tsmarvin <57049894+tsmarvin@users.noreply.github.com>
fix: Qualify unresolved XML doc cref references in test files
…entation refactor: Attempt to improve documentation and formatting.
- Update hosted powershell to 7.6 rc1. - Added ascii art to the agent home page. - Added default migrations
Data model: - Add TaskSchedule/WorkflowSchedule many-to-many join entities with composite PKs, IsOneTime flag, and CreatedAtUtc - Remove ScheduleId FK from WerkrTask and Workflow entities - Add CatchUpEnabled to DbSchedule for missed-occurrence detection - Add ScheduleId to WerkrJob for per-schedule catch-up tracking - Add IsEphemeral to WerkrTask for console-created task cleanup - Configure new relationships and DbSets in WerkrDbContext - Update Sqlite migration snapshot UI (Blazor Server): - Remove schedule dropdown/columns from Task and Workflow CRUD pages and dashboard - Update Console.razor to map OperatorType → TaskActionType and handle meta/complete SSE events for unified execution path - Fix sidebar layout: flex-based nav-scrollable, move footer outside scrollable region - Use card class on ChangePassword guidance box - Remove unused import and version text from NavMenu
…ecution feat: unified execution data model and UI
## Workflow Engine: Variables, No-Code Actions, Interactive DAG Editor & Real-Time Run Monitoring
The next-generation workflow experience for Werkr: a first-class inter-step variable system, 16 new no-code action handlers (11→27 total), a TypeScript/Node.js build pipeline, real-time run monitoring via SignalR, a vis-timeline Gantt view, and a full AntV X6-based DAG renderer and interactive workflow editor — replacing the previous server-rendered SVG `DagView.razor` entirely. It also includes targeted workflow editor bug fixes and creation UX improvements: renaming `ControlStatement.Sequential` to `Default`, structured condition editing, workflow target tags, schedule association, and inline task creation.
---
### Workflow Variables
**Why:** Workflows need inter-step data flow. Previously, steps were isolated — each executed independently with no way to pass results forward. Variables make workflows composable: a "get server list" step can feed into a "deploy to each" step.
#### Data Model
| Entity | Purpose |
|---|---|
| `WorkflowVariable` | Design-time variable definition scoped to a workflow. Unique `(WorkflowId, Name)`. |
| `WorkflowRunVariable` | Append-only runtime value record with `Version`, `Source`, and optional back-references to the producing step/job. |
| `VariableSource` enum | `Default` (0), `ManualInput` (1), `StepOutput` (2), `ReExecutionEdit` (3) |
`WorkflowStep` gains nullable `InputVariableName` and `OutputVariableName` columns (max 128 chars).
#### gRPC
New **`VariableService.proto`** with three RPCs (all via `EncryptedEnvelope`):
- `GetVariable` — Agent reads the latest variable value from the API.
- `SetVariable` — Agent writes a step's output variable back to the API.
- `CreateWorkflowRun` — Agent requests a new workflow run record (cron-triggered flows).
Modified protos:
- **`ScheduleSync.proto`** — `ScheduledWorkflowDefinition` adds variable definitions, run ID, and trigger variables; `ScheduledWorkflowStepDef` adds input/output variable name fields.
- **`JobReport.proto`** — `JobResultRequest` adds `workflow_run_id`, `output_variable_name`, and `output_variable_value`.
#### REST API (7 endpoints in `VariableEndpoints.cs`)
| Method | Route | Purpose |
|---|---|---|
| GET | `/api/workflows/{workflowId}/variables` | List variable definitions |
| POST | `/api/workflows/{workflowId}/variables` | Create variable definition |
| PUT | `/api/workflows/{workflowId}/variables/{variableId}` | Update variable definition |
| DELETE | `/api/workflows/{workflowId}/variables/{variableId}` | Delete variable definition |
| GET | `/api/workflow-runs/{runId}/variables` | Latest values per run |
| GET | `/api/workflow-runs/{runId}/variables/{name}/history` | Full version history |
| PUT | `/api/workflow-runs/{runId}/variables/{name}` | Edit runtime variable (appends `ReExecutionEdit`) |
All endpoints require `Policies.IsAdmin`.
#### Agent Execution Flow
`WorkflowExecutionService` is extended with:
- An in-memory variable cache (`Dictionary<string, string>`) per workflow run.
- Input variable resolution before each step.
- Temp-file exchange via `job-output/_vars/` for shell operators (`WERKR_INPUT` / `WERKR_OUTPUT` injected as environment variables).
- Post-step variable push to the API via `VariableClient`.
- `CreateWorkflowRun` gRPC call for cron-triggered workflows that lack a pre-existing run record.
#### Configuration
- `WorkflowVariableOptions` — `SectionName = "WorkflowVariables"`, `MaxValueSizeBytes` default **65 536**.
- Bound in both Agent and API `appsettings.json`.
---
### No-Code Actions
**Why:** Expands the built-in action catalog from **11 → 27 handlers**, enabling file inspection, content manipulation, archiving, iteration, JSON transformation, and a full suite of network actions — all without writing scripts.
#### New Actions (16)
| Action | Category | Description |
|---|---|---|
| `Delay` | Control Flow | Pause execution for a specified duration |
| `ForEach` | Control Flow | Iterate over items |
| `GetFileInfo` | File | Retrieve file metadata |
| `ReadContent` | File | Read file content into a variable |
| `ListDirectory` | File | Enumerate directory contents |
| `FindReplace` | File | Regex or literal find-and-replace in files |
| `CompressArchive` | Archive | Create zip/tar archives |
| `ExpandArchive` | Archive | Extract archives |
| `WatchFile` | File | Watch for file-system changes |
| `TransformJson` | Data | JSONPath-based data transformation |
| `HttpRequest` | Network | General-purpose HTTP request |
| `DownloadFile` | Network | Download a remote file |
| `UploadFile` | Network | Upload a file to a remote URL |
| `TestConnection` | Network | TCP/HTTP connectivity check |
| `SendWebhook` | Network | Fire a webhook (JSON payload) |
| `SendEmail` | Network | Send email via SMTP (MailKit) |
#### Updated Pre-Existing Actions (11)
`CopyFile`, `MoveFile`, `RenameFile`, `DeleteFile`, `CreateFile`, `CreateDirectory`, `TestExists`, `ClearContent`, `WriteContent`, `StartProcess`, `StopProcess` — all updated to support `OutputVariableValue` propagation.
#### Network Infrastructure
- **`IUrlValidator`** / **`UrlValidator`** — SSRF protection: DNS pinning, private-IP/loopback rejection, scheme validation (http/https only), configurable URL allowlist.
- **`IHttpClientFactory`** — Named `"WerkrActions"` client with `SocketsHttpHandler`, DNS-pinning `ConnectCallback`, 2-minute `PooledConnectionLifetime`.
- **`ActionOperatorConfiguration`** extended with `EnableNetworkActions` (default `false`), `AllowedUrls` (default `[]`), `AllowPrivateNetworks` (default `false`).
#### Interface Changes
- `IActionHandler.ExecuteAsync()` — new optional parameter `string? inputVariableValue = null`.
- `ActionOperatorResult` — new property `string? OutputVariableValue = null`.
- `IShellOperator` methods — new optional parameter `IReadOnlyDictionary<string, string>? environmentVariables = null`.
- Shell operators updated: `PwshOperator` injects via `SessionStateProxy.SetVariable()` (runspace-scoped); `SystemShellOperator` injects via `ProcessStartInfo.Environment` (per-process).
---
### Workflow Editor Bug Fixes & Creation UX
**Why:** The original workflow editor had usability gaps — freeform condition input was error-prone, the `Sequential` enum name was misleading, and creating workflows required excessive navigation between pages.
- **ControlStatement rename** — `ControlStatement.Sequential` renamed to `ControlStatement.Default` with a backward-compatible DB value converter that reads legacy `Sequential`, `Parallel`, `ConditionalIf`, `ConditionalElseIf`, `ConditionalWhile`, and `ConditionalDo` values as their modern equivalents. Unrecognized strings fall back to `Default`. Full round-trip test coverage in `ControlStatementConverterTests`.
- **ConditionBuilder** — Replaces freeform condition input with a structured component supporting exit code comparisons and success status checks, with raw/advanced mode toggle and regex validation.
- **TargetTags** — Added `TargetTags` (`string[]` stored as JSON) to the `Workflow` entity with custom `ValueComparer`; exposed via `TagInput` component in the workflow editor.
- **Schedule association UI** — Associate/disassociate actions and available-schedule dropdown added to the workflow editor.
- **TaskCreateModal** (`TaskSetupModal`) — Inline task creation from the workflow editor with full form support (action types, arguments, tags, success criteria, timeout). Supports both create (POST) and edit (PUT) modes. bUnit tests cover modal visibility, form rendering, submission, cancellation, and edit mode.
- **DagView node coloring** updated to match the renamed `Default` control type.
- **Regenerated Postgres and SQLite `InitialCreate` migrations** with `target_tags` column on the workflows table and variable columns on workflow steps.
---
### Interactive Visual Workflow Editor
**Why:** The form-based step/dependency management was not intuitive or visually appealing. The best visual workflow editors share a common set of critical UX patterns: composable architecture (separating mapping, operations, layout, and traversal concerns), connection-drop-to-node-creator, undo/redo with grouped history, node dirtiness tracking, fixed connection points with visual feedback state machines, and searchable, categorized shape palettes.
The editor uses a **batch-save architecture**: all mutations modify local X6 graph state and an in-memory changeset. An explicit "Save" syncs to the API. Undo/redo operates purely on local state — avoiding the complexity of reversing per-action API calls.
- **DagEditor.razor** — Top-level editor page at `/workflows/{Id}/dag-editor`. Three-column layout: `StepPalette` | `DagEditorCanvas` | `NodeConfigPanel`. Manages draft restore, metadata editing, DAG validation. Authorized for Admin/Operator roles.
- **DagEditorCanvas.razor** — Interactive X6 canvas with minimap
- **DagEditorJsInterop** — Editor interop: `InitEditorAsync`, `LoadGraphAsync`, `AddNodeAsync`, `UpdateNodeDataAsync`, `GetChangesetJsonAsync`, `UndoAsync`/`RedoAsync`, `SetLayoutDirectionAsync`, `ZoomToAsync`/`ZoomToFitAsync`. JS→.NET callbacks: `OnNodeSelected`, `OnNodeDropped`, `OnSaveRequested`, `OnCycleDetected`, `OnGraphDirtyChanged`.
- **StepPalette.razor** — Categorized, searchable sidebar with drag-to-canvas via X6 Dnd. Collapsible categories with filtered step creation for rapid discovery.
- **NodeConfigPanel.razor** — Right-side property editor for task info, control flow, conditions, variable bindings, dependencies. Enables task-level I/O inspection — the number 1 debugging capability for workflow operators.
- **EditorToolbar.razor** — Save, undo/redo, validate, zoom, export controls
- **Undo/redo** via X6 History plugin — tracks all mutations with grouped operations (e.g., delete node + edges = one undo step)
- **Keyboard shortcuts** via X6 Keyboard: Delete, Ctrl+A, Ctrl+C/V, Ctrl+Z/Y, Escape, arrow keys
- **Clipboard** via X6 Clipboard: copy/paste subgraphs with preserved internal edges
- **changeset.ts** — Tracks add/delete/move mutations locally. Debounced: rapid operations accumulate, Save sends a single batch.
- **cycle-detection.ts** — Client-side DFS cycle detection O(V+E) with visual feedback on invalid connections. Required for DAG integrity.
- **draft-storage.ts** — Auto-save drafts to localStorage. `beforeunload` warning for unsaved changes.
- **export-handler.ts** — PNG and SVG export via `graph.toSVG()` / `graph.toPNG()`
- **dnd-handler.ts** — Drag-and-drop from palette to canvas
- **annotation-node.ts** — Free-form sticky note annotations on canvas for documenting workflow sections
---
### AntV X6 DAG Renderer — Replacing Server-Rendered SVG
**Why:** The previous `DagView.razor` was a server-rendered SVG using Kahn's algorithm with fixed-size nodes (160×52) and click-to-select only. SVG + foreignObject rendering with Dagre layout is the proven approach for rich node content (full HTML/CSS) while maintaining SVG coordinates for pan, zoom, and edges. AntV X6 provides all visual interactions client-side at 0ms latency, with built-in undo/redo, clipboard, drag-from-toolbar, minimap, and snapline alignment.
- **DagCanvas.razor** — Read-only X6 DAG component with toolbar (LR/TB layout switching)
- **DagJsInterop** — Typed C# wrapper inheriting `GraphJsInteropBase`. Methods: `CreateGraphAsync`, `LoadGraphAsync`, `ZoomToFitAsync`, `ApplyStatusOverlayAsync`. No scattered `IJSRuntime.InvokeAsync("eval", ...)` calls.
- **TypeScript core:** `create-graph.ts`, `dag-readonly.ts`, `werkr-node.ts`, `werkr-edge.ts`
- **Dagre hierarchical layout** via `layout-engine.ts` — configurable TB/LR rank direction. The `tight-tree` ranker was chosen over `network-simplex` for dramatically better performance at scale.
- **foreignObject HTML nodes** with Bootstrap styling: cards, badges, action-type indicators — enabling full HTML/CSS inside graph nodes rather than flat SVG text
- **parallel-lanes.ts** — Light background lanes behind same-level parallel nodes for visual concurrency indication
- **status-overlay.ts** — Color-coded execution status per selected run via `cell.setData()`. Consistent color language: Green=Success, Red=Failed, Amber=Running, Purple=Pending, Gray=Skipped.
- **X6 plugins:** Selection, Snapline, Scroller, Transform, MiniMap — all built into X6 3.x core
- **Type definitions:** `dag-types.ts` (node/edge DTOs), `dotnet-interop.d.ts` (.NET callback interface)
---
### Real-Time Run Monitoring & Execution Views
**Why:** The workflow debugging experience is the primary functionality for the product — building workflows happens once; debugging them happens daily.
- **Three-view tiered complexity** — different users need different detail levels (Compact for quick glance, Timeline for duration analysis, Detail for debugging)
- **Steps × Runs grid view** — the most effective at-a-glance cross-run pattern recognition, with color-coded cells making failures immediately visible
- **Gantt charts** — essential for bottleneck identification and understanding parallelism
- **Sparkline bar charts** — quick pattern recognition for duration and failure trends without drilling in
- **Event grouping** — collapsing related events (Scheduled→Started→Completed) into one logical unit reduces cognitive load
- **Real-time liveness** — all views update as events stream, rather than polling on a timer
- **Task-level I/O inspection** — see exactly what went in/out at every task boundary, including workflow variable values
- **Saved filter views** — operators managing many workflows need personalized, filtered views by status, agent, tag, and owner
**Workflow event types** in `Werkr.Core/Communication/`:
- **WorkflowEvent.cs** — Six new event types: `StepStartedEvent`, `StepCompletedEvent`, `StepFailedEvent`, `StepSkippedEvent`, `RunCompletedEvent`, `LogAppendedEvent`
- **WorkflowEventBroadcaster** — Singleton fan-out via `System.Threading.Channels`. Published from gRPC service handlers (`JobReportingGrpcService`, `OutputStreamingService`, `VariableService`) when agents report execution progress.
- **WorkflowEventSubscription** — Consumer subscription pattern for SSE endpoints
**Real-time data pipeline:**
```
Agent → gRPC → API WorkflowEventBroadcaster → SSE stream → JobEventRelayService → SignalR WorkflowRunHub → Browser
```
- **WorkflowRunHub** — SignalR hub at `/hubs/workflow-run`. Authorized clients join groups keyed by run ID to receive `StepStatusChanged`, `RunCompleted`, and `LogAppended` events.
- **JobEventRelayService** — `BackgroundService` + `IHealthCheck` that opens a long-lived SSE connection to `GET /api/events/workflow-runs` via the `"ApiServiceSse"` named `HttpClient`, deserializes events, and relays them to the hub via `IHubContext<WorkflowRunHub>`. Auto-reconnects with exponential backoff (1s → 30s). Tracks active run subscriptions in a `ConcurrentDictionary`. Registered as health check (`"sse-relay"`) for operational visibility.
- **ConnectionStatus.razor** — Visual indicator (Live / Reconnecting / Polling) in the UI
- **RunDetail.razor** — Multi-view run detail page (Compact / Timeline / Log tabs)
- **GanttTab.razor** + **TimelineJsInterop** — vis-timeline Gantt chart showing horizontal bars per task with duration and status. Live bars grow during active runs via SignalR push.
- **RunSparkline.razor** — Server-side SVG mini bar charts (bar height = duration, bar color = status) inline on the workflow list
- **RunGridView.razor** — Steps × Runs 2D status matrix for cross-run comparison
- **StepDetailPanel.razor** — Step-level log preview and error messages
- **TimelineView.razor** — Chronological step execution list with attempt tracking and event grouping
- **SavedFilterService** + **FilterBar.razor** — Named saved filter views persisted via localStorage. Backed by a full filter model ecosystem: `FilterField`, `FilterDefinition`, `FilterCriteria`, `FilterFieldType`, `SavedFilterView` in `Werkr.Common/Models/`.
- **SignalR DTOs** — `StepStatusDto`, `RunStatusDto`, `LogLineDto` in `WorkflowRunHubDtos.cs` — typed payloads for each hub broadcast method
- **Additional DTOs** — `RunSparklineDto`, `StepStatusSummaryDto`, `AnnotationDto`, `DagValidationResult` in `Werkr.Common/Models/`
- Dedicated SSE `HttpClient` (`"ApiServiceSse"`) configured with infinite timeout and no resilience handlers in `Program.cs`
---
### API Endpoints & Batch Operations
**Batch save endpoint** — The server-side contract for the editor's batch-save architecture:
- `POST /api/workflows/{workflowId}/steps/batch` — Atomic batch operations for editor save. Accepts a `WorkflowStepBatchRequest` containing ordered step operations.
- **Sign convention**: negative `StepId` = temp ID (new nodes created in the editor), positive = real ID (existing nodes). The response includes `StepIdMapping[]` for temp→real ID resolution after save.
- **WorkflowStepBatchModels.cs** — `WorkflowStepBatchRequest`, `StepBatchOperation`, `DependencyBatchItem`, `WorkflowStepBatchResponse`, `StepIdMapping`
**Run management:**
- `POST /api/workflows/{id}/runs/{runId}/retry-from/{stepId}` — Retry from a failed step with optional variable overrides via `RetryFromFailedRequest`
**SSE event streams:**
- `GET /api/events/workflow-runs` — Dedicated SSE stream for workflow run events (consumed by `JobEventRelayService`)
- `GET /api/workflows/runs/{runId}/events` — Per-run filtered event stream
- `GET /api/events/jobs` — Existing job event stream (backward-compatible)
**Saved filter persistence:**
- Full CRUD at `/api/filters/{pageKey}` (GET list, POST create, PUT update, DELETE) with page keys for runs, workflows, jobs, agents, schedules, tasks. Admin-only share toggle.
---
### Consistent Color Standard & Theme System
**Why:** A consistent color language across all views — where the same semantic colors map to the same states throughout the entire UI — is essential for quick visual parsing.
- **CSS custom properties** in `theme.css` defining a standardized palette with dark/light theme support:
- Status: `--werkr-success` (#28a745), `--werkr-failed` (#dc3545), `--werkr-running` (#ffc107), `--werkr-pending` (#6f42c1), `--werkr-skipped` (#6c757d), `--werkr-not-run`
- Node types: `--werkr-node-default`, `--werkr-node-conditional`, `--werkr-node-fallback`, `--werkr-node-loop`
- Structural: `--werkr-edge-color`, `--werkr-node-stroke`, `--werkr-parallel-group-bg`, `--werkr-snapline`
- Applied consistently across DAG nodes, sparklines, grid view cells, Gantt bars, and status badges
---
### JS/TS Build Infrastructure
**Why:** The X6 graph engine, vis-timeline, and Dagre layout all require a proper JS/TS build pipeline. Keeping all drag, zoom, pan, and connection drawing in the browser while reserving SignalR round-trips for state commits.
- **TypeScript 5.9** project with strict mode under `graph-ui/`
- **esbuild** bundler (~50ms incremental builds) with code-split output to `wwwroot/js/dist/`: `dag-readonly.js`, `dag-editor.js`, `timeline-view.js`, plus shared vendor chunks. Editor bundle lazy-loaded only when entering edit mode.
- **MSBuild integration** in `Werkr.Server.csproj`: `EnsureNode` → `NpmInstall` → `BuildGraphUi` targets fire automatically during `dotnet build`. No separate npm steps needed during development.
- **Vitest 3.0** test runner with 7 unit tests covering changeset operations, cycle detection, draft storage, clipboard handling, timeline item mapping, and status styling
- **Blazor↔JS interop hierarchy:** `GraphJsInteropBase<T>` manages `IJSObjectReference` + `DotNetObjectReference` lifecycle with `IAsyncDisposable`. Three derived classes: `DagJsInterop` (read-only), `DagEditorJsInterop` (editor), `TimelineJsInterop` (Gantt).
- `.nvmrc` pins Node.js 22. .gitignore excludes `node_modules/` and `wwwroot/js/dist/`.
---
### CI/CD & Dependency Updates
- **CI workflow** (`ci.yml`): Added Node.js 22 setup → `npm ci` → Vitest → `npm run build:prod` → bundle size check via `check-bundle-size.mjs` (250 KB gzipped budget)
- **DocFX workflow** (`DocFX_gh-pages.yml`): Simplified from multi-job Windows workflow to single Ubuntu-based job
- **NuGet dependency updates** in Directory.Packages.props: Microsoft.Extensions, ASP.NET Core, EF Core, SignalR, and test packages updated to latest patch versions
- **Central package transitive pinning** enabled in Directory.Packages.props to enforce consistent transitive dependency versions
- **Lock file updates** across all projects to match new package versions
- **Cross-platform test fix** in `UrlValidatorTests.cs`: `RelativeUrl_Rejected` test now handles Unix vs. Windows URI parsing differences
- **`System.Text.Json` transitive dependency** update in installer project
---
### Tests
**New .NET unit tests:**
- **`ControlStatementConverterTests`** — Round-trip, legacy value mapping, unknown fallback
- **`WorkflowVariableTests`** (~446 lines) — Entity CRUD, unique constraints, version ordering, cascade deletes
- **`WorkflowServiceTests`** — Diamond DAG, three-independent-steps, mixed control statements
- **`UrlValidatorTests`** — SSRF protection: private IP rejection, loopback blocking, allowlist enforcement, scheme validation
- **`TaskSetupModalTests`** — Modal lifecycle, edit mode, HTTP methods, callbacks
- **`ConditionBuilderTests`** — Structured condition editing component
- **27 action handler test files** — One per handler (16 new + 11 updated)
**New TypeScript tests (Vitest):**
- `changeset.test.ts` — Changeset accumulation and merge operations
- `cycle-detection.test.ts` — DFS cycle detection correctness
- `draft-storage.test.ts` — localStorage draft persistence
- `clipboard-handler.test.ts` — Copy/paste subgraph operations
- `timeline-items.test.ts` — Gantt item mapping from DTOs
- `timeline-styles.test.ts` — Status-to-color mapping consistency
- `smoke.test.ts` — Module import validation
---
### New Dependencies
| Package | Version | Purpose |
|---------|---------|---------|
| `@antv/x6` | 3.1.6 | Graph visualization & editing engine (MIT) |
| `dagre` | 0.8.5 | Hierarchical DAG layout (MIT) |
| `vis-timeline` | 7.7.3 | Gantt timeline rendering (Apache-2.0 / MIT) |
| `vis-data` | 7.1.9 | Reactive data containers for vis-timeline (Apache-2.0 / MIT) |
| `typescript` | 5.9.x | TypeScript compiler |
| `esbuild` | 0.27.x | Bundler |
| `vitest` | 3.0.x | Test runner |
| `Microsoft.Extensions.Http.Resilience` | 10.3.0 | `IHttpClientFactory` with resilience policies for network actions |
| `MailKit` | 4.15.1 | SMTP email sending for `SendEmail` action |
### New Prerequisites
- **Node.js 22+** required on dev machines and CI agents
…Compliance BREAKING CHANGE: Enum values renamed across StepExecutionStatus, WorkflowRunStatus, and DependencyMode. All persisted string values and API contracts change accordingly. No migration path needed (pre-v1.0). 1.1.1 — State Model Alignment - Rename StepExecutionStatus.Completed → Succeeded - Rename WorkflowRunStatus.Completed → Succeeded - Rename DependencyMode.All → AllSuccess, Any → AnySuccess - Update ~35 files: services, DTOs, Blazor UI, Graph-UI TS/CSS, tests 1.1.2 — Workflow Variable Entity Compliance - Add DataType, IsRequired, LogRedaction to WorkflowVariable entity - Extend ScheduleSync proto WorkflowVariableDef with new fields - Update DTO, API endpoints, and gRPC mapper - Fix output variable writing to push even when value is null 1.1.3 — Workflow Enabled/Disabled Behavior - Add NotifyWorkflowDisabled RPC to ScheduleInvalidation proto - Add CancellationTokenSource tracking per active workflow run - Add WorkflowDisabledDispatcher to notify agents on disable - Cancel in-flight runs gracefully when workflow is disabled 1.1.4 — Retry-from-Failed Compliance - Add prior_succeeded_step_ids and run_variable_values to proto - Pre-populate stepResults from prior succeeded steps on retry - Seed variable cache from latest run variable values on retry - Skip already-succeeded steps during retry execution - Add 3 new tests: variable chaining, override precedence, diamond DAG 1.1.5 — Terminology Audit - Zero remaining references to old enum names confirmed via grep - Reset app-data migrations to clean InitialCreate baseline Test results: 1,103 passed (577 unit + 217 integration + 309 e2e)
…ent Compliance
Project 1.2: Task Engine & Action Handler Compliance
- Change default task timeout from 30 to 60 minutes across all fallback
paths (config, gRPC sync, Settings UI, action descriptors)
- Add ICMP ping support to TestConnectivity handler; make Port nullable
(required only for TCP/HTTP/HTTPS)
- Add Basic, Bearer, and API Key authentication to HttpRequest handler
- Capture PowerShell Information stream (Write-Information) via dual
host-override + post-invocation stream capture with PSHOST dedup
- Add [ActionCategory] attribute to all 26 IActionHandler implementations;
realign ActionRegistry categories to spec (merge Content→File,
Notification→Network, rename Control→ControlFlow, Event→File monitoring)
- Add startup validation that handler attributes match registry categories
- Update StepPalette category icons for new groupings
Project 1.3: Security & Crypto Compliance
- Upgrade API key hashing from SHA-256 to SHA-512
- Add PasswordHistory entity, IPasswordValidator, and recording service
for NIST-aligned password reuse prevention (configurable depth, default 5)
- Replace heartbeat-based key clearing with time-based grace period;
add KeyRotatedAtUtc column and configurable grace period (default 5 min)
- Bootstrap FieldEncryptionProvider into API DI; apply AES-256-GCM
transparent encryption to WorkflowRunVariable.Value via EF Core
value converter
Project 1.4: Agent & gRPC Compliance
- Report agent version at registration and on each heartbeat; persist to
RegisteredConnection; surface in all agent DTOs
- Implement graceful shutdown with configurable drain timeout (default 30s),
active job tracking, and ApplicationStopping callback
- Add HolidayRuleDefinition and CalendarDefinition proto messages;
sync algorithmic calendar rules to agents for client-side evaluation
of unmaterialized holiday years
- Add ShiftMode enum and schedule-level shift configuration (None,
NextBusinessDay, PreviousBusinessDay, NearestBusinessDay) with
ObservanceRule tiebreaker; extend ScheduleAuditLog for shift tracking
Migrations regenerated as clean InitialCreate baselines for all four
contexts (Postgres + SQLite × app data + identity).
BREAKING CHANGE: API key hashes are now SHA-512; existing keys invalid.
Port is nullable on TestConnectionParameters. Action handler categories
renamed. HeartbeatResponse has new agent_version field. RegistrationService
.CompleteRegistrationAsync has new agentVersion parameter.
…liance
Epic 1.5.1: API Versioning
- Rename all REST routes from /api/ to /api/v1/ across 58 files (~375
occurrences): 15 API endpoint files, Server auth endpoints, auth
proxy forwarded URL, 34 Server-side HttpClient callers, and 7 test
files including Results.Created/Accepted location URIs
Epic 1.5.2: Health & Observability
- Remove IsDevelopment() guards from health endpoint mapping in
ServiceDefaults and OpenAPI publishing in Api; /health, /alive, and
/openapi/v1.json now available in all environments
Epic 1.5.3: Retention Service Compliance
- Change RetentionDays default from 90 to 365 per spec §12
- Add configurable SweepIntervalMinutes to AuditLogOptions (default
1440, hard minimum 15) replacing hardcoded 24-hour sweep interval;
values below minimum are clamped with a warning log
BREAKING CHANGE: All REST endpoints moved from /api/ to /api/v1/.
Requests to unversioned /api/ paths return 404.
1.6.2: Color Standard
- Rename CSS custom properties from --werkr-success/--werkr-failed/etc
to --werkr-status-succeeded/--werkr-status-failed/etc in both dark
and light themes; remove --werkr-not-run in favor of
--werkr-status-cancelled
- Replace Bootstrap badge bridge (.badge.bg-success etc) with
werkr-status-* background and werkr-border-* border utility classes
referencing CSS custom properties
- Migrate StatusDisplayHelper from Bootstrap bg-* classes to
werkr-status-* classes for all execution and domain statuses
- Update TimelineView card headers from Bootstrap border-* to
werkr-border-* classes
- Update GanttTab CSS and StatusToClassName, RunSparkline GetFill,
RunGridView GetStatusIcon to use renamed variables and add Cancelled
status throughout
- Update graph-ui status-overlay.ts and timeline-styles.ts to use
renamed variables and add Cancelled status
1.6.1: RunDetail Grid View Integration
- Add 5th "Grid" tab to RunDetail with lazy-loaded step × run matrix
via RunGridView component (limited to 20 recent runs)
- Reuse already-loaded detail for current run to minimize API calls
- Wire cell selection: same-run clicks open step detail panel,
cross-run clicks navigate to that run's detail page
- Handle real-time SignalR step status updates in grid data
Rewrite Testing.md, add SSE to Architecture.md communication model, add VS Code test tasks for API integration and graph-ui.
…ile monitor trigger, validation fixes) Epics 1.8.3–1.8.4 (validation & bug fixes): - Fix gantt-pending CSS using wrong color variable (--werkr-status-cancelled → --werkr-status-pending) - Fix Guid.Parse → TryParse for ConnectionId in JobReportingGrpcService - Add Include(Step.Task) to eliminate redundant query in job reporting - Log TryWrite failures in OutputStreamingGrpcService instead of silent discard - Fix critical timezone bug in monthly WeekAndDay recurrence (bypassed ConvertToUtc) - Add missing ActionCategory attribute on ForEachHandler - Add httpbin to docker-compose for webhook/upload receiver tests Epic 1.8.1 (ForEach composite node POC): - New CompositeType enum, WorkflowStep composite fields, Workflow child workflow fields - Extended ScheduleSync.proto with composite step fields and ChildWorkflowDefinition - Auto-create child workflow on composite step creation, list filtering, cascade delete - New CompositeNodeExecutor class for ForEach iteration over child DAG - StepPalette ForEach entry, NodeConfigPanel composite config, DagEditor composite handling - graph-ui double-border composite node rendering - Removed old ForEachHandler/ForEachParameters (replaced by composite node model) Epic 1.8.2 (file monitor trigger POC): - FileMonitorTrigger entity with VariableSource.TriggerContext - TriggerEvent.proto with ReportFileMonitorEvent RPC - Agent-side FileMonitorService (FileSystemWatcher, debounce, path allowlist) - TriggerEventClient with encrypted envelope pattern - API-side TriggerEventGrpcService (event → workflow run creation) - RunNowService refactored to accept VariableSource parameter - REST CRUD endpoints for trigger management - UI list and edit pages for file monitor triggers BREAKING CHANGE: ForEach action handler removed from ActionRegistry — replaced by composite node model. Existing workflows using the ForEach action type must be migrated to use a ForEach composite step.
- Introduced Dockerfile for validating the Werkr Server .deb build pipeline. - Created Docker Compose file for validating .deb-installed binaries with PostgreSQL and TLS. - Added scripts for building .deb packages for both Werkr Server and Agent. - Implemented systemd service files for Werkr Server and Agent with environment configurations. - Added configuration management for Werkr Server and Agent, including conffiles and debconf templates. - Established post-installation and removal scripts to manage system users, directories, and services. - Included health checks for services in Docker Compose. - Enhanced error handling and logging in the build scripts.
…ponents - Added AuditClient service to handle logging of audit events via HTTP. - Integrated audit logging into user authentication processes, including login, MFA verification, and account management. - Introduced a new Audit Log page for Admins to view audit events with filtering and export options. - Updated API key management endpoints to log creation and revocation events. - Enhanced Schedule Setup modal to display audit logs related to schedule changes. - Added JavaScript function for downloading files in JSON and CSV formats. - Updated navigation menu to include a Reporting section for audit logs.
…ement - Replaced IHttpClientFactory with ApiServiceAccessor in DagEditor, Detail, Index, RunDetail, Runs, GanttTab, ScheduleSetupModal, StepDetailPanel, TagInput, TaskSetupModal components. - Updated API call methods to utilize ApiServiceAccessor for GET, POST, PUT, and DELETE requests. - Introduced BlazorUserTokenProvider to generate user-specific JWTs for API requests. - Implemented UserTokenContext to manage user tokens across async calls. - Added ServiceAuthForwardingHandler for system-level API calls using service identity. - Modified AgentHealthMonitorService to use the new system client for health checks. - Enhanced AuditClient and SavedFilterService to set user tokens before API interactions.
…x pattern with an ResponseMetadata field.
- integrate the TimeZoneNames package so we can display friendly tz abbreviations - update schedules to allow specific UTC offsets - Add urgency sending flow
…s, delivery pipeline
Implement the core notification system with email, webhook, and in-app channels for workflow events, security events, and system health.
- Channel architecture with INotificationChannel interface, event category registry (5 categories, 14 event types), encrypted channel config entity, CRUD + test-delivery endpoints, and 11 new audit event types.
- Email channel via MailKit SMTP with HTML + plain-text fallback.
- Webhook channel with HTTP POST JSON, HMAC-SHA-512 signing, and header-based or credential-store auth.
- In-app notifications with UserNotification entity, DB persistence, push via INotificationHubService, and user notification API.
- Notification templates with {{variable}} interpolation, 42 default templates (14 events × 3 channels), and CRUD + reset endpoints.
- Subscription model (per-workflow, tag-based, global) with quiet-hours preferences, persistent retry delivery queue, background retry service, retention providers, and subscription/preference/dead-letter API endpoints.
- Pin Microsoft.Extensions.Http 10.0.4; EF Core migrations for Postgres and SQLite (6 new tables).
Merge up the WIP spec-gap and documentation improvements.
…esign-spec Create Official Design Specification / Product Manifest and begin implementing spec-gap improvements.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.