Changelog
What changed in each release of PromptWire.
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