diff --git a/.gitignore b/.gitignore index 4ae580f..7005519 100644 --- a/.gitignore +++ b/.gitignore @@ -328,3 +328,4 @@ ASALocalRun/ # MFractors (Xamarin productivity tool) working folder .mfractor/ +*.stackdump diff --git a/docs/advanced-filemaker-scripting-syntax.md b/docs/advanced-filemaker-scripting-syntax.md index 17686fc..8d1ba93 100644 --- a/docs/advanced-filemaker-scripting-syntax.md +++ b/docs/advanced-filemaker-scripting-syntax.md @@ -59,8 +59,9 @@ the same flag: - `Exit after last: On` on found-set iterators. - `With dialog: Off` on steps that can suppress their confirmation UI. -- `Restore: On|Off` — **reserved**. Not currently emitted by any POCO; - see "What to drop vs. surface" below for the rationale. +- `Restore: On|Off` — emitted by steps whose XML carries a meaningful + stored-state flag (e.g. Enter Find Mode); see "What to drop vs. + surface" below for the fixed-value cases that stay XML-only. ### Form 3 — trailing `; Kind: [...]` blocks @@ -125,16 +126,16 @@ Pro never alters it, never emits it in clipboard output, and no user workflow produces a different value. Round-tripping such state adds visual noise for zero information. -### Canonical drop: `` on `If` +### Canonical hidden state: `` on `If` -Upstream `agentic-fm` snippets include the element; FM Pro's own -clipboard output never does; no FM Pro user interaction produces -`state="True"`. `IfStep` drops it on both read and write. The audit -entry documents the drop: - -> <Restore state="False"/> — intentionally dropped. FM Pro never -> changes the value and never emits the element in clipboard output; it -> carries no information worth round-tripping. +The vendored canonical reference (`docs/filemaker-xml-canonical/`, +round-trip verified against FM Pro 2025/2026) shows FM Pro *does* write +the element, so `IfStep` emits it in XML — but the value is fixed (no FM +Pro user interaction produces `state="True"`), so it stays hidden from +the display line: the shape declares it `Display = DisplayMode.Hidden` +and it round-trips in XML only. The same treatment applies to Loop's +``/`` pair. See the divergence review log in +`docs/filemaker-xml-canonical/divergence-review.md`. ### Canonical surface: field `id` via `(#id)` suffix diff --git a/docs/filemaker-xml-canonical/LICENSE.md b/docs/filemaker-xml-canonical/LICENSE.md new file mode 100644 index 0000000..9a5bc01 --- /dev/null +++ b/docs/filemaker-xml-canonical/LICENSE.md @@ -0,0 +1,40 @@ +# License — Vendored canonical FileMaker XML references + +The reference material in this directory is **not** original to SharpFM. It is +vendored, unmodified except where noted, from two open-source projects by +**Andrew Kear** of **Clockwork Creative Technology** (https://www.clockworkct.co.uk), +and is redistributed here under its original licence. + +## License: CC BY 4.0 + +Both sources are licensed under the +[Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/). + +You are free to share and adapt the material for any purpose, provided you give +appropriate credit. SharpFM gives that credit here and in the `README.md` +alongside this file. + +## Attribution + +- **FileMaker XML Snippet Claude Skill** — reverse-engineered specification of + FileMaker's `fmxmlsnippet` clipboard format. + Source: https://github.com/andykear/FileMaker-XMLsnippet-Claude-Skill + Vendored version: **v1.12** (FileMaker Pro 2026 / FM 26 support). + Vendored under `skill/`. + +- **Clockwork Inspector** — open-source FileMaker DDR / database-design XML + analyzer. SharpFM vendors only two extracts: the `FM_STEP_IDS` step catalog + and the `extractStepText` display renderer, used as a cross-check catalog and + a reference for SharpFM's own step-display convention. + Source: https://github.com/andykear/FileMaker-XML-inspector-open-source + Vendored version: **v2.0**. + Vendored under `inspector/`. + +## What SharpFM uses this for + +SharpFM is an XML-faithful FileMaker clipboard editor. These references are the +authoritative description of the exact native XML FileMaker's Script Workspace +paste handler accepts cleanly, including the documented silent-failure modes. +SharpFM's step model is validated against them. No SharpFM source code is +derived from Clockwork's code; the vendored files are reference data and are +parsed at test time only. diff --git a/docs/filemaker-xml-canonical/README.md b/docs/filemaker-xml-canonical/README.md new file mode 100644 index 0000000..b659300 --- /dev/null +++ b/docs/filemaker-xml-canonical/README.md @@ -0,0 +1,45 @@ +# Canonical FileMaker XML references (vendored) + +This directory vendors the authoritative, reverse-engineered description of the +native XML FileMaker Pro's Script Workspace paste handler accepts. SharpFM's +script-step model (`src/SharpFM.Model/Scripting/`) is validated against it so +that XML written back to the clipboard round-trips through FileMaker with no +silently-dropped elements. + +See [`LICENSE.md`](LICENSE.md) for attribution. Both sources are CC BY 4.0, +authored by Andrew Kear / Clockwork Creative Technology. + +## Layout + +| Path | Source | Used for | +|------|--------|----------| +| `skill/SKILL.md`, `skill/references/*.md` | FileMaker XML Snippet Skill **v1.12** | Canonical clip-XML skeletons per step. The refresh step extracts these fenced blocks into checked-in test fixtures (under `tests/SharpFM.Tests/CanonicalSkill/fixtures/`) that the round-trip suite reads — the markdown is not parsed live at test time. **Sole source of truth for clip-XML emission.** | +| `skill/README.upstream.md` | same | The upstream project's own README, kept for provenance. | +| `inspector/FM_STEP_IDS.js` | Clockwork Inspector **v2.0** | Verbatim 217-entry `stepId → {name, category}` catalog. Used as the **working list** to align SharpFM's POCO `StepMetadata` (Id/Name/Category) and find the steps we don't yet model. Once the POCOs match it, **SharpFM's `StepMetadata` is the authoritative catalog** — this file stays only as the upstream reference for spotting drift on future FM releases. | +| `inspector/extractStepText.js` | Clockwork Inspector **v2.0** | Verbatim reference renderer for human-readable step text. Seeds SharpFM's `StepDisplayRenderer` convention. The Inspector's DDR parser is **not** reused — it targets a different XML dialect (database-design XML, not clip XML). | + +## Silent-failure modes (from `skill/references/core.md`) + +The paste handler is lenient as an XML parser but strict as a paste handler. +Structurally valid XML can paste with data silently dropped. The verified modes +SharpFM's renderer must respect: + +- **Set Variable** — the variable name must be in a `` child, present and + last. A bare `` or misplaced name pastes with no variable name. +- **Perform JavaScript in Web Viewer** — parameters use `

`; a `` element is silently dropped. +- **Install OnTimer Script** — the interval must be wrapped in ``; a bare top-level `` binds to the wrong slot and the timer never fires. + +## Refreshing + +Run [`refresh-canonical.ps1`](refresh-canonical.ps1) to re-sync both sources +from upstream. Review the diff before committing — upstream version bumps (new +FM releases) may add steps or change canonical shapes, which is exactly the +signal the audit tests are meant to surface. After refreshing, regenerate the +test fixtures from the updated skill markdown: + +``` +dotnet run --file docs/filemaker-xml-canonical/extract-fixtures.cs +``` + +This rewrites `tests/SharpFM.Tests/CanonicalSkill/fixtures/` and reports any +catalog ids left without a fixture. diff --git a/docs/filemaker-xml-canonical/divergence-review.md b/docs/filemaker-xml-canonical/divergence-review.md new file mode 100644 index 0000000..3d01718 --- /dev/null +++ b/docs/filemaker-xml-canonical/divergence-review.md @@ -0,0 +1,158 @@ +# Divergence review log + +Every place SharpFM's emitted XML **changed** to match the vendored skill's +canonical form during the canonicalization audit. The policy is *trust the +skill*: where our output differed, we adopt the skill's form and record the +change here for a second review. + +Each entry: the step, what we emitted **before**, what we emit **now**, the +skill section that mandates it, and a review box. Tick the box once a human has +confirmed the change is correct. + +> Status legend: `[ ]` awaiting review · `[x]` reviewed & accepted · `[!]` flagged for discussion + +## Phase 5 — worst offenders + +### Set Variable (141) — no behavioral change +- [ ] Already canonical (skill §3). Refactored to the shape-driven renderer; + emitted XML is byte-for-byte unchanged. Listed for completeness only. + +### If (68), Else If (125), Else (69) — added `` +- **Before:** `` was dropped on read and never emitted. +- **Now:** emit `` as the first child (before + `` where present). +- **Skill:** §8.1. Round-trip tested against FM Pro 2025/2026 — FileMaker *does* + write it. Supersedes the earlier `docs/advanced-filemaker-scripting-syntax.md` + note that claimed FM never emits it. +- [ ] Reviewed + +### Loop (71) — added `` and `` +- **Before:** emitted no children. +- **Now:** emit `` then ``. +- **Skill:** §8.1. +- [ ] Reviewed + +> Both values are fixed (FileMaker never varies them), so they are hidden from +> the display line and round-tripped in XML only. + +### Install OnTimer Script (148) — element order Interval → Script +- **Before:** emitted `