Changelog
What changed in each release of PromptWire.
1.13.0 (14 Aug 2026)
- Fixed: Options fields now resolve by label across environments. When a page is pushed between environments (e.g. local → production), options field IDs are matched by title rather than raw integer. Option IDs are auto-incremented per install and routinely differ between sites; matching by label means the correct option is always selected regardless of which environment generated the YAML. Applies to both the local PHP push path and the remote API.
- Fixed:
FieldtypeFileandFieldtypeImagefields now register disk-resident files duringpw_page_push. Previously, a file placed in the page's asset directory viapw_page_assets,pw_file_sync, or a manual copy was silently skipped when pushing field metadata — the file existed on disk but was not registered in ProcessWire's Pagefiles collection. The push now detects this and adds thePagefileobject before writing the description, so a singlepw_page_pushis enough to register and describe a newly-uploaded file. - Fixed:
pw_page_initno longer requires manual deletion ofpage.meta.jsonwhen the file was written by a remote pull. A remote pull setspageIdto the remote environment's integer; this causedinitPageMetato treat the page as already locally-linked and block re-init. The guard now checksids.localexclusively — a meta with onlyids.remoteis correctly treated as unlinked locally and proceeds without the manual delete step. - New:
pw_page_initgains dry-run mode. Dry-run by default — preview what would be linked or scaffolded without writingpage.meta.json. PassdryRun: falseto apply. Consistent with every other write tool in the suite. - Improvement:
pw_page_initpreservesids.remoteacross re-init. Any existing remote-environment tracking in the old meta is carried forward into the new one. - Migration impact: zero. All changes are backwards-compatible. Existing
page.yamlfiles with integer option IDs are resolved by label on the next push; no YAML edits required.
1.12.7 (27 Jul 2026)
- Fixed:
pw_page_publishon remote now triespage:updatefirst and only falls through topage:createwhen the page is not found. Previously, an interrupted publish could leave an orphan on production with a-1slug suffix. The remote branch now mirrors the same try-update-then-create pattern used bypw_page_push. - Migration impact: zero. Fixes duplicate orphan pages visible in
pw_site_syncdry-runs.
1.12.6 (14 Jul 2026)
- Fixed: MCP remote client no longer misreports
page:update404s as "Remote API not found". Application errors such asPage not found: /path/are surfaced verbatim, restoring thepage:createfallback when pushing a locally-created page to production for the first time. - Fixed: HTTP 400 application errors (for example
Template not found: guide-pageorParent page not found: /guides/) are returned verbatim instead of the opaqueRemote API returned HTTP 400. - New:
clear-cache procachetarget (included inclear-cache allwhen ProCache is installed). Clears ProCache static cache and reports how many entries were removed. - Migration impact: zero.
1.12.5 (14 Jul 2026)
- New:
pw_page_renametool (+page:renameCLI command). Renames a ProcessWire page slug on local, remote, or both. Dry-run by default. Checks for name collisions and refuses system pages (home, admin). Reports whether PagePathHistory is installed (auto-301 from old URL). See Page Slug Rename. - New: Local sync folder reconcile after rename. When a local rename succeeds, PromptWire automatically moves
site/assets/pw-mcp/.../old-slug/to the new path and updatespage.meta.json. PassreconcileLocal: false(MCP) or--no-reconcile(CLI) to skip. - Remote routing:
targets: remoteandtargets: bothcall the remote PromptWire API — no SSH or admin clicks required. Same pattern aspw_page_push. - Migration impact: zero.
1.12.4 (14 Jul 2026)
- Fixed:
yamlValue()now correctly quotes non-string objects after a(string)cast. Fields backed by custom ProcessWire field types that return an object rather than a plain PHP string (for example SeoNeo) previously bypassed colon/special-character quoting, causing js-yaml to throwbad indentation of a mapping entryon the next remote push when a value contained a colon (for exampletitle: Foo: Barmust betitle: "Foo: Bar"). - Migration impact: zero.
1.12.3 (14 Jul 2026)
- Fixed: PHP CLI
page:pushnow rejects--targets=remoteand--targets=bothwith a clear error. Previously the CLI silently pushed to the local database only — remote push is an MCP server concern. The error points topw_page_pushwithtargets="remote"as the correct tool. - Fixed: Nested per-target push errors now surface at the top level. When
pw_page_push targets="remote"fails, the concrete error (for example a YAML parse failure) is included in the top-levelerrorstring instead of being buried indata.results.remote.error. - Improved: YAML parse errors in
parsePageYamlnow include an actionable hint when an unquoted colon in a field value is the likely cause. - Migration impact: zero.
1.12.2 (25 May 2026)
- New:
NEW*placeholder support in repeater and matrix fields. When a repeater/matrix item inpage.yamlhas_itemId: NEW1(orNEW2, etc.), PromptWire creates a fresh item instead of skipping it as missing. For matrix fields, the optional_matrixTypekey sets the matrix type automatically. See Content Sync — Matrix placeholders. - Impact: The manual
matrix:add → page:pullbootstrapping step for new pages goes away. A singlepage:publish → page:pushpass now creates and populates matrix items in one shot. - Migration impact: zero. Existing
page.yamlfiles with integer_itemIdvalues continue to work exactly as before.
1.12.1 (22 May 2026)
- Fixed:
pw_file_syncnow reads local files fromids.local.id, notmeta.pageId. After a remote pull,pageIdin meta reflects the remote environment — local binaries live under a different id. The sync no longer silently reports zero local files when id drift is present. - Fixed:
pw_file_syncpasses filedescriptionfrompage.yamltofile:upload, and re-syncs when the binary is unchanged but the description differs (metadataOnlyupload). - Fixed:
file:uploadremoves on-disk orphans before replacing a file, preventing ProcessWire from suffixing replacements (for examplemediahub-1_17_0-1.zip). - New:
file:uploadsupportsmetadataOnly: trueto update a file description without re-uploading the binary. - Fixed:
pw_page_push/page:updateapply file field descriptions from YAML (metadata only — binaries still sync viapw_file_sync). Previously dry-run reported description changes that were never applied. - Fixed: Remote
page:updateapplies file description arrays when pushed from the MCP server. - Changed:
files:pushallowspromptwire-api.phpat the site root so the remote API endpoint can be deployed via the existing push tooling. New script:scripts/push-api-to-remote.mjs. - Migration impact: zero for callers. Existing workflows gain correct behaviour; no signature changes.
1.12.0 (11 May 2026)
- Default-changed:
pw_site_syncno longer pushessite/modules/*unless asked. Every sync run now prependssite/modules/*to the effectiveexcludeFilePatternsand skips module code in the file step. To ship a plugin update alongside templates/content, pass the newpushModules: trueflag. Dry-run plans surface afiles.modulesExcludedblock when the auto-exclusion is in effect. - Fixed:
pw_health.writesEnabledis no longer a hardcodedfalse. Now computed from the actual gate state: CLI invocations reporttruewith reasoncli; web invocations reporttruewith reasonapi-key(plus+ip-allowlistor+httpwhen those gates apply). A siblingwritesEnabledReasonfield carries the breakdown. - Migration impact:
pw_site_synccallers that relied on module pushes by default must addpushModules: true. Anything scripting againstwritesEnabled === falsewill now seetrueon correctly configured installs.
1.11.1 (1 May 2026)
- New: Frontend-usage scan on remove operations. Before
pw_template_fields_pushremoves a field from a template's fieldgroup, it scanssite/templates/for hardcoded references to the field name (in.php,.module,.inc, and.htmlfiles) and emits a warning listing file paths, line numbers, and snippets when any match. Complements v1.11.0's module-ownership awareness: that catches fields belonging to known modules; this catches the broader case where a regular field likeyour_emailorfeedbackis hardcoded in a custom contact form's PHP. Removing the field would leave ProcessWire healthy but silently no-op the assignment, so the form stops working with no admin-side error. - Implementation note: The scan is fail-open on every error path (missing templates dir, FS permission, iterator exception) and capped at 200 files / 2.0s wallclock so it can never block the classifier. Word-boundary matching keeps substring false positives out (
blog_does not matchblog_date). Warning, not danger, because the removal may be a legitimate cleanup, the operator gets full visibility without being blocked. - Migration impact: zero. Strictly additive on the warnings array. No existing tool's signature or output changes.
1.11.0 (1 May 2026)
- New:
pw_template_fields_pushtool. The first tool in the fieldgroup-edit family. Adds, removes, and reorders fields on a template's fieldgroup, and sets per-fieldgroup context overrides (label override, description, required, columnWidth, showIf, requiredIf, collapsed, plus the FieldtypePage-specific keys liketemplate_id,parent_id,findPagesSelector, andinputfield). It explicitly does not modify field definitions: fieldtype changes, inputfield class swaps, and parent pickers belong to the upcomingpw_field_pushin v1.12. DefaultdryRun: true. - New: Three-tier conflict classifier. Every planned change is tagged
safe,warning, ordanger. Dangers block the write unlessforce: trueis also passed; warnings are visible but non-blocking. The classifier flags removals of system or permanent core fields (title,pass,roles, etc.), edits to module-owned templates (FormBuilder, Repeater storage, ProcessWireadmin/user/role/permission, MediaHub, ProFields), removal of fields required on the current template, broken fieldset open/close pairs, and incomplete additions (e.g. a Page reference with no selectable-pages constraint). - New: Cross-site fieldtype-drift detection. When called with
site: "both", the MCP layer compares the projected post-push state on each side and refuses to proceed if a field would exist on both with a different fieldtype (for example,FieldtypeCroppableImage3locally vsFieldtypeImageon production). Drift is surfaced as a top-levelcrossSiteblock alongside the per-side results. - New: Audit trail on writes. Every response includes
{ removed, added, contextSet, reordered, saves }, populated even when a later step throws, so partial-applied writes are visible and recovery is straightforward. - Migration impact: zero. Strictly additive across CLI, MCP, and response shapes. No existing tool's signature or output changes.
1.10.2 (1 May 2026)
- New:
pw_page_assets compareand thepageAssetssection ofpw_site_comparenow report anidDriftPagesarray alongside the existing counter. Previously, pages with divergent local/remote ids but identical assets never appeared in the diff (early-continue path), so the counter was the only signal they existed. Now the operator can see exactly which pages are drifting and decide whether the divergence is benign (organic id-sequence drift between independent installs) or a real correctness issue. - New:
scripts/push-module-to-remote.mjs, a generalised companion topush-self-to-remote.mjsfor pushing any third-party module to a PromptWire-equipped remote. Takes--source=<path>and--prefix=<site/modules/NAME/>arguments, plus an--excludeflag for skipping internal docs and test fixtures. First real-world use was aligning MediaHub 1.15.3 to 1.15.4 on production. - Migration impact: zero.
idDriftPagesis strictly additive on the result shape.
1.10.1 (30 April 2026)
- New: Per-environment
idsblock inpage.meta.json. Each pull populates only its own slot (ids.localorids.remote); the other side's slot is preserved verbatim. Closes the v1.10.0 gap where re-pulling from the other environment silently overwrotemeta.pageIdand made the next push address the wrong page. The legacy top-levelpageIdis kept as a back-compat mirror. - Changed:
pushPageis now path-first with id verification. Pages are resolved by canonical PW path; the last-seen id in the meta is used as a sanity check. If the path now resolves to a different id (page deleted and recreated, slug rebound, meta from a different site), the push is refused with a structured error and a hint to useforce: trueif the operator really means to push to the new id. - Changed: The MCP-side pull merges the remote payload with the existing local meta instead of overwriting it, so a remote pull no longer destroys local id state.
pushPageandpublishPagenow recordids.remoteafter a successful live remote operation. - Migration impact: zero for callers. Older metas keep working; the first write on v1.10.1 or later adds the
idsblock.
1.10.0 (30 April 2026)
- New:
pw_page_assetstool. Syncs the on-disk asset directory for a page (site/assets/files/{pageId}/) between local and remote. Catches both standardFieldtypeFileandFieldtypeImageuploads and module-managed files (notably MediaHub, plus any custom uploader that stores files keyed by page id). The previouspw_file_synconly iterated a page's fieldgroup, so files placed in the page-asset directory by modules outside the normal field flow were silently missed. Supportsinventory,download,upload,delete, andcompareactions, both directions, and is dry-run by default. PW image variations (name.WxH.ext) are filtered out by default because they are regenerated on demand. - Changed: Pages are matched by canonical PW path, then each side resolves its own
pageIdfrom that path before walking its own asset directory. Local 1234 and remote 5678 may both legitimately resolve to/about/, normal for two sites that started from independent fresh installs. Every result reportslocalPageId,remotePageId, and anidDriftboolean. - Changed:
pw_site_comparegains apageAssetssection alongside pages, schema, and files, with a per-page summary ofchanged,localOnly, andremoteOnlyfiles.pw_site_sync's page-files step is replaced with a directory-walking variant that catches MediaHub-style files. The previous remote-to-local gap (a no-op with a "use SFTP" warning) is closed: pulls now fetch each missing or changed file viapage-assets:download. - Changed:
page.meta.jsonnow embeds apageAssetssnapshot at pull time (relative path, size, md5, plus a directory hash, asset count, and total bytes). Subsequentpw_page_assetsresults include adriftSinceLastPullblock that compares the snapshot baseline against the live inventory. Answers "what has changed in production since I last pulled?" without a fresh remote round-trip.
1.9.3 (30 April 2026)
- Fixed: File inventories no longer descend into
.git,.svn,.hg,.cursor,.vscode,.idea,node_modules,__pycache__,.next, or.cachedirectories. Previously, a file under one of these that happened to match the inventory's extension whitelist (for example, an IDE artifact stored inside a checked-out module's.gitdirectory) could appear inpw_site_sync,pw_site_compare, andpw_search_filesresults, and could be accidentally pushed to production unless you remembered to passexcludeFilePatterns. The exclusion is now hardcoded at the directory-iterator level, so version-control metadata and IDE state can never appear in a deploy plan. - Performance: Pruning at the iterator level rather than filtering after the fact means
.git/objects/pack/*andnode_modules/trees are no longer walked at all. Inventory generation is faster on sites with developer-installed module clones. - Note:
vendor/is intentionally not in the prune list, because some sites rely on file sync to ship Composer dependencies. If you need to skip it on a particular site, add it viaexcludeFilePatterns.
1.9.2 (30 April 2026)
- Fixed: Deploy script no longer uploads repository documentation (
ROADMAP.md,README.md,CHANGELOG.md, internal session notes) to the production module directory, where ProcessWire does not read them.
1.9.1 (30 April 2026)
- Fixed:
pw_modules_listwith noclassesfilter no longer returns null class names. The default call now returns every installed module with a populated class field.
1.9.0 (30 April 2026)
- New:
pw_modules_listtool. Lists installed modules with version, file path, and install state. Passsite: "both"to compare local and production install state in one call. - New:
pw_users_listtool. Lists users with id, name, email, roles, and anymember_*fields. PassincludeAll: truefor every non-system field on the user template. Password hashes are always excluded. - New:
pw_resolvetool for bulk name-to-id lookup across fields, templates, pages, roles, permissions, users, or modules. Translates names into the equivalent IDs on the target site in a single call, useful before pushing changes that touch IDs which differ across environments. - New:
pw_inspect_templatetool. Likepw_get_templatebut each field comes back as{name, type, label}, sized for spotting fieldgroup differences (e.g. a field that isFieldtypeImageon one environment andFieldtypeCroppableImage3on another) before pushing changes.
1.8.4 (30 April 2026)
- Fixed:
pw_site_compareno longer reports phantom diffs. Page content is now hashed deterministically across environments, so identical content produces identical hashes regardless of timezone formatting, page-array storage order, or whether a date field has an output format set. Expect a one-time wave of "modified" pages on the first compare after upgrading both sides, then it settles and any remaining diffs are real.
1.8.3 (30 April 2026)
- New:
pw_page_pullgainssource: "local" | "remote". Withsource: "remote", a page that was edited directly in the production admin is fetched over HTTPS and written into your local sync tree, so you can re-edit and push back without touching the live admin.
1.8.2 (30 April 2026)
- New:
pw_pages_pushgainstargets: "local" | "remote" | "both". Pages are pushed in parent-first order so any newly-created parents exist before their children try to attach. Removes the manual page-by-page loop previously needed for bulk migrations.
1.8.1 (30 April 2026)
- Fixed: Diagnostic tools now actually run against the remote site when asked. Previously
site: "remote"was silently ignored and tools likepw_db_queryalways queried the local database. Eight read tools (pw_health,pw_db_schema,pw_db_query,pw_db_explain,pw_db_counts,pw_logs,pw_last_error,pw_clear_cache) now acceptsite: "local" | "remote" | "both". With"both", the call runs in parallel against both environments and returns both results in one round trip, useful for spotting drift.
1.8.0 (30 April 2026)
- Fixed: File inventories now include
.modulefiles and symlinked module directories by default. Previouslypw_site_syncand related file commands silently skipped FormBuilder, LoginRegisterPro, WireSitemapXML, and any modules developed in symlinked sibling repositories.
1.7.0 (21 April 2026)
- New:
pw_site_comparetool for comparing local and remote sites across pages, schema, and files. Pages are matched by path, not ID, so comparison works across environments with different auto-increment sequences. - New:
pw_site_synctool for orchestrated deployment. Runs a comparison, optionally backs up the target, enables maintenance mode, pushes schema, pages (with file/image assets), and template/module files, then disables maintenance. Dry-run by default. - New:
pw_maintenancetool for toggling maintenance mode on local, remote, or both sites. Front-end visitors see a styled 503 page; superusers and the PromptWire API are unaffected. - New:
pw_backuptool for creating, listing, restoring, and deleting site backups. Database dumps use ProcessWire's built-inWireDatabaseBackup; file backups zipsite/templatesandsite/modules. - Security: HTTPS is now enforced on the API endpoint. Requests over plain HTTP receive a 403 before the API key is checked. Local development environments can bypass this with
PROMPTWIRE_ALLOW_HTTPinconfig-promptwire.php. - Security: Backup directories are automatically protected with a
.htaccessthat denies all web access. SQL dumps are never accessible via HTTP. - Changed: Module is now
autoloadso it can intercept front-end requests during maintenance mode. The overhead is a singlefile_exists()check per page load.
1.6.0 (21 April 2026)
- New:
pw_db_schematool for inspecting database tables, columns, types, keys, and indexes. - New:
pw_db_querytool for running read-only SELECT queries directly against the database. Mutations are blocked and a LIMIT is auto-injected. - New:
pw_db_explaintool for running EXPLAIN on a query to diagnose slow queries and missing indexes. - New:
pw_db_countstool for a quick overview of row counts across core tables and the largest field data tables. - New:
pw_logstool for listing available log files and reading/filtering entries by level and text pattern. - New:
pw_last_errortool for retrieving the most recent error from the error and exception logs. - New:
pw_clear_cachetool for clearing caches by target: all, modules, templates, compiled, or wire-cache.
1.5.1 (21 April 2026)
- Fixed:
pw_page_pushnow auto-creates pages on the remote target when they don't exist yet, instead of failing with "Page not found". - Fixed:
pw_page_publishno longer blocks publishing to a second target after a page has already been created on the first. Each target handles its own duplicate check independently. - Security: Users are now encouraged to rename the API endpoint file to a non-obvious name. The MCP server uses the full
PW_REMOTE_URLas-is with no filename assumption.
1.5.0 (8 April 2026)
- Changed: Module renamed from PW-MCP to PromptWire. Class names, file names, CLI scripts, API endpoints, and environment variables have all been updated.
- Changed: Install directory is now
site/modules/PromptWire/(wasPwMcp/). - Changed: On install or upgrade, the module automatically detects and removes old
PwMcp/andPwMcpAdmin/directories. - Changed: Remote API file renamed to
promptwire-api.php; config file toconfig-promptwire.php. - Changed: Environment variable
PW_MCP_CLI_PATHrenamed toPROMPTWIRE_CLI_PATH. - Changed: API key constant renamed from
PW_MCP_API_KEYtoPROMPTWIRE_API_KEY. - Kept: Data directories unchanged:
.pw-sync/for schema andsite/assets/pw-mcp/for content sync. No migration needed for existing data. - Fixed: Admin dashboard "Wire to File" exported pages to
site/assets/promptwire/instead ofsite/assets/pw-mcp/. One line inSyncManager.phpwas missed during the rename. Pull the latest frommainfor the fix. If any exports were created before updating, move them fromsite/assets/promptwire/intosite/assets/pw-mcp/and delete the empty directory.
1.4.0 (8 April 2026)
- Changed: Module restructured so the repo root is the module directory. Clone or download directly into
site/modules/PwMcp/. - Changed: On install or upgrade, the module automatically detects and removes the old
site/modules/PwMcpAdmin/directory from pre-1.4.0 installs. - Fixed:
schemaPush()routed to the remote API when bothPW_PATHandPW_REMOTE_URLwere set, so schema pushes silently went to production while reads used the local site. Now applies the samePW_PATH-first guard used elsewhere. - Fixed:
validateRefs()defaulted to validating against the remote site when both env vars were set, inconsistent with the "local wins" rule. Now defaults to local whenPW_PATHis present. - Fixed:
pushPage()andpublishPage()always returnedsuccess: trueeven when local or remote sub-operations failed. Failures were only visible in nested results. Top-levelsuccessnow reflects actual outcome. - Fixed:
publishPage()silently swallowed YAML parse errors and created remote pages with empty fields. Now reports the parse failure instead. - Improved:
schemaPull()backs up existingfields.jsonandtemplates.jsonas.bakfiles before overwriting, so a mistaken pull is recoverable. - Improved: Remote API endpoint now sends
X-Robots-Tag: noindex, nofollowheader.
1.3.1 (27 March 2026)
- Fixed: When both
PW_PATHandPW_REMOTE_URLare set (hybrid config),runPwCommandnow prefers the local PHP CLI. PreviouslyPW_REMOTE_URLsilently hijacked all commands, causing page queries to return stale remote data instead of live local data. - Fixed: Remote API endpoint now sends
Cache-Control: no-storeandPragma: no-cacheheaders to prevent proxy or browser caching of API responses.
1.3.0 (27 March 2026)
- New:
pw_page_inittool for initialising or repairingpage.meta.jsonfor sync directories where content files were created manually. - Improved:
pw_page_newis now idempotent. If the directory exists butpage.meta.jsonis missing, it creates only the scaffold files without overwriting existingpage.yamlor field files. - Improved:
pw_page_publishauto-generatespage.meta.jsonfrompage.yamland directory structure when the meta file is missing. - Improved: Error messages in
pw_page_pushandpw_page_publishnow show relative paths instead of absolute server paths, and include actionable hints.
1.2.0 (8 March 2026)
- File sync, schema sync, cross-environment page ID resolution, remote API.
1.1.0 (5 February 2026)
- Content sync (pull/push), page creation and publishing.
1.0.0 (29 January 2026)
- Initial release. Site inspection, page queries, template/field introspection.
Last updated