* fix(cli): surface shared UI (ui/) changes in sync push dry-run preview
The git-sync "Pull from repo" preview never showed shared UI (ui/) changes,
so users thought the shared-UI folder was not syncing. The apply step does
sync it (pushSharedUi on dryRun=false); only the dry-run preview was blind.
Shared UI maps a single top-level ui/ folder to the workspace_shared_ui store
and is handled out-of-band from the normal file diff (isNotWmillFile excludes
ui/). The dry-run path returns before pushSharedUi runs, so the `changes` list
the modal consumes never contained any ui/ entry and read as "no changes".
- Add exported diffSharedUi(workspace) computing added/edited/deleted ui/<rel>
entries (push direction), and refactor pushSharedUi to reuse it so preview
and apply never diverge.
- Fold the diff into `changes` in the dry-run path (both JSON and terminal),
guarded by try/catch. Apply path is unchanged.
- Label ui/ paths as "shared UI" in prettyChanges (getTypeStrFromPath throws
on non-wmill paths like ui/config.json).
- Do not run pushSharedUi in the zero-changes branch during a dry-run.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(cli): report shared-UI-only push in sync JSON output
Address local review: when a real apply has only ui/ changes it reaches the
zero-file-changes branch, pushes the shared-UI store, then printed
"No changes to push" in --json-output. Surface pushSharedUi's result so the
message no longer claims no changes when the store was written. Also correct
the pushSharedUi docstring (empty-but-existing folder still clears a
non-empty remote store).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(cli): trim shared_ui diff test header to the durable invariant
Address Codex nit: replace the narrative regression header with a 4-line
statement of the invariant (diffSharedUi mirrors pushSharedUi's apply
semantics so preview and apply never diverge).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(cli): own-property shared-UI diff and count ui/ in dry-run summary
Address Codex review:
- diffSharedUi used `rel in remote`/`rel in files`, so a file named after an
Object.prototype member (e.g. ui/toString) always registered as present and
was misdiffed; pushSharedUi could then skip deleting it. Use Object.hasOwn.
- The dry-run "N changes to apply" summary logged before the shared UI fold,
so a shared-UI-only dry-run printed "0 changes to apply" then listed the
changes. Fold before the summary so the count includes ui/.
- Add a unit test for the ui/toString inherited-property filename.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>