@rubytech/create-maxy 1.0.879 → 1.0.881
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +1 -0
- package/payload/platform/plugins/admin/skills/plainly/SKILL.md +105 -0
- package/payload/platform/plugins/admin/skills/plainly/references/worked-examples.md +301 -0
- package/payload/platform/plugins/cloudflare/PLUGIN.md +1 -1
- package/payload/platform/plugins/docs/references/platform.md +5 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +3 -3
- package/payload/platform/templates/agents/admin/IDENTITY.md +5 -1
- package/payload/platform/templates/agents/public/IDENTITY.md +6 -0
- package/payload/platform/templates/specialists/agents/content-producer.md +6 -0
- package/payload/platform/templates/specialists/agents/database-operator.md +6 -0
- package/payload/platform/templates/specialists/agents/personal-assistant.md +6 -0
- package/payload/platform/templates/specialists/agents/project-manager.md +6 -0
- package/payload/platform/templates/specialists/agents/research-assistant.md +6 -0
- package/payload/premium-plugins/real-agency/BUNDLE.md +4 -2
- package/payload/premium-plugins/real-agency/plugins/brochures/PLUGIN.md +36 -0
- package/payload/premium-plugins/real-agency/plugins/brochures/commands/make-brochure.md +11 -0
- package/payload/premium-plugins/real-agency/plugins/brochures/skills/a4-print-documents/SKILL.md +288 -0
- package/payload/premium-plugins/real-agency/plugins/brochures/skills/brand-design/SKILL.md +185 -0
- package/payload/premium-plugins/real-agency/plugins/brochures/skills/make-brochure/SKILL.md +239 -0
- package/payload/premium-plugins/real-agency/plugins/brochures/skills/property-brochure/SKILL.md +306 -0
- package/payload/premium-plugins/real-agency/plugins/brochures/skills/property-brochure/references/template.html +1824 -0
- package/payload/premium-plugins/real-agency/plugins/brochures/skills/property-extract/SKILL.md +228 -0
- package/payload/server/chunk-KMVUUVHM.js +11438 -0
- package/payload/server/chunk-LVC7NKZ2.js +689 -0
- package/payload/server/cloudflare-task-tracker-CY6QL6CY.js +22 -0
- package/payload/server/maxy-edge.js +2 -1
- package/payload/server/public/assets/{Checkbox-CqsIsmEi.js → Checkbox-CeujDRv0.js} +1 -1
- package/payload/server/public/assets/{admin-uVxIhs_u.js → admin-BN_z-2Bm.js} +4 -4
- package/payload/server/public/assets/data-LYciLZK9.js +1 -0
- package/payload/server/public/assets/graph-C-SKAbGX.js +1 -0
- package/payload/server/public/assets/{graph-labels-D0qUVHtZ.js → graph-labels-Co03qEv5.js} +1 -1
- package/payload/server/public/assets/jsx-runtime-BcZkJOEw.css +1 -0
- package/payload/server/public/assets/{page-CnyySOZF.js → page-C4E0CWHe.js} +1 -1
- package/payload/server/public/assets/{page-DcK36vDf.js → page-DGLz4ozf.js} +1 -1
- package/payload/server/public/assets/{public-SXA00FTv.js → public-rILg7e8-.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-DcByEBLy.js → useVoiceRecorder-D3Upd7Q3.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +80 -5
- package/payload/server/public/assets/data-CH-nQ7oX.js +0 -1
- package/payload/server/public/assets/graph-mpWDe4rf.js +0 -1
- package/payload/server/public/assets/jsx-runtime-Cy_HdZWV.css +0 -1
- /package/payload/server/public/assets/{jsx-runtime-BEjEWeaF.js → jsx-runtime-BWYXu1CT.js} +0 -0
package/payload/premium-plugins/real-agency/plugins/brochures/skills/property-extract/SKILL.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: property-extract
|
|
3
|
+
description: Use when a live property listing URL on an estate-agent website (Muvin, or any site using the Loop CRM CDN at b-cdn.net) needs to be turned into a local property assets directory containing photos, floorplans, EPC documents, and structured metadata that the property-brochure skill can consume. Trigger phrases include "extract property from <url>", "get property details from <url>", "scrape this listing", "pull all the photos from <listing>", "stage assets for the brochure", or any request that names a live property URL and asks for the photos, floorplans, and details to be saved locally.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
- WebFetch
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# property-extract
|
|
15
|
+
|
|
16
|
+
Turn one publicly-accessible property listing URL into a self-contained property assets directory that `property-brochure` can consume without re-visiting the source site.
|
|
17
|
+
|
|
18
|
+
The reference output this skill targets is `/Users/neo/estate-agents/muvin/properties/henham-road-debden-green-hamperden-end-cb11-3lz-949931/` — read that directory once before generating to anchor the standard.
|
|
19
|
+
|
|
20
|
+
## Outcome contract
|
|
21
|
+
|
|
22
|
+
The skill is **complete** when the target directory contains exactly this structure:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
<output-dir>/<property-slug>-<listing-id>/
|
|
26
|
+
property.json # structured metadata
|
|
27
|
+
description.md # human-readable description + agent + EPC + council tax
|
|
28
|
+
brochure/ # empty — reserved for property-brochure output
|
|
29
|
+
epc/ # EPC certificate PDF/image, OR empty if rating is "TBC"
|
|
30
|
+
floorplans/ # all floorplan images, original filenames
|
|
31
|
+
images/ # all property photographs and renders, original filenames
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Every photograph and floorplan referenced by the listing must be downloaded. The folders `brochure/` and `epc/` may legitimately be empty (the first by design, the second if no EPC has been issued); `images/` and `floorplans/` must not be empty if the listing exposes any.
|
|
35
|
+
|
|
36
|
+
`<property-slug>` comes from the URL path segment (e.g. `henham-road-debden-green-hamperden-end-cb11-3lz`). `<listing-id>` is the numeric ID, also from the URL. Concatenating them keeps the folder both human-readable and unique even when the same street has multiple listings.
|
|
37
|
+
|
|
38
|
+
Anything else (raw HTML dumps, `/tmp` files, intermediate URL lists) must be cleaned up before reporting completion.
|
|
39
|
+
|
|
40
|
+
## Inputs
|
|
41
|
+
|
|
42
|
+
Required: a property listing URL, fully-formed and publicly accessible. If only a postcode or property name is given, decline and ask for the URL — listings are uniquely identified by their numeric IDs, and there is no reliable way to infer one from a description.
|
|
43
|
+
|
|
44
|
+
Optional: an output directory. The default is `<brand_dir>/properties/`, where `<brand_dir>` is the brand workspace for the agent that owns the listing. For a Muvin URL with the existing brand pack at `/Users/neo/estate-agents/muvin/`, that resolves to `/Users/neo/estate-agents/muvin/properties/`. If the brand workspace cannot be located, fall back to `./properties/` in the caller's current working directory.
|
|
45
|
+
|
|
46
|
+
The property directory **must** sit inside its brand workspace at `<brand_dir>/properties/<property_slug>-<listing_id>/` — never as a sibling of the brand workspace, never inside another property's folder. This is the contract `make-brochure` and `property-brochure` read against.
|
|
47
|
+
|
|
48
|
+
## Scope boundaries
|
|
49
|
+
|
|
50
|
+
| In scope | Out of scope |
|
|
51
|
+
|---|---|
|
|
52
|
+
| Muvin listings (`muvin.co.uk/property/...`) and any other agent fronting the Loop CRM CDN (`*.b-cdn.net/propertyimages/...`, `*.b-cdn.net/floorplans/...`) | Listings on agency-specific platforms (Rightmove, Zoopla, OnTheMarket, OpenRent) — those have separate page structures and image hosts |
|
|
53
|
+
| All photos, floorplans, drone shots, AI-staged renders | Stripping AI-generated images from the photo set — keep them all and flag in metadata |
|
|
54
|
+
| Property description, key features, price, specs, agent contact | Walkthrough video transcription (the property-brochure skill handles that separately if the user supplies one) |
|
|
55
|
+
| EPC rating as a value, EPC certificate PDF if linked from the page | EPC certificate retrieval from the EPC Register — that's a separate lookup; if the listing does not link the certificate, leave `epc/` empty and record `"epc_rating": "TBC"` (or the band shown) in `property.json` |
|
|
56
|
+
| Council tax band as shown on the page | Council tax band verification against VOA — out of scope |
|
|
57
|
+
| Material Information visible on the listing page (tenure, council tax, EPC) | Full Part A/B/C compliance gathering — that's the brochure assembly step's job |
|
|
58
|
+
|
|
59
|
+
If the page is JS-rendered and `curl` returns no asset URLs, fall back to a headless-browser fetch (Chrome DevTools MCP or Playwright). If even that fails, stop and report `STATUS: BLOCKED` — do not synthesise an asset list.
|
|
60
|
+
|
|
61
|
+
## Artifact contracts
|
|
62
|
+
|
|
63
|
+
### Folder layout
|
|
64
|
+
|
|
65
|
+
The four subfolders are **mandatory and named exactly** as specified — they are part of the contract that `property-brochure` reads against. Do not pluralise differently, do not collapse `epc/` into `floorplans/`, do not add a sibling `videos/` folder. If a future asset class needs accommodating, propose a contract change to the plugin first.
|
|
66
|
+
|
|
67
|
+
### `images/`
|
|
68
|
+
|
|
69
|
+
Every URL on the page matching `b-cdn.net/propertyimages/<tenant-uuid>/<listing-id>/` is an image asset. Two CDN buckets are in active use as of April 2026:
|
|
70
|
+
|
|
71
|
+
- `loop-app.b-cdn.net` — older photos (2024-vintage uploads)
|
|
72
|
+
- `loopcrm.b-cdn.net` — newer 2026 additions (drone shots, AI-staged renders, screenshots)
|
|
73
|
+
|
|
74
|
+
Download all of them. Preserve the original filenames — they encode upload timestamps as Unix epochs (e.g. `DSC01495_1727361503898.jpg` → 26 Sept 2024) which are useful for ordering and de-duplication later.
|
|
75
|
+
|
|
76
|
+
Image categories observable from filename prefixes:
|
|
77
|
+
|
|
78
|
+
| Prefix | Origin |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `DSC*`, `IMG*` | Photographer's DSLR/mirrorless |
|
|
81
|
+
| `DJI_*` | Drone imagery |
|
|
82
|
+
| `ChatGPT-Image-*` | AI-staged render |
|
|
83
|
+
| `Screenshot-*` | Map/aerial screenshot from a desktop tool |
|
|
84
|
+
| `iPhone*`, `WhatsApp*` | Quick mobile snaps (lower resolution) |
|
|
85
|
+
|
|
86
|
+
Record the count per prefix in `property.json` under `media.image_breakdown` — `property-brochure` uses this to pick the right photo for each slot.
|
|
87
|
+
|
|
88
|
+
### `floorplans/`
|
|
89
|
+
|
|
90
|
+
URLs matching `b-cdn.net/floorplans/<tenant-uuid>/<listing-id>/`. Listings typically ship one floorplan per floor (so 1–3 files for a UK home). Preserve original filenames.
|
|
91
|
+
|
|
92
|
+
### `epc/`
|
|
93
|
+
|
|
94
|
+
If the page links a PDF whose URL contains `epc` or whose link text mentions "EPC" / "Energy Performance Certificate", download it here. If the page only states a rating ("EPC rating: D") without linking a certificate, leave the folder empty and reflect the rating in `property.json`. If the rating is "TBC", record that exact string — do not guess.
|
|
95
|
+
|
|
96
|
+
### `brochure/`
|
|
97
|
+
|
|
98
|
+
Always empty on output. This is the slot `property-brochure` writes its `output/brochure.html` and per-page print PNGs into. Creating it pre-empts a "where does the brochure go" question downstream.
|
|
99
|
+
|
|
100
|
+
### `property.json`
|
|
101
|
+
|
|
102
|
+
Machine-readable metadata. Required keys:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"source": {
|
|
107
|
+
"url": "<full listing URL>",
|
|
108
|
+
"listing_id": "<numeric id>",
|
|
109
|
+
"tenant_id": "<uuid from CDN paths>",
|
|
110
|
+
"scraped_on": "<YYYY-MM-DD>"
|
|
111
|
+
},
|
|
112
|
+
"address": {
|
|
113
|
+
"line_1": "...",
|
|
114
|
+
"locality": "...",
|
|
115
|
+
"postcode": "..."
|
|
116
|
+
},
|
|
117
|
+
"price": {
|
|
118
|
+
"amount": <integer GBP>,
|
|
119
|
+
"currency": "GBP",
|
|
120
|
+
"qualifier": "Offers Over | Guide Price | Asking Price | POA"
|
|
121
|
+
},
|
|
122
|
+
"specifications": {
|
|
123
|
+
"property_type": "Detached House | ...",
|
|
124
|
+
"bedrooms": <int>,
|
|
125
|
+
"bathrooms": <int>,
|
|
126
|
+
"reception_rooms": <int>,
|
|
127
|
+
"tenure": "Freehold | Leasehold | null",
|
|
128
|
+
"epc_rating": "A | B | ... | TBC",
|
|
129
|
+
"council_tax_band": "A | B | ... | H",
|
|
130
|
+
"age": "<string, optional>"
|
|
131
|
+
},
|
|
132
|
+
"key_features": ["...", "..."],
|
|
133
|
+
"agent": {
|
|
134
|
+
"name": "...",
|
|
135
|
+
"agency": "...",
|
|
136
|
+
"phone": "...",
|
|
137
|
+
"email": "..."
|
|
138
|
+
},
|
|
139
|
+
"media": {
|
|
140
|
+
"video_tours": ["<url>", "..."],
|
|
141
|
+
"image_count": <int>,
|
|
142
|
+
"floorplan_count": <int>,
|
|
143
|
+
"epc_document": "<filename in epc/ or null>",
|
|
144
|
+
"brochure": null
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Unknown values are `null`, not `""` and not omitted. The downstream brochure skill relies on `null` to recognise "we know we don't have this" vs. a missing key (= "this wasn't extracted, look again").
|
|
150
|
+
|
|
151
|
+
### `description.md`
|
|
152
|
+
|
|
153
|
+
Plain Markdown, no frontmatter. Structure:
|
|
154
|
+
|
|
155
|
+
1. H1: full address.
|
|
156
|
+
2. One-line summary: price, beds, baths, reception rooms, type, council tax, EPC.
|
|
157
|
+
3. Source line: linked listing URL.
|
|
158
|
+
4. Agent line: name, agency, phone, email.
|
|
159
|
+
5. H2 "Property Description" — verbatim paragraphs from the listing's description section. Preserve paragraph breaks. Do not paraphrase. Strip HTML entities (`’` → `'`, `&` → `&`).
|
|
160
|
+
6. H2 "Video tours" — bulleted list of every video URL on the page (YouTube, Vimeo, Giraffe360, Matterport, etc.).
|
|
161
|
+
7. H2 "EPC and council tax" — both values exactly as shown.
|
|
162
|
+
8. H2 "Folder layout" — one-line description of what's in each subfolder, with the actual counts.
|
|
163
|
+
|
|
164
|
+
Capture rules:
|
|
165
|
+
|
|
166
|
+
- **Verbatim** for the description body. The agent's wording is the source of truth for the brochure copy.
|
|
167
|
+
- If the listing has no description text (rare), record `_No description provided on the listing._` and continue. Do not invent.
|
|
168
|
+
- If the listing's marketing footer ("WOULD YOU LIKE TO VIEW", "CAN WE HELP YOU TOO") is intermingled with the property description, **keep the property paragraphs and drop the agency boilerplate** — the brochure has its own back-page CTA.
|
|
169
|
+
|
|
170
|
+
## Image preview safety
|
|
171
|
+
|
|
172
|
+
**Do not `Read` any downloaded image whose longest edge exceeds 2000px** — it breaks the session by overrunning the multimodal encoding budget. Most DSLR (`DSC*`) and drone (`DJI_*`) photos from a Muvin listing are 6000–8000px and will trigger this. Measure with `sips -g pixelWidth -g pixelHeight <file>` before any `Read`, or skip the visual check entirely (filename, byte-size, and `sips` dimensions cover most "did the download work?" questions). See `make-brochure` for the full safety workflow including the `sips -Z 2000` downscale recipe.
|
|
173
|
+
|
|
174
|
+
## Process — high level
|
|
175
|
+
|
|
176
|
+
The skill orchestrates four capabilities, each a **what** not a **how**:
|
|
177
|
+
|
|
178
|
+
1. **Probe.** Fetch the URL once with `WebFetch` to get a summarised view (price, address, agent, image count). This is a cheap sanity check — if the summary disagrees with what you extract from raw HTML, the page is likely JS-rendered and you need a headless browser.
|
|
179
|
+
2. **Extract.** Pull the raw HTML and grep all `b-cdn.net/propertyimages/...` and `b-cdn.net/floorplans/...` URLs. Deduplicate. Also grep PDF URLs containing `epc`. Extract the `<div class="section__description">` block for the description text.
|
|
180
|
+
3. **Stage.** Create the four-folder structure under `<output-dir>/<slug>-<listing-id>/`. Download images and floorplans in parallel (`xargs -n1 -P8 curl -O -L`) — there are routinely 40–60 images per listing and serial downloads are slow.
|
|
181
|
+
4. **Assemble.** Write `property.json` and `description.md`. Run a final consistency pass: image count in JSON matches files on disk, EPC rating in JSON matches the description.md line, agent contact in JSON matches the description.md header.
|
|
182
|
+
|
|
183
|
+
The skill does not prescribe which HTTP tool to use. `curl` is fine for the static HTML pages Muvin serves. If a future agent ships a JS-rendered listing page, switch to Chrome DevTools MCP or Playwright — the contract on the output is unchanged.
|
|
184
|
+
|
|
185
|
+
## Reference standard
|
|
186
|
+
|
|
187
|
+
Before producing output, read these files to anchor the format:
|
|
188
|
+
|
|
189
|
+
- `/Users/neo/estate-agents/muvin/properties/henham-road-debden-green-hamperden-end-cb11-3lz-949931/property.json` — the JSON schema in practice.
|
|
190
|
+
- `/Users/neo/estate-agents/muvin/properties/henham-road-debden-green-hamperden-end-cb11-3lz-949931/description.md` — the prose voice and structure.
|
|
191
|
+
|
|
192
|
+
A delivered package that diverges substantially in shape from the reference is wrong, even if the content is accurate.
|
|
193
|
+
|
|
194
|
+
## Common mistakes
|
|
195
|
+
|
|
196
|
+
| Mistake | Why it's wrong |
|
|
197
|
+
|---|---|
|
|
198
|
+
| Using only the `WebFetch` summary | The summary lists "49 images" but does not return individual URLs. You must grep the raw HTML for filenames. |
|
|
199
|
+
| Stripping AI-generated renders from `images/` | They are part of the listing's marketing set. The brochure skill chooses which to use; the extractor's job is fidelity. |
|
|
200
|
+
| Renaming files to a `<slug>-NN.jpg` scheme on extraction | That's `property-brochure`'s job at the brochure-assembly step. Keep originals so the brochure skill can match by prefix and timestamp. |
|
|
201
|
+
| Inventing values for unknown specifications | `null` means "not on the listing". A guess at tenure or EPC introduces silent error into downstream Material Information compliance. |
|
|
202
|
+
| Including the agency's marketing boilerplate ("WOULD YOU LIKE TO VIEW", "CAN WE HELP YOU TOO") in `description.md` | The brochure has its own back page. Including it would duplicate text the brand designer is already authoring. |
|
|
203
|
+
| Skipping `floorplans/` because the listing only has one | One floorplan still goes in `floorplans/`, not `images/`. The folder layout is a contract — `property-brochure` looks for floorplans in exactly one place. |
|
|
204
|
+
| Saving `/tmp/muvin_property.html` or other working files inside the output directory | The directory is the deliverable. Working files get cleaned up. |
|
|
205
|
+
| Hardcoding the tenant UUID | The UUID identifies the agency on Loop CRM. Different Muvin offices can have different tenant IDs. Extract it from the actual URLs on the page. |
|
|
206
|
+
| Treating "EPC: TBC" as a missing field | "TBC" is information — the agent is telling you the assessment hasn't been done. Record it verbatim. |
|
|
207
|
+
|
|
208
|
+
## Completion criteria
|
|
209
|
+
|
|
210
|
+
Report `DONE` only after:
|
|
211
|
+
|
|
212
|
+
- The directory `<slug>-<listing-id>/` exists with all four subfolders.
|
|
213
|
+
- `property.json` and `description.md` are at the directory root.
|
|
214
|
+
- `images/` count matches `media.image_count` in `property.json`.
|
|
215
|
+
- `floorplans/` count matches `media.floorplan_count` in `property.json`.
|
|
216
|
+
- `epc/` is either empty (with rating "TBC" or only-rating-shown) or contains a downloaded certificate referenced by `media.epc_document`.
|
|
217
|
+
- `brochure/` exists and is empty.
|
|
218
|
+
- No `/tmp` files, no `.html` dumps, no `urls.txt` left behind.
|
|
219
|
+
- The source URL appears in `property.json.source.url` and on the source line of `description.md`.
|
|
220
|
+
|
|
221
|
+
If any of those are not true, report `DONE_WITH_CONCERNS` and list each gap.
|
|
222
|
+
|
|
223
|
+
## When NOT to use this skill
|
|
224
|
+
|
|
225
|
+
- The user wants a brochure produced from photos they already have on disk → skip extraction, go straight to `property-brochure`.
|
|
226
|
+
- The listing is on Rightmove, Zoopla, OnTheMarket, or another non-Loop-CRM platform → the URL parsing and CDN paths differ. Either extend this skill with a new branch or route to a platform-specific extractor.
|
|
227
|
+
- The user wants a quick price/specs lookup, not the full asset bundle → use `WebFetch` directly. The folder structure is overkill.
|
|
228
|
+
- The user wants market data, comparables, or transaction history → that's a different research task; this skill is asset staging, not analysis.
|