Skip to content

Releases: breonwilliams/flowmint-workflows

FlowMint Workflows v0.7.0

Choose a tag to compare

@breonwilliams breonwilliams released this 03 Sep 11:57
  • Added: workflow emails and messages can now use the option LABEL a visitor actually chose, not the value stored behind it. {{ labels.workshop }} writes "Hand-Cut Joinery Intensive" where {{ data.workshop }} writes "joinery". Machine steps keep using the raw value, so nothing existing changes.
  • Fixed: uploaded-file details in workflows are now documented as they actually behave — keyed by field name, with no file URL, and a shape that changes when more than one file is attached. Each of those failed silently before, producing a workflow that reported success while sending nothing.
  • Fixed: the connector could not reach an HTTPS local development site.

v0.6.8

Choose a tag to compare

@breonwilliams breonwilliams released this 13 Aug 01:05

Connector setup: the Copy Command button now sits below the code block instead of overlaying it, fixing an overlap and a color-contrast issue.

FlowMint Workflows v0.6.7

Choose a tag to compare

@breonwilliams breonwilliams released this 23 Jul 16:24

Adds AGENTS.md developer/AI reference documentation. No functional changes.

v0.6.6

Choose a tag to compare

@breonwilliams breonwilliams released this 11 Jul 14:25

Changelog

All notable changes to FlowMint Workflows will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.6.6] — 2026-07-11

Fixed

  • Plugin Check compliance sweep (2026-07-11). Added the required translators: comments to the failure notifier's placeholder-bearing __() calls; raised Requires at least from 5.0 to 5.6 (the Cowork connector depends on the Application Passwords API, WP 5.6+, and scheduled triggers use wp_timezone(), WP 5.3+ — the header now matches reality instead of under-promising); bumped Tested up to to 7.0. (includes/Core/class-fmw-failure-notifier.php, flowmint-workflows.php, readme.txt, CLAUDE.md.)

[0.6.5] — 2026-07-04

Added

  • Failure notifications. FMW_Failure_Notifier (includes/Core/class-fmw-failure-notifier.php) listens to fmw_workflow_run_failed at priority 100 and pushes a plain-text alert when a run permanently fails (exhausts all retries): Slack incoming webhook when the slack_webhook credential is configured (non-blocking POST, 3s timeout), otherwise email to the notification_email credential falling back to the site admin_email — every site gets a signal out of the box. The alert carries the workflow name, error code/message, entry context, and a deep link to the run for one-click inspect/replay. Defensively wrapped so it can never break the failure path it observes; fires only after max retries so every alert is a final, human-worthy failure. Filters: fmw_failure_notification_enabled, fmw_failure_notification_message. Closes the long-documented "failed runs are only visible in the admin UI" operational gap.

Changed

  • bin/build-release.sh now verifies the release ZIP's internal structure after packaging (required nested paths incl. vendor/autoload.php and Action Scheduler) and aborts on a flattened or vendor-less archive — turning the documented "Composer not on PATH → dead-on-arrival ZIP" gotcha into a hard build failure. Build tooling only; not shipped in the ZIP.
  • Documentation truthfulness pass: CLAUDE.md corrected to shipped reality (phase table, pforms_* hook names since FRE 1.8.0, FRE 1.8.0 minimum, MCP layout, known gaps) and the FMW_DB_VERSION 0.3.0 no-DDL convention documented at the constant.

[0.6.4] — 2026-06-02

Fixed

  • Conditional step took the else branch every time, regardless of the if expression. FMW_Step_Conditional::execute() was reading $this->config['if'] — i.e. the POST-interpolation config the executor passed in. The executor runs the entire step config through FMW_Interpolator::interpolate() before instantiating the step, including the conditional's if field. Since the interpolator only understands {{ context.path }} substitution and has no concept of comparison/logical operators, an expression like {{ data.urgency == 'high' }} came out as an empty string by the time it reached the conditional step. FMW_Expression::evaluate('') correctly returns false, so every conditional silently took the else branch. The previous code carried a // Workaround: ... comment in the step that explicitly admitted the implementation didn't work — it shipped anyway. Caught during pressure testing of a real urgency-routing workflow that submitted two entries with different urgency values, both produced identical branch behavior.

    The fix plumbs the RAW (pre-interpolation) config through alongside the interpolated one:

    • FMW_Step_Base gains a $raw_config property, populated from $step_definition['raw_config'] and falling back to $this->config for backward compat with any direct-instantiation callers.
    • FMW_Workflow_Executor includes 'raw_config' => $raw_config in the step definition it constructs.
    • FMW_Step_Conditional reads $this->raw_config['if'] for the expression. Comparison operators now survive into the expression evaluator, which builds its own interpolator pass to resolve the {{ context.path }} blocks correctly.
    • FMW_Step_Conditional also pulls then / else step arrays from raw_config when available, so a nested conditional inside a then branch gets its own if field un-interpolated. Without this, the nested-conditional case would reintroduce the bug at the inner level.

Notes

  • No database schema changes. FMW_DB_VERSION unchanged at 0.3.0.
  • No new step types, no API changes.
  • Existing non-conditional workflows are unaffected — they continue to read $this->config, which still receives the same pre-interpolated values it always has.
  • skip_if clauses (the FMW_Expression docblock mentions them) and the try_catch step both also use the expression evaluator. skip_if was not exercised by pressure testing and may or may not have the same drift; will be audited separately. try_catch's nested try/catch arrays contain step definitions that re-enter the executor, so they're not affected by this fix one way or the other.

[0.6.3] — 2026-06-02

Fixed

  • Stale rename guard in workflow validatorFMW_Workflow_Validator::validate_full() was checking function_exists( 'fre' ) before consulting the Promptless Forms registry to verify form_id existence. The function was renamed fre()pforms() in PForms v1.8.0; the guard was checking the legacy name. Every form-id existence check silently fell through to the "FormEngine not loaded" warning even when Promptless Forms was present and the registry was queryable. Now checks function_exists( 'pforms' ). Caught during pressure testing.
  • Update endpoint dropped trigger inference when caller omitted form_idFMW_REST_Workflows::update() did not pre-fetch the existing workflow's form_id before re-validating, so a PATCH that supplied a new config without an explicit trigger block — but expected the existing form binding to be preserved per the standard REST "omitted = unchanged" contract — failed with Missing required field: trigger. Now pulls the existing form_id from the database and injects it into the validation payload, making update() symmetric with create() when both receive a config that lacks an explicit trigger.

Changed (documentation / DX)

  • MCP connector descriptions corrected on step shapeflowmint-connector.js step shape descriptions said { id, type, config, on_error?, when? } but the validator requires name, not id. Two description strings updated to { name, type, config, on_error?, when? } so first-time workflow creates don't fail with a confusing "missing or invalid 'name'" error. Important for users on existing connector installs: the connector JS lives at ~/flowmint-mcp/flowmint-connector.js on each Mac, downloaded by the connector setup command. Updating the plugin does NOT update the local copy. Re-run the connector setup command from WP admin → FlowMint Workflows → Claude Connection to pull the corrected descriptions.
  • Preflight response now documents the workflow context shape — added a context_shape block listing every top-level namespace accessible via {{ … }} interpolation (data, entry, entry_files, run, workflow, form, steps, vars), with descriptions, an example, and a common_traps list calling out the two patterns that produce silent empty-string substitutions: entry.fields.* (form fields are at data.*, not entry.fields.*) and steps.<type>.* (use the step NAME, not the type). Resolves the friction that surfaced during pressure testing of session_registrationsession_registration_confirmation, where guessed interpolation paths produced an empty to field in the email step and a generic config_error.
  • MCP tool description now references current namesflowmint_create_workflow description previously referred to "fre_submission_complete" (the legacy hook name) and "an FRE form". Updated to "pforms_submission_complete" and "Promptless Forms" to match the v0.6.2 rename. No behavior change.

Notes

  • No database schema changes. FMW_DB_VERSION unchanged at 0.3.0.
  • Minimum required Promptless Forms version unchanged at 1.8.0.
  • Internal symbol surface (FMW_* classes, fmw_* actions/filters, pforms_submission_complete hook listener wiring) unchanged.

[0.6.2] — 2026-06-02

Fixed

  • Dependency check now treats Promptless Forms as present when either the PForms_VERSION constant is defined OR the Promptless_Forms class exists. Single-signal checks against the constant were observed to false-positive on certain managed-host environments (Bluehost's stack in testing) where the constant was not defined at admin_notices time despite Promptless Forms being active and the admin pages rendering correctly. The class fallback closes that gap so FlowMint stops showing a spurious "missing dependency" error when its prerequisite plugin is actually present and working. Version-compare enforcement still requires the constant — when only the class is detectable we accept "present" and let any real version mismatch surface as step-run failures in run history rather than as a blanket block.

Changed

  • User-facing admin notices and the plugin Description header updated from "Form Runtime Engine" to "Promptless Forms" — Promptless Forms shipped on WordPress.org at the renamed slug in v1.8.0 and FlowMint's surface text was still pointing at the legacy name.
  • Internal symbol surface (FMW_REQUIRED_FRE_VERSION constant, FormEngine step categories, internal class names referencing Fre) is unchanged — those are internal-only and renaming would invalidate stored workflow JSON without behavioral benefit. Only user-visible strings were touched.

Notes

  • No database schema changes; FMW_DB_VERSION unchanged at 0.3.0.
  • Minimum required Promptless Forms version unchanged at 1.8.0.

[0.6.1] — 2026-05-17

Changed

  • Renamed connector admin page from "Claude Connection" to "C...
Read more

FlowMint Workflows v0.6.5

Choose a tag to compare

@breonwilliams breonwilliams released this 06 Jul 22:09

Adds failure notifications: when a workflow run permanently fails, FlowMint alerts via Slack (slack_webhook credential) or email (notification_email credential / admin email) with a deep link to inspect and replay the run. No schema or workflow changes — safe update from any 0.6.x.

v0.6.4 - fix conditional step always taking else branch

Choose a tag to compare

@breonwilliams breonwilliams released this 02 Jun 19:51

Changelog

All notable changes to FlowMint Workflows will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.6.4] — 2026-06-02

Fixed

  • Conditional step took the else branch every time, regardless of the if expression. FMW_Step_Conditional::execute() was reading $this->config['if'] — i.e. the POST-interpolation config the executor passed in. The executor runs the entire step config through FMW_Interpolator::interpolate() before instantiating the step, including the conditional's if field. Since the interpolator only understands {{ context.path }} substitution and has no concept of comparison/logical operators, an expression like {{ data.urgency == 'high' }} came out as an empty string by the time it reached the conditional step. FMW_Expression::evaluate('') correctly returns false, so every conditional silently took the else branch. The previous code carried a // Workaround: ... comment in the step that explicitly admitted the implementation didn't work — it shipped anyway. Caught during pressure testing of a real urgency-routing workflow that submitted two entries with different urgency values, both produced identical branch behavior.

    The fix plumbs the RAW (pre-interpolation) config through alongside the interpolated one:

    • FMW_Step_Base gains a $raw_config property, populated from $step_definition['raw_config'] and falling back to $this->config for backward compat with any direct-instantiation callers.
    • FMW_Workflow_Executor includes 'raw_config' => $raw_config in the step definition it constructs.
    • FMW_Step_Conditional reads $this->raw_config['if'] for the expression. Comparison operators now survive into the expression evaluator, which builds its own interpolator pass to resolve the {{ context.path }} blocks correctly.
    • FMW_Step_Conditional also pulls then / else step arrays from raw_config when available, so a nested conditional inside a then branch gets its own if field un-interpolated. Without this, the nested-conditional case would reintroduce the bug at the inner level.

Notes

  • No database schema changes. FMW_DB_VERSION unchanged at 0.3.0.
  • No new step types, no API changes.
  • Existing non-conditional workflows are unaffected — they continue to read $this->config, which still receives the same pre-interpolated values it always has.
  • skip_if clauses (the FMW_Expression docblock mentions them) and the try_catch step both also use the expression evaluator. skip_if was not exercised by pressure testing and may or may not have the same drift; will be audited separately. try_catch's nested try/catch arrays contain step definitions that re-enter the executor, so they're not affected by this fix one way or the other.

[0.6.3] — 2026-06-02

Fixed

  • Stale rename guard in workflow validatorFMW_Workflow_Validator::validate_full() was checking function_exists( 'fre' ) before consulting the Promptless Forms registry to verify form_id existence. The function was renamed fre()pforms() in PForms v1.8.0; the guard was checking the legacy name. Every form-id existence check silently fell through to the "FormEngine not loaded" warning even when Promptless Forms was present and the registry was queryable. Now checks function_exists( 'pforms' ). Caught during pressure testing.
  • Update endpoint dropped trigger inference when caller omitted form_idFMW_REST_Workflows::update() did not pre-fetch the existing workflow's form_id before re-validating, so a PATCH that supplied a new config without an explicit trigger block — but expected the existing form binding to be preserved per the standard REST "omitted = unchanged" contract — failed with Missing required field: trigger. Now pulls the existing form_id from the database and injects it into the validation payload, making update() symmetric with create() when both receive a config that lacks an explicit trigger.

Changed (documentation / DX)

  • MCP connector descriptions corrected on step shapeflowmint-connector.js step shape descriptions said { id, type, config, on_error?, when? } but the validator requires name, not id. Two description strings updated to { name, type, config, on_error?, when? } so first-time workflow creates don't fail with a confusing "missing or invalid 'name'" error. Important for users on existing connector installs: the connector JS lives at ~/flowmint-mcp/flowmint-connector.js on each Mac, downloaded by the connector setup command. Updating the plugin does NOT update the local copy. Re-run the connector setup command from WP admin → FlowMint Workflows → Claude Connection to pull the corrected descriptions.
  • Preflight response now documents the workflow context shape — added a context_shape block listing every top-level namespace accessible via {{ … }} interpolation (data, entry, entry_files, run, workflow, form, steps, vars), with descriptions, an example, and a common_traps list calling out the two patterns that produce silent empty-string substitutions: entry.fields.* (form fields are at data.*, not entry.fields.*) and steps.<type>.* (use the step NAME, not the type). Resolves the friction that surfaced during pressure testing of session_registrationsession_registration_confirmation, where guessed interpolation paths produced an empty to field in the email step and a generic config_error.
  • MCP tool description now references current namesflowmint_create_workflow description previously referred to "fre_submission_complete" (the legacy hook name) and "an FRE form". Updated to "pforms_submission_complete" and "Promptless Forms" to match the v0.6.2 rename. No behavior change.

Notes

  • No database schema changes. FMW_DB_VERSION unchanged at 0.3.0.
  • Minimum required Promptless Forms version unchanged at 1.8.0.
  • Internal symbol surface (FMW_* classes, fmw_* actions/filters, pforms_submission_complete hook listener wiring) unchanged.

[0.6.2] — 2026-06-02

Fixed

  • Dependency check now treats Promptless Forms as present when either the PForms_VERSION constant is defined OR the Promptless_Forms class exists. Single-signal checks against the constant were observed to false-positive on certain managed-host environments (Bluehost's stack in testing) where the constant was not defined at admin_notices time despite Promptless Forms being active and the admin pages rendering correctly. The class fallback closes that gap so FlowMint stops showing a spurious "missing dependency" error when its prerequisite plugin is actually present and working. Version-compare enforcement still requires the constant — when only the class is detectable we accept "present" and let any real version mismatch surface as step-run failures in run history rather than as a blanket block.

Changed

  • User-facing admin notices and the plugin Description header updated from "Form Runtime Engine" to "Promptless Forms" — Promptless Forms shipped on WordPress.org at the renamed slug in v1.8.0 and FlowMint's surface text was still pointing at the legacy name.
  • Internal symbol surface (FMW_REQUIRED_FRE_VERSION constant, FormEngine step categories, internal class names referencing Fre) is unchanged — those are internal-only and renaming would invalidate stored workflow JSON without behavioral benefit. Only user-visible strings were touched.

Notes

  • No database schema changes; FMW_DB_VERSION unchanged at 0.3.0.
  • Minimum required Promptless Forms version unchanged at 1.8.0.

[0.6.1] — 2026-05-17

Changed

  • Renamed connector admin page from "Claude Connection" to "Connector" (menu) / "The FlowMint Connector" (page title) — vendor-neutral naming future-proofed for additional AI clients
  • Redesigned connector page with card-based layout, clearer 3-step setup flow, and improved connection status display
  • Added warning notice when Application Passwords are unavailable (requires HTTPS or WP_ENVIRONMENT_TYPE='local')

[0.6.0] — 2026-05-15

Added — Scheduled workflow triggers

Workflows can now be triggered on a recurring schedule (hourly / twice-daily / daily / weekly) in addition to form submissions. Closes the "Scheduled workflows" item that was explicitly deferred to v2+ in docs/ROADMAP.md — the architecture left room for it, and v0.6.0 cashes that in. Full design contract: docs/DESIGN_SCHEDULED_TRIGGERS.md. User-facing guide: docs/SCHEDULED_WORKFLOWS.md.

New trigger abstraction.

  • Workflow JSON gains a trigger block. Two trigger types in v0.6: { type: "form", form_id: "…" } (form-triggered, the existing pattern made explicit) and { type: "schedule", interval: "…", hour: …, minute: …, day_of_week: … } (scheduled, new).
  • Legacy workflows that have just a top-level form_id continue to work — the validator normalizes them into the v0.6 shape transparently. Existing workflows on production sites do NOT need their JSON rewritten.
  • The REST API accepts the new trigger block at the wrapper level for convenience (alongside id, title, config), or inside the config JSON. Preflight reports supported_trigger_types: ["form", "schedule"] so MCP clients can introspect capabilities.

New step types (FormEngine category).

  • fre_list_entries — Query FE entries by form, status, and/or age. Backed by FRE_Entry_Query (FRE 1.6.0+). Hard cap of 1000 rows per call. Returns oldest-first. Output includes a hit_limit flag so the next tick can pick up the overflow.
  • fre_delete_entries — Bulk-delete by ID list (accepts entry objects from fre_list_entries OR bare integer IDs). Idempotent — re-running on already-deleted IDs returns already_gone rather than erroring. Per-id failure tolerance — one bad entry doesn't sink the batch; fail...
Read more

v0.6.3 - DX fixes from pressure testing

Choose a tag to compare

@breonwilliams breonwilliams released this 02 Jun 19:25

Changelog

All notable changes to FlowMint Workflows will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.6.3] — 2026-06-02

Fixed

  • Stale rename guard in workflow validatorFMW_Workflow_Validator::validate_full() was checking function_exists( 'fre' ) before consulting the Promptless Forms registry to verify form_id existence. The function was renamed fre()pforms() in PForms v1.8.0; the guard was checking the legacy name. Every form-id existence check silently fell through to the "FormEngine not loaded" warning even when Promptless Forms was present and the registry was queryable. Now checks function_exists( 'pforms' ). Caught during pressure testing.
  • Update endpoint dropped trigger inference when caller omitted form_idFMW_REST_Workflows::update() did not pre-fetch the existing workflow's form_id before re-validating, so a PATCH that supplied a new config without an explicit trigger block — but expected the existing form binding to be preserved per the standard REST "omitted = unchanged" contract — failed with Missing required field: trigger. Now pulls the existing form_id from the database and injects it into the validation payload, making update() symmetric with create() when both receive a config that lacks an explicit trigger.

Changed (documentation / DX)

  • MCP connector descriptions corrected on step shapeflowmint-connector.js step shape descriptions said { id, type, config, on_error?, when? } but the validator requires name, not id. Two description strings updated to { name, type, config, on_error?, when? } so first-time workflow creates don't fail with a confusing "missing or invalid 'name'" error. Important for users on existing connector installs: the connector JS lives at ~/flowmint-mcp/flowmint-connector.js on each Mac, downloaded by the connector setup command. Updating the plugin does NOT update the local copy. Re-run the connector setup command from WP admin → FlowMint Workflows → Claude Connection to pull the corrected descriptions.
  • Preflight response now documents the workflow context shape — added a context_shape block listing every top-level namespace accessible via {{ … }} interpolation (data, entry, entry_files, run, workflow, form, steps, vars), with descriptions, an example, and a common_traps list calling out the two patterns that produce silent empty-string substitutions: entry.fields.* (form fields are at data.*, not entry.fields.*) and steps.<type>.* (use the step NAME, not the type). Resolves the friction that surfaced during pressure testing of session_registrationsession_registration_confirmation, where guessed interpolation paths produced an empty to field in the email step and a generic config_error.
  • MCP tool description now references current namesflowmint_create_workflow description previously referred to "fre_submission_complete" (the legacy hook name) and "an FRE form". Updated to "pforms_submission_complete" and "Promptless Forms" to match the v0.6.2 rename. No behavior change.

Notes

  • No database schema changes. FMW_DB_VERSION unchanged at 0.3.0.
  • Minimum required Promptless Forms version unchanged at 1.8.0.
  • Internal symbol surface (FMW_* classes, fmw_* actions/filters, pforms_submission_complete hook listener wiring) unchanged.

[0.6.2] — 2026-06-02

Fixed

  • Dependency check now treats Promptless Forms as present when either the PForms_VERSION constant is defined OR the Promptless_Forms class exists. Single-signal checks against the constant were observed to false-positive on certain managed-host environments (Bluehost's stack in testing) where the constant was not defined at admin_notices time despite Promptless Forms being active and the admin pages rendering correctly. The class fallback closes that gap so FlowMint stops showing a spurious "missing dependency" error when its prerequisite plugin is actually present and working. Version-compare enforcement still requires the constant — when only the class is detectable we accept "present" and let any real version mismatch surface as step-run failures in run history rather than as a blanket block.

Changed

  • User-facing admin notices and the plugin Description header updated from "Form Runtime Engine" to "Promptless Forms" — Promptless Forms shipped on WordPress.org at the renamed slug in v1.8.0 and FlowMint's surface text was still pointing at the legacy name.
  • Internal symbol surface (FMW_REQUIRED_FRE_VERSION constant, FormEngine step categories, internal class names referencing Fre) is unchanged — those are internal-only and renaming would invalidate stored workflow JSON without behavioral benefit. Only user-visible strings were touched.

Notes

  • No database schema changes; FMW_DB_VERSION unchanged at 0.3.0.
  • Minimum required Promptless Forms version unchanged at 1.8.0.

[0.6.1] — 2026-05-17

Changed

  • Renamed connector admin page from "Claude Connection" to "Connector" (menu) / "The FlowMint Connector" (page title) — vendor-neutral naming future-proofed for additional AI clients
  • Redesigned connector page with card-based layout, clearer 3-step setup flow, and improved connection status display
  • Added warning notice when Application Passwords are unavailable (requires HTTPS or WP_ENVIRONMENT_TYPE='local')

[0.6.0] — 2026-05-15

Added — Scheduled workflow triggers

Workflows can now be triggered on a recurring schedule (hourly / twice-daily / daily / weekly) in addition to form submissions. Closes the "Scheduled workflows" item that was explicitly deferred to v2+ in docs/ROADMAP.md — the architecture left room for it, and v0.6.0 cashes that in. Full design contract: docs/DESIGN_SCHEDULED_TRIGGERS.md. User-facing guide: docs/SCHEDULED_WORKFLOWS.md.

New trigger abstraction.

  • Workflow JSON gains a trigger block. Two trigger types in v0.6: { type: "form", form_id: "…" } (form-triggered, the existing pattern made explicit) and { type: "schedule", interval: "…", hour: …, minute: …, day_of_week: … } (scheduled, new).
  • Legacy workflows that have just a top-level form_id continue to work — the validator normalizes them into the v0.6 shape transparently. Existing workflows on production sites do NOT need their JSON rewritten.
  • The REST API accepts the new trigger block at the wrapper level for convenience (alongside id, title, config), or inside the config JSON. Preflight reports supported_trigger_types: ["form", "schedule"] so MCP clients can introspect capabilities.

New step types (FormEngine category).

  • fre_list_entries — Query FE entries by form, status, and/or age. Backed by FRE_Entry_Query (FRE 1.6.0+). Hard cap of 1000 rows per call. Returns oldest-first. Output includes a hit_limit flag so the next tick can pick up the overflow.
  • fre_delete_entries — Bulk-delete by ID list (accepts entry objects from fre_list_entries OR bare integer IDs). Idempotent — re-running on already-deleted IDs returns already_gone rather than erroring. Per-id failure tolerance — one bad entry doesn't sink the batch; failures land in a failed array.

Database schema (v0.2.0 migration).

  • wp_fmw_workflows.form_id is now NULLABLE (scheduled workflows have no bound form).
  • New wp_fmw_workflows.trigger_type column (VARCHAR(32) NOT NULL DEFAULT 'form') indexed via new composite key idx_trigger_type (trigger_type, enabled) for efficient "find all enabled scheduled workflows" lookups by FMW_Schedule_Listener.
  • Migration is additive, idempotent, and probes column / index state via SHOW COLUMNS / SHOW INDEX before each ALTER. Existing rows are correctly classified as trigger_type = 'form' by the column default. Rollback to v0.5.0 does NOT require dropping the new column — the older code simply ignores it.

New class: FMW_Schedule_Listener (includes/Core/class-fmw-schedule-listener.php).

  • Mirrors FMW_Submission_Listener but for the scheduled trigger path.
  • Subscribes to fmw_workflow_saved / fmw_workflow_disabled / fmw_workflow_deleted (newly fired by the repository) — registers an Action Scheduler recurring event when a scheduled workflow is saved + enabled, unregisters when it's disabled or deleted.
  • Tick handler creates a queued run via FMW_Run_Repository::create_pending_scheduled (form_id = '', entry_id = 0 sentinels per design §5.2), then enqueues fmw_run_workflow async action — same downstream path as form submissions.
  • Timezone-aware first-tick computation: daily and weekly intervals use site-local time (wp_timezone()), matching how Settings → General displays "site timezone."

Daily reconciliation pass.

  • New AS recurring action fmw_reconcile_scheduled_events fires daily and reconciles AS recurring events with the workflows table. Drift correction: even if an AS action was lost or wiped, the next reconciliation rebuilds it.
  • Bootstrap is self-healing: on the first plugins_loaded after v0.6.0 lands, schedules the daily reconciliation AND runs an immediate pass so any pre-existing scheduled workflows get their cron events without a 24h wait. Hooked on init priority 20 (after AS's data store initialization at init priority 1).

Validator additions.

  • FMW_Workflow_Validator::normalize() — public static method that converts legacy → v0.6 shape on a copy. Idempotent.
  • trigger block validation: enum-checked type ('form' | 'schedule'), enum-checked interval ('hourly' | 'twicedaily' | 'daily' | 'weekly'), range-checked hour (0–23), minute (0–59), day_of_week (1–7 ISO-8601).
  • New warning (not error) for scheduled workflows that interpolate {{ data.* }} / {{ entry.* }} / {{ entry_files.* }} — scheduled runs have no FE entry context, so those referenc...
Read more

v0.6.2 - dependency check + Promptless Forms text cleanup

Choose a tag to compare

@breonwilliams breonwilliams released this 02 Jun 17:22

Changelog

All notable changes to FlowMint Workflows will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.6.2] — 2026-06-02

Fixed

  • Dependency check now treats Promptless Forms as present when either the PForms_VERSION constant is defined OR the Promptless_Forms class exists. Single-signal checks against the constant were observed to false-positive on certain managed-host environments (Bluehost's stack in testing) where the constant was not defined at admin_notices time despite Promptless Forms being active and the admin pages rendering correctly. The class fallback closes that gap so FlowMint stops showing a spurious "missing dependency" error when its prerequisite plugin is actually present and working. Version-compare enforcement still requires the constant — when only the class is detectable we accept "present" and let any real version mismatch surface as step-run failures in run history rather than as a blanket block.

Changed

  • User-facing admin notices and the plugin Description header updated from "Form Runtime Engine" to "Promptless Forms" — Promptless Forms shipped on WordPress.org at the renamed slug in v1.8.0 and FlowMint's surface text was still pointing at the legacy name.
  • Internal symbol surface (FMW_REQUIRED_FRE_VERSION constant, FormEngine step categories, internal class names referencing Fre) is unchanged — those are internal-only and renaming would invalidate stored workflow JSON without behavioral benefit. Only user-visible strings were touched.

Notes

  • No database schema changes; FMW_DB_VERSION unchanged at 0.3.0.
  • Minimum required Promptless Forms version unchanged at 1.8.0.

[0.6.1] — 2026-05-17

Changed

  • Renamed connector admin page from "Claude Connection" to "Connector" (menu) / "The FlowMint Connector" (page title) — vendor-neutral naming future-proofed for additional AI clients
  • Redesigned connector page with card-based layout, clearer 3-step setup flow, and improved connection status display
  • Added warning notice when Application Passwords are unavailable (requires HTTPS or WP_ENVIRONMENT_TYPE='local')

[0.6.0] — 2026-05-15

Added — Scheduled workflow triggers

Workflows can now be triggered on a recurring schedule (hourly / twice-daily / daily / weekly) in addition to form submissions. Closes the "Scheduled workflows" item that was explicitly deferred to v2+ in docs/ROADMAP.md — the architecture left room for it, and v0.6.0 cashes that in. Full design contract: docs/DESIGN_SCHEDULED_TRIGGERS.md. User-facing guide: docs/SCHEDULED_WORKFLOWS.md.

New trigger abstraction.

  • Workflow JSON gains a trigger block. Two trigger types in v0.6: { type: "form", form_id: "…" } (form-triggered, the existing pattern made explicit) and { type: "schedule", interval: "…", hour: …, minute: …, day_of_week: … } (scheduled, new).
  • Legacy workflows that have just a top-level form_id continue to work — the validator normalizes them into the v0.6 shape transparently. Existing workflows on production sites do NOT need their JSON rewritten.
  • The REST API accepts the new trigger block at the wrapper level for convenience (alongside id, title, config), or inside the config JSON. Preflight reports supported_trigger_types: ["form", "schedule"] so MCP clients can introspect capabilities.

New step types (FormEngine category).

  • fre_list_entries — Query FE entries by form, status, and/or age. Backed by FRE_Entry_Query (FRE 1.6.0+). Hard cap of 1000 rows per call. Returns oldest-first. Output includes a hit_limit flag so the next tick can pick up the overflow.
  • fre_delete_entries — Bulk-delete by ID list (accepts entry objects from fre_list_entries OR bare integer IDs). Idempotent — re-running on already-deleted IDs returns already_gone rather than erroring. Per-id failure tolerance — one bad entry doesn't sink the batch; failures land in a failed array.

Database schema (v0.2.0 migration).

  • wp_fmw_workflows.form_id is now NULLABLE (scheduled workflows have no bound form).
  • New wp_fmw_workflows.trigger_type column (VARCHAR(32) NOT NULL DEFAULT 'form') indexed via new composite key idx_trigger_type (trigger_type, enabled) for efficient "find all enabled scheduled workflows" lookups by FMW_Schedule_Listener.
  • Migration is additive, idempotent, and probes column / index state via SHOW COLUMNS / SHOW INDEX before each ALTER. Existing rows are correctly classified as trigger_type = 'form' by the column default. Rollback to v0.5.0 does NOT require dropping the new column — the older code simply ignores it.

New class: FMW_Schedule_Listener (includes/Core/class-fmw-schedule-listener.php).

  • Mirrors FMW_Submission_Listener but for the scheduled trigger path.
  • Subscribes to fmw_workflow_saved / fmw_workflow_disabled / fmw_workflow_deleted (newly fired by the repository) — registers an Action Scheduler recurring event when a scheduled workflow is saved + enabled, unregisters when it's disabled or deleted.
  • Tick handler creates a queued run via FMW_Run_Repository::create_pending_scheduled (form_id = '', entry_id = 0 sentinels per design §5.2), then enqueues fmw_run_workflow async action — same downstream path as form submissions.
  • Timezone-aware first-tick computation: daily and weekly intervals use site-local time (wp_timezone()), matching how Settings → General displays "site timezone."

Daily reconciliation pass.

  • New AS recurring action fmw_reconcile_scheduled_events fires daily and reconciles AS recurring events with the workflows table. Drift correction: even if an AS action was lost or wiped, the next reconciliation rebuilds it.
  • Bootstrap is self-healing: on the first plugins_loaded after v0.6.0 lands, schedules the daily reconciliation AND runs an immediate pass so any pre-existing scheduled workflows get their cron events without a 24h wait. Hooked on init priority 20 (after AS's data store initialization at init priority 1).

Validator additions.

  • FMW_Workflow_Validator::normalize() — public static method that converts legacy → v0.6 shape on a copy. Idempotent.
  • trigger block validation: enum-checked type ('form' | 'schedule'), enum-checked interval ('hourly' | 'twicedaily' | 'daily' | 'weekly'), range-checked hour (0–23), minute (0–59), day_of_week (1–7 ISO-8601).
  • New warning (not error) for scheduled workflows that interpolate {{ data.* }} / {{ entry.* }} / {{ entry_files.* }} — scheduled runs have no FE entry context, so those references silently resolve to empty string at runtime; the warning surfaces the typo at save time.

Job handler.

  • FMW_Workflow_Job::build_context() recognizes the scheduled-run sentinel (entry_id === 0) and skips the FE entry fetch entirely. The context's entry, data, entry_files stay empty arrays; the interpolator already handles missing variables by returning empty string, so existing step implementations continue to work unchanged.

Repository.

  • FMW_Workflow_Repository::create / update now normalize config and persist trigger_type column, allow NULL form_id for scheduled workflows.
  • New FMW_Workflow_Repository::get_all_by_trigger_type($type, $args) for the listener's reconciliation pass.
  • get_for_form() tightened with explicit trigger_type = 'form' filter — a misconfigured scheduled workflow that somehow has a non-NULL form_id can never be picked up by the FRE submission listener as if it were form-triggered.
  • Repository now fires fmw_workflow_saved (on create + update), fmw_workflow_disabled (on enabled 1→0 transition), and fmw_workflow_deleted (on delete) actions.

REST.

  • /workflows list endpoint accepts a trigger_type query parameter.
  • /preflight reports supported_trigger_types.
  • All other endpoints accept the new trigger block in request bodies and return it in responses. Backwards-compat for legacy form_id at the wrapper level: still works, still normalized to trigger.type = "form" internally.

Verification (local Flywheel site).
99 of 99 smoke checks green across three layered test suites:

  • Phase 1 (32 checks) — schema migration, value-object accessors, validator normalization + trigger validation, repository scheduled + legacy create/retrieve, lifecycle hooks fire correctly, schedule listener stub is a no-op.
  • Phase 2 (32 checks) — listener wiring, AS event registration on save/update/disable/delete, end-to-end tick → run completes synchronously, reconciliation drift correction, form-triggered regression unaffected.
  • Phase 3 (35 checks) — both new step types registered with correct metadata, every documented filter combination on fre_list_entries, idempotency + mixed-input tolerance on fre_delete_entries, end-to-end retention workflow scenario with the actual 725 use case JSON.

Plugin version stamp: 0.6.0 — stable release following 725 Print Lab production verification.

[0.5.0] — 2026-05-10

Added — Claude Cowork MCP connector

Closes the Critical C2 finding in FLOWMINT_AUDIT.md: the WordPress-side REST connector at flowmint/v1/connector/* had been built in v0.3.0, but the client-side MCP bridge that lets Claude Desktop reach those endpoints was missing. This release ships the bridge.

New files

  • includes/Connectors/MCP/assets/flowmint-connector.js — single-file Node.js stdio MCP server. Exposes 16 tools (preflight, full workflow CRUD, run history + replay, step type catalog, credential introspection + test, template read). Maps 1:1 to the existing REST endpoints. Forked from the Form Runtime Engine connector with FlowMint-specific tool definitions and route paths.
  • includes/Connectors/MCP/class-fmw-connector-admin.phpFlowMint Workflows → Claude Connection admin page. Generates and revokes ...
Read more

v0.6.1

Choose a tag to compare

@breonwilliams breonwilliams released this 17 May 23:04

Connector admin page UI polish. See CHANGELOG.md for details.

Changed

  • Renamed connector admin page from "Claude Connection" to "Connector" (menu) / "The FlowMint Connector" (page title) — vendor-neutral naming future-proofed for additional AI clients
  • Redesigned connector page with card-based layout, clearer 3-step setup flow, and improved connection status display
  • Added warning notice when Application Passwords are unavailable (requires HTTPS or WP_ENVIRONMENT_TYPE='local')

v0.6.0

Choose a tag to compare

@breonwilliams breonwilliams released this 15 May 19:09

Scheduled Workflow Triggers

v0.6.0 adds scheduled workflow triggers as a first-class capability. Workflows can now fire on a recurring schedule (hourly / twicedaily / daily / weekly) in addition to form submissions.

Highlights

  • New trigger abstraction — Workflow JSON gains a trigger block with two types: form (existing pattern) and schedule (new)
  • New step typesfre_list_entries and fre_delete_entries for bulk querying and deleting FormEngine entries
  • Daily reconciliation — Self-healing AS recurring action ensures scheduled workflows stay registered even if AS data is cleared
  • Database schema v0.2.0 — Additive migration (nullable form_id + new trigger_type column); existing workflows unaffected

Production Verified

99/99 smoke checks green across three layered test suites. 725 Print Lab production verification complete.

See CHANGELOG.md for full details, or the user guide at docs/SCHEDULED_WORKFLOWS.md.