@rubytech/create-maxy-code 0.1.111 → 0.1.112
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/memory/references/schema-estate-agent.md +51 -1
- package/payload/platform/plugins/venture-studio/PLUGIN.md +6 -1
- package/payload/platform/plugins/venture-studio/bin/scaffold.sh +1 -1
- package/payload/platform/plugins/venture-studio/skills/brand-pack/SKILL.md +1 -1
- package/payload/platform/plugins/venture-studio/skills/investor-data-room/SKILL.md +27 -14
- package/payload/platform/plugins/venture-studio/skills/investor-data-room/references/business-plan-template.md +7 -4
- package/payload/platform/plugins/venture-studio/skills/investor-data-room/references/data-room-structure.md +6 -5
- package/payload/platform/plugins/venture-studio/skills/investor-data-room/references/deck-blueprint-template.md +7 -6
- package/payload/platform/plugins/venture-studio/skills/office-hours/SKILL.md +8 -9
- package/payload/platform/plugins/venture-studio/skills/zero-to-prototype/SKILL.md +4 -0
- package/payload/premium-plugins/real-agent/BUNDLE.md +3 -2
- package/payload/premium-plugins/real-agent/agents/listing-curator.md +133 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/a4-print-documents/SKILL.md +1 -1
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/brand-design/SKILL.md +5 -11
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/make-brochure/SKILL.md +7 -7
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-extract/SKILL.md +31 -39
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/SKILL.md +4 -4
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-socials/SKILL.md +3 -2
- package/payload/premium-plugins/venture-studio/PLUGIN.md +6 -1
- package/payload/premium-plugins/venture-studio/bin/scaffold.sh +1 -1
- package/payload/premium-plugins/venture-studio/skills/brand-pack/SKILL.md +1 -1
- package/payload/premium-plugins/venture-studio/skills/investor-data-room/SKILL.md +27 -14
- package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/business-plan-template.md +7 -4
- package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/data-room-structure.md +6 -5
- package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/deck-blueprint-template.md +7 -6
- package/payload/premium-plugins/venture-studio/skills/office-hours/SKILL.md +8 -9
- package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/SKILL.md +4 -0
package/payload/premium-plugins/real-agent/plugins/brochures/skills/a4-print-documents/SKILL.md
CHANGED
|
@@ -298,7 +298,7 @@ The longest edge of every brochure photo, **measured before any optimisation**,
|
|
|
298
298
|
|
|
299
299
|
The cap is firm — beyond 4000 px the file size grows without visible benefit. The floor is firm too: below it the photo softens noticeably even on screen at 100% zoom, and worse in print.
|
|
300
300
|
|
|
301
|
-
**
|
|
301
|
+
**1600 px source-ceiling caveat.** Many UK listing-CDN exports cap at a 1600 px ceiling (this is a common Loop-CRM tenant default; some portal exports cap similarly). That is below the full-bleed and half-page floors. When the source photos cap below the floor for an assigned slot and no higher-resolution substitute exists, raise this with the user rather than silently shipping a sub-floor cover — a `DONE_WITH_CONCERNS` is the right exit.
|
|
302
302
|
|
|
303
303
|
**Measure before optimising:**
|
|
304
304
|
|
|
@@ -15,7 +15,7 @@ allowed-tools:
|
|
|
15
15
|
|
|
16
16
|
Turn one publicly-accessible website URL into a self-contained brand-design directory that downstream design, marketing, and document-generation skills can consume without re-visiting the source site.
|
|
17
17
|
|
|
18
|
-
The
|
|
18
|
+
The output shape is a brand workspace at `<brand_dir>/` containing the four artifacts defined in **Outcome contract** below. The contract is the format; any prior conforming brand pack on disk may be inspected as a reference, but no specific location is required.
|
|
19
19
|
|
|
20
20
|
## Outcome contract
|
|
21
21
|
|
|
@@ -29,7 +29,7 @@ The skill is **complete** when the target directory contains exactly these four
|
|
|
29
29
|
description.md # company copy + official registration details
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
`<slug>` is the lowercase, hyphen-separated brand name (e.g.
|
|
32
|
+
`<slug>` is the lowercase, hyphen-separated brand name — derived from the brand's own name, not its FQDN (e.g. `<brand>`, not `<brand>realestate.co.uk`). The slug is reused as the directory name unless the caller specifies otherwise — that is, the brand workspace is `<output-dir>/<slug>/` and these four files live at its root.
|
|
33
33
|
|
|
34
34
|
A sibling `properties/` directory may also be present at `<output-dir>/properties/` — it belongs to `property-extract` and **must not** be touched by this skill. Working files this skill creates (screenshots, intermediate JSON, snapshot dumps) must be cleaned up before reporting completion. The four artifacts above are the deliverable; nothing else this skill writes is "scratch" that survives.
|
|
35
35
|
|
|
@@ -153,7 +153,7 @@ A photographic crop of the logo from a screenshot is **not** acceptable — the
|
|
|
153
153
|
|
|
154
154
|
### `description.md`
|
|
155
155
|
|
|
156
|
-
Plain Markdown, no frontmatter.
|
|
156
|
+
Plain Markdown, no frontmatter. Structure:
|
|
157
157
|
|
|
158
158
|
1. Brand name on its own line.
|
|
159
159
|
2. The brand's own tagline / one-liner from the homepage hero.
|
|
@@ -199,13 +199,7 @@ The skill does **not** prescribe which browser tool to use. Where multiple are a
|
|
|
199
199
|
|
|
200
200
|
## Reference standard
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
- `/Users/neo/estate-agents/beacons/DESIGN.md` — the depth and format expected of the token spec.
|
|
205
|
-
- `/Users/neo/estate-agents/beacons/description.md` — the voice and structure expected of the company description.
|
|
206
|
-
- `/Users/neo/estate-agents/beacons/beacons-logo-light.png`, `…-dark.png` — the visual standard for logo crops.
|
|
207
|
-
|
|
208
|
-
A delivered package that diverges substantially in structure from the reference is wrong, even if the content is accurate.
|
|
202
|
+
The four artifact contracts above (DESIGN.md tier-1/2/3 token spec, the two PNG logo files with filename describing the art colour, `description.md` with the official-details block) are the contract. If a prior conforming brand pack exists on disk at any `<brand_dir>/` (look for the four artifacts in the layout shown in **Outcome contract**), inspect it as a worked example. A delivered package that diverges substantially in structure from those contracts is wrong, even if the content is accurate.
|
|
209
203
|
|
|
210
204
|
## Common mistakes
|
|
211
205
|
|
|
@@ -216,7 +210,7 @@ A delivered package that diverges substantially in structure from the reference
|
|
|
216
210
|
| Paraphrasing the homepage hero into "punchier" copy | `description.md` is the source of truth for the brand's voice. The brand's words, not yours. |
|
|
217
211
|
| Inventing token values that the site doesn't use | Token tier 1 is **observed**. `(proposed)` is for tier-2/3 values that fill an obvious gap, not for guesses about what the brand wants. |
|
|
218
212
|
| Including blog posts or case studies in `description.md` | The file is identity, not editorial. |
|
|
219
|
-
| Naming files after the
|
|
213
|
+
| Naming files after the FQDN (`<brand>realestate-logo.png` instead of `<brand>-logo.png`) | Slug is the brand name, not the full domain. |
|
|
220
214
|
| Skipping the mobile viewport during token capture | Type scale and section padding both differ at mobile. A desktop-only tokenization is incomplete. |
|
|
221
215
|
| Generating the dark theme block in `DESIGN.md` from imagination | If the site is light-only, the dark theme is an **inversion derived from the primitives**, marked "proposed", not a parallel design system. |
|
|
222
216
|
| Embedding the company description inside `DESIGN.md` | The artifacts are separable on purpose. Each file has one job. |
|
|
@@ -108,7 +108,7 @@ The skill performs four checks in order. Each rule fully specifies its *conditio
|
|
|
108
108
|
|
|
109
109
|
### 1. Resolve the brand identity
|
|
110
110
|
|
|
111
|
-
If `brand_source` is a URL: derive `brand_slug` as the lowercase domain root with no TLD (e.g. `https
|
|
111
|
+
If `brand_source` is a URL: derive `brand_slug` as the lowercase domain root with no TLD (e.g. `https://<agent>.co.uk` → `<agent>`, `https://example-agent.co.uk` → `example-agent`).
|
|
112
112
|
|
|
113
113
|
If `brand_source` is a path: `brand_slug` = the directory's basename.
|
|
114
114
|
|
|
@@ -132,7 +132,7 @@ If `brand_source` was a path and `DESIGN.md` is missing, treat that as an author
|
|
|
132
132
|
|
|
133
133
|
### 3. Resolve the property identity
|
|
134
134
|
|
|
135
|
-
If `property_source` is a URL: derive `property_slug` from the
|
|
135
|
+
If `property_source` is a URL: derive `property_slug` from whichever path component the source exposes (e.g. `/property/<slug>/<id>/` on Loop-CRM tenants; portals expose different shapes). The folder name is `<property_slug>-<id>` (e.g. `<street-locality-postcode>-<listing-id>`).
|
|
136
136
|
|
|
137
137
|
If `property_source` is a path: the folder name is the directory's basename.
|
|
138
138
|
|
|
@@ -178,6 +178,8 @@ Property photographs almost always exceed this threshold. Concrete examples in t
|
|
|
178
178
|
| `ChatGPT-Image-*` (AI render) | 1024 or 2048px (borderline — measure) |
|
|
179
179
|
| `Screenshot-*` (desktop capture) | 1200–2880px (borderline — measure) |
|
|
180
180
|
|
|
181
|
+
Filename prefixes vary by source — Loop-CRM tenants commonly ship the shapes above; other portals re-serve under their own filename conventions. The 2000 px rule is what binds, not the prefix.
|
|
182
|
+
|
|
181
183
|
### Safe inspection workflow
|
|
182
184
|
|
|
183
185
|
Before any `Read` against an image:
|
|
@@ -212,7 +214,7 @@ The orchestrator does not bundle the upstream skills' outputs — each leaves it
|
|
|
212
214
|
|
|
213
215
|
## Slot-assignment hand-off — verify image content visually, not by filename
|
|
214
216
|
|
|
215
|
-
A repeated failure mode in this pipeline is mis-mapping a slot from filename alone — the brochure step references `images
|
|
217
|
+
A repeated failure mode in this pipeline is mis-mapping a slot from filename alone — the brochure step references `images/<property-slug>-22.webp` because slot 22 should be the inglenook, but the actual photograph at index 22 is a downstairs WC. Filename tells you order; pixels tell you content.
|
|
216
218
|
|
|
217
219
|
The orchestrator's role is to **enforce the visual-verification step** before `property-brochure` writes the HTML:
|
|
218
220
|
|
|
@@ -290,11 +292,9 @@ After a complete run, the on-disk layout is **exactly** this — no deeper nesti
|
|
|
290
292
|
|
|
291
293
|
The `output/` folder is a portable deliverable: every image referenced by `brochure.html` resolves to a file under `output/images/`. References that escape `output/` (`../images/`, `../../floorplans/`, `../../epc/`) are a defect — the brochure must not depend on the sibling property-extract folders staying in place.
|
|
292
294
|
|
|
293
|
-
|
|
294
|
-
- `/Users/neo/estate-agents/muvin/` (brand_slug = `muvin`)
|
|
295
|
-
- `/Users/neo/estate-agents/beacons/` (brand_slug = `beacons`)
|
|
295
|
+
The brand-workspace set is whatever directories exist under the caller's `<output_root>/` — enumerate them with `ls <output_root>` at runtime rather than assuming a fixed set. Each brand directory is its own workspace and matches the `<brand_slug>/` layout above.
|
|
296
296
|
|
|
297
|
-
A fresh run with no `output_root` and no existing brand pack lands the workspace in the caller's CWD
|
|
297
|
+
A fresh run with no `output_root` and no existing brand pack lands the workspace in the caller's CWD as `./<brand_slug>/`, not under any other path.
|
|
298
298
|
|
|
299
299
|
Determinism rules — a run that violates any of these is wrong, even if the brochure renders:
|
|
300
300
|
- `properties/` is **inside** `<brand_dir>/`, never a sibling.
|
package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-extract/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: property-extract
|
|
3
|
-
description: Use when a live property listing URL on
|
|
3
|
+
description: Use when a live property listing URL on any UK estate-agent website 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
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -15,7 +15,7 @@ allowed-tools:
|
|
|
15
15
|
|
|
16
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
17
|
|
|
18
|
-
The
|
|
18
|
+
The contract is **portal-agnostic**: the output shape is the same whether the source is an agent's own site (Muvin / Loop CRM tenants, custom builds) or a portal (Rightmove, Zoopla, OnTheMarket, OpenRent). The static-HTML probe is the cheap default; when it returns no asset URLs or the data is tab-bound, fall back to a headless browser. See **Process — high level**.
|
|
19
19
|
|
|
20
20
|
## Outcome contract
|
|
21
21
|
|
|
@@ -34,7 +34,7 @@ Every photograph and floorplan referenced by the listing must be downloaded. `ep
|
|
|
34
34
|
|
|
35
35
|
Do **not** pre-create a `brochure/` slot. `property-brochure` writes its deliverable directly to `<property_dir>/output/` — see `property-brochure/SKILL.md → Reference standard`. An empty `brochure/` next to `output/` is the legacy layout and a defect.
|
|
36
36
|
|
|
37
|
-
`<property-slug>` comes from the URL path segment (e.g.
|
|
37
|
+
`<property-slug>` comes from the URL path segment (e.g. `<street-locality-postcode>` for Loop-CRM-style URLs, or whatever slug component the source portal exposes). `<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.
|
|
38
38
|
|
|
39
39
|
Anything else (raw HTML dumps, `/tmp` files, intermediate URL lists) must be cleaned up before reporting completion.
|
|
40
40
|
|
|
@@ -42,7 +42,7 @@ Anything else (raw HTML dumps, `/tmp` files, intermediate URL lists) must be cle
|
|
|
42
42
|
|
|
43
43
|
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.
|
|
44
44
|
|
|
45
|
-
Optional: an output directory. The default is `<brand_dir>/properties/`, where `<brand_dir>` is the brand workspace for the agent that owns the listing.
|
|
45
|
+
Optional: an output directory. The default is `<brand_dir>/properties/`, where `<brand_dir>` is the brand workspace for the agent that owns the listing. If a brand pack already exists at `<brand_dir>/DESIGN.md`, properties nest under `<brand_dir>/properties/`. If the brand workspace cannot be located, fall back to `./properties/` in the caller's current working directory.
|
|
46
46
|
|
|
47
47
|
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.
|
|
48
48
|
|
|
@@ -50,14 +50,15 @@ The property directory **must** sit inside its brand workspace at `<brand_dir>/p
|
|
|
50
50
|
|
|
51
51
|
| In scope | Out of scope |
|
|
52
52
|
|---|---|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
53
|
+
| Download every CDN-hosted image, floorplan and EPC asset referenced by the listing page | Stripping AI-generated images from the photo set — keep them all and flag in metadata |
|
|
54
|
+
| Extract description copy verbatim from whichever description container the page exposes | Paraphrasing or rewriting the description — the brochure step owns voice |
|
|
55
|
+
| Capture a screenshot of any map element by heuristic (provider-agnostic — Google Maps iframe, Mapbox canvas, static-map `<img>`, custom embed) | Synthesising a map when the listing has none (no postcode-centroid renders, no AI maps) |
|
|
55
56
|
| Property description, key features, price, specs, agent contact | Walkthrough video transcription (the property-brochure skill handles that separately if the user supplies one) |
|
|
56
57
|
| 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` |
|
|
57
58
|
| Council tax band as shown on the page | Council tax band verification against VOA — out of scope |
|
|
58
59
|
| 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 |
|
|
59
60
|
|
|
60
|
-
|
|
61
|
+
The skill is portal-agnostic. The Loop-CRM CDN pattern (`*.b-cdn.net/propertyimages/...`, `*.b-cdn.net/floorplans/...`) is one common example that the static-HTML probe handles cheaply; agency-specific platforms (Rightmove, Zoopla, OnTheMarket, OpenRent, custom builds) JS-render most data and require the Playwright fallback documented in **Process — high level** step 4b. When the static probe returns no asset URLs or critical fields are tab-bound, escalate to the headless-browser fallback as a first-class path, not a conditional one. If even that returns nothing, stop and report `STATUS: BLOCKED` — do not synthesise an asset list.
|
|
61
62
|
|
|
62
63
|
## Artifact contracts
|
|
63
64
|
|
|
@@ -67,12 +68,9 @@ The three subfolders (`images/`, `floorplans/`, `epc/`) are **mandatory and name
|
|
|
67
68
|
|
|
68
69
|
### `images/`
|
|
69
70
|
|
|
70
|
-
Every URL on the page
|
|
71
|
+
Every URL on the page pointing at an image asset is in scope. On Loop-CRM tenants the pattern is `b-cdn.net/propertyimages/<tenant-uuid>/<listing-id>/` — two example buckets in active use as of April 2026 are `loop-app.b-cdn.net` (older 2024-vintage uploads) and `loopcrm.b-cdn.net` (newer 2026 additions including drone shots, AI-staged renders, screenshots). Other portals serve from their own hosts (e.g. Rightmove's `media.rightmove.co.uk`); the rule is the same — grep every image URL the page emits, deduplicate, download all of them.
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
- `loopcrm.b-cdn.net` — newer 2026 additions (drone shots, AI-staged renders, screenshots)
|
|
74
|
-
|
|
75
|
-
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.
|
|
73
|
+
Preserve the original filenames — many tenants encode upload timestamps as Unix epochs in the filename (e.g. `DSC01495_1727361503898.jpg` → 26 Sept 2024) which are useful for ordering and de-duplication later. Where filenames carry no timestamp, fall back to download order.
|
|
76
74
|
|
|
77
75
|
Image categories observable from filename prefixes:
|
|
78
76
|
|
|
@@ -88,7 +86,7 @@ Record the count per prefix in `property.json` under `media.image_breakdown` —
|
|
|
88
86
|
|
|
89
87
|
#### Curator-friendly rename — "<Property Name> N.jpg"
|
|
90
88
|
|
|
91
|
-
After downloading, **also rename the images to `<Property Name> N.jpg`** (1-indexed, ordered by upload timestamp parsed from the original filename) so a human curator can browse `images/` in Finder/Preview and intuitively pick which photo goes in which slot. The downstream `property-brochure` slot map references `images/<property-slug>-NN.webp`, where `NN` matches the curator-chosen `N` 1:1 — so renaming source images to that order at extract time makes the entire pipeline traceable: the curator sees
|
|
89
|
+
After downloading, **also rename the images to `<Property Name> N.jpg`** (1-indexed, ordered by upload timestamp parsed from the original filename) so a human curator can browse `images/` in Finder/Preview and intuitively pick which photo goes in which slot. The downstream `property-brochure` slot map references `images/<property-slug>-NN.webp`, where `NN` matches the curator-chosen `N` 1:1 — so renaming source images to that order at extract time makes the entire pipeline traceable: the curator sees `<Property Name> 22.jpg` in Finder, the brochure HTML references `images/<property-slug>-22.webp`, and a search across either resolves to the same photograph.
|
|
92
90
|
|
|
93
91
|
The rename is **not** a replacement of the original CDN-named files — those are preserved as-is for timestamp ordering and de-duplication. The renamed files are the same bytes (or a `cp`/`ln` of the originals), placed alongside, with the new `<Property Name> N.jpg` filenames.
|
|
94
92
|
|
|
@@ -105,15 +103,15 @@ for src in $(ls -1 | grep -E '^(DSC|DJI|ChatGPT-Image|Screenshot|IMG|iPhone|What
|
|
|
105
103
|
done
|
|
106
104
|
```
|
|
107
105
|
|
|
108
|
-
The `<Property Name>` is taken from `property.json -> property_name` (see *Property name vs address* below). If the property has no distinct name (uncommon at this register), use the first part of the address (
|
|
106
|
+
The `<Property Name>` is taken from `property.json -> property_name` (see *Property name vs address* below). If the property has no distinct name (uncommon at this register), use the first part of the address (the street name).
|
|
109
107
|
|
|
110
108
|
Record the original-to-curator-name mapping in `property.json -> media.image_curator_map` so the rename is reversible:
|
|
111
109
|
|
|
112
110
|
```json
|
|
113
111
|
"media": {
|
|
114
112
|
"image_curator_map": {
|
|
115
|
-
"
|
|
116
|
-
"
|
|
113
|
+
"The Old Rectory 1.jpg": "DJI_0125_1777122816019.jpg",
|
|
114
|
+
"The Old Rectory 2.jpg": "DJI_0115_1777122829462.jpg",
|
|
117
115
|
"...": "..."
|
|
118
116
|
}
|
|
119
117
|
}
|
|
@@ -121,7 +119,7 @@ Record the original-to-curator-name mapping in `property.json -> media.image_cur
|
|
|
121
119
|
|
|
122
120
|
### `floorplans/`
|
|
123
121
|
|
|
124
|
-
|
|
122
|
+
Every URL on the page pointing at a floorplan asset is in scope. On Loop-CRM tenants the pattern is `b-cdn.net/floorplans/<tenant-uuid>/<listing-id>/`; other portals serve from their own hosts. Listings typically ship one floorplan per floor (so 1–3 files for a UK home). Preserve original filenames.
|
|
125
123
|
|
|
126
124
|
### `epc/`
|
|
127
125
|
|
|
@@ -131,7 +129,7 @@ If the page links a PDF whose URL contains `epc` or whose link text mentions "EP
|
|
|
131
129
|
|
|
132
130
|
**Maps are extracted, never synthesized.** If the listing doesn't supply one, the brochure ships without a map. No fallback to OSM static maps, no postcode-geocoded re-render via postcodes.io, no AI-generated map artwork. Postcode centroids can mislead about exact location, and the brochure should reflect what the agency actually publishes — not what the pipeline could imagine.
|
|
133
131
|
|
|
134
|
-
The capture is **provider-agnostic by design.** Estate agents embed maps in many ways: Google Maps iframes (Loop
|
|
132
|
+
The capture is **provider-agnostic by design.** Estate agents embed maps in many ways: Google Maps iframes (common on Loop-CRM tenants), Mapbox or Leaflet `<div>`+canvas instantiations (custom builds), `<img>` static-map renders (used by some portal-style listings), Apple Maps embeds, custom-class wrappers — and that list will only grow. Don't hard-code a single CMS's markup. Instead: **find a map element by heuristic, screenshot it, save the bytes.** The provider's brand and tile style come along for the ride.
|
|
135
133
|
|
|
136
134
|
**Detect.** Render the listing page in a real browser (Playwright). Try these heuristics in order, taking the first non-empty hit:
|
|
137
135
|
|
|
@@ -166,21 +164,21 @@ The rule, in one line: **extract or omit**.
|
|
|
166
164
|
|
|
167
165
|
### Property name vs address — they are not the same field
|
|
168
166
|
|
|
169
|
-
At the super-premium register, many properties have a **distinct name** that is separate from the postal address: *
|
|
167
|
+
At the super-premium register, many properties have a **distinct name** that is separate from the postal address: *The Old Rectory*, *Mill House*, *Beacon House*. The brochure's cover hero is the property name; the subtitle is the address. The two must be captured separately at extraction time.
|
|
170
168
|
|
|
171
169
|
Detect the property name by:
|
|
172
170
|
|
|
173
|
-
1. Looking for "<Name>, <street>" patterns in the listing's title or H1 (e.g. "
|
|
174
|
-
2. Looking for a name that is *not* a numbered street address (numbered addresses like "12
|
|
175
|
-
3. Cross-checking with a Sprift / Land Registry report — if the title is registered as "
|
|
171
|
+
1. Looking for "<Name>, <street>" patterns in the listing's title or H1 (e.g. "The Old Rectory, Mill Lane").
|
|
172
|
+
2. Looking for a name that is *not* a numbered street address (numbered addresses like "12 Mill Lane" don't have a separate name).
|
|
173
|
+
3. Cross-checking with a Sprift / Land Registry report — if the title is registered as "<Name> at <street>", that's the property name.
|
|
176
174
|
|
|
177
175
|
Record both in `property.json`:
|
|
178
176
|
|
|
179
177
|
```json
|
|
180
|
-
"property_name": "
|
|
178
|
+
"property_name": "The Old Rectory", // or null if the property has no distinct name
|
|
181
179
|
"address": {
|
|
182
|
-
"line_1": "
|
|
183
|
-
"locality": "
|
|
180
|
+
"line_1": "Mill Lane",
|
|
181
|
+
"locality": "<Locality>",
|
|
184
182
|
"...": "..."
|
|
185
183
|
}
|
|
186
184
|
```
|
|
@@ -309,29 +307,24 @@ Capture rules:
|
|
|
309
307
|
|
|
310
308
|
## Image preview safety
|
|
311
309
|
|
|
312
|
-
**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
|
|
310
|
+
**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 any premium 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.
|
|
313
311
|
|
|
314
312
|
## Process — high level
|
|
315
313
|
|
|
316
314
|
The skill orchestrates four capabilities, each a **what** not a **how**:
|
|
317
315
|
|
|
318
|
-
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
|
|
319
|
-
2. **Extract.**
|
|
316
|
+
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 JS-rendered and you need a headless browser.
|
|
317
|
+
2. **Extract — tiered.** Try the static-HTML path first because it's cheap: pull the raw HTML and grep every image-asset URL (Loop-CRM tenants use `b-cdn.net/propertyimages/...` and `b-cdn.net/floorplans/...`; other portals serve from their own hosts), deduplicate, grep PDF URLs containing `epc`, extract any visible description container. **If the static probe returns zero image URLs, or the probed summary in step 1 reports content the static HTML does not contain (EPC band, floorplan thumbnail, video URL), escalate to the Playwright fallback in step 4b** — that's the first-class path for portals and tabbed UIs, not a conditional one. (Map detection is provider-agnostic and happens in step 4 below — don't try to parse map markup at this static-HTML stage.)
|
|
320
318
|
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.
|
|
321
319
|
4. **Capture map** (conditional, provider-agnostic). Drive Playwright to the listing URL and apply the heuristic detector under **Map — extract or omit**: try iframe-by-provider, then class/id-by-keyword, then static-map images, then visual fallback. On the first hit, scroll into view, wait for tiles, screenshot the **element** (not the page), convert to `map.webp` at ~1500 px wide. If no heuristic finds a map, skip — **extract or omit**, no fallback synthesis.
|
|
322
|
-
4b. **Traverse tabbed UIs (
|
|
320
|
+
4b. **Traverse tabbed UIs and JS-rendered portals (first-class for non-static hosts).** Modern listing pages from Loop CRM tenants, Rightmove, Zoopla, OnTheMarket and others render top-level data in tabs — *Details / Floorplan / EPC / Virtual Tour / Map View / Book Viewing* — and the static HTML returned by `WebFetch` or `curl` often does not include the inactive-tab content. Whenever step 2's static probe came up short, drive a Playwright session against the listing URL and walk the tab list: detect elements with `role="tablist"`, `role="tab"`, or class/id substrings `tab` containing the keywords `EPC`, `Floor plan`, `Map`, `Virtual tour`, `Brochure`. For each tab found, `page.click(<selector>)`, `page.waitForLoadState('networkidle')`, then harvest the panel content. For the EPC tab specifically: scrape the certificate PDF/PNG link and the displayed current/potential scores into `specifications.epc_rating`, `specifications.epc_current_score`, `specifications.epc_potential_score`. For other tabs: extract what each contract field needs and skip the rest. The traversal is principled — never hard-code a single agency's or portal's tab markup as the sole detector; the same listing surface ships with different tab implementations across CMS tenants and portal layouts.
|
|
323
321
|
5. **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. `media.map` is populated iff a map screenshot landed on disk; `address.geo` is populated iff coordinates were parseable from a recognised URL pattern (and may legitimately be `null` even when `media.map` is set — see the schema notes).
|
|
324
322
|
|
|
325
|
-
The skill does not prescribe which HTTP tool to use. `curl` is fine for
|
|
323
|
+
The skill does not prescribe which HTTP tool to use. `curl` is fine for static-HTML hosts (most Loop-CRM tenants serve listing data inline); switch to Chrome DevTools MCP or Playwright for JS-rendered listing pages and portals — the contract on the output is unchanged.
|
|
326
324
|
|
|
327
325
|
## Reference standard
|
|
328
326
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
- `/Users/neo/estate-agents/muvin/properties/henham-road-debden-green-hamperden-end-cb11-3lz-949931/property.json` — the JSON schema in practice.
|
|
332
|
-
- `/Users/neo/estate-agents/muvin/properties/henham-road-debden-green-hamperden-end-cb11-3lz-949931/description.md` — the prose voice and structure.
|
|
333
|
-
|
|
334
|
-
A delivered package that diverges substantially in shape from the reference is wrong, even if the content is accurate.
|
|
327
|
+
The format contract is defined by `property.json` (schema above) and `description.md` (structure above). If the caller has a prior conforming property pack on disk (under any `<brand_dir>/properties/<slug>-<id>/`), read its `property.json` and `description.md` to anchor the format. A delivered package that diverges substantially in shape from those is wrong, even if the content is accurate.
|
|
335
328
|
|
|
336
329
|
## Common mistakes
|
|
337
330
|
|
|
@@ -343,8 +336,8 @@ A delivered package that diverges substantially in shape from the reference is w
|
|
|
343
336
|
| 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. |
|
|
344
337
|
| 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. |
|
|
345
338
|
| 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. |
|
|
346
|
-
| Saving `/tmp/
|
|
347
|
-
| Hardcoding the tenant UUID |
|
|
339
|
+
| Saving `/tmp/listing_raw.html` or other working files inside the output directory | The directory is the deliverable. Working files get cleaned up. |
|
|
340
|
+
| Hardcoding the tenant UUID | On Loop-CRM tenants the UUID identifies the agency; different offices have different tenant IDs. Extract it from the actual URLs on the page rather than assuming a single value. |
|
|
348
341
|
| Treating "EPC: TBC" as a missing field | "TBC" is information — the agent is telling you the assessment hasn't been done. Record it verbatim. |
|
|
349
342
|
| Recording "EPC: TBC" when the listing's EPC tab actually shows a band but the static HTML did not | Modern listings tab-hide data behind a JS tab switcher; `WebFetch` / `curl` see only the active tab. If the listing visibly carries EPC content the static HTML lacks, drive Playwright per step 4b and harvest from the tab panel. "TBC" recorded from a missed-tab extract is a silent data-loss defect, not a faithful record. |
|
|
350
343
|
| Synthesizing a map when the listing has none | The rule is **extract or omit**. Postcode-centroid renders, OSM static maps, and AI-generated map artwork are all forbidden. If the heuristic detector returns nothing, write `media.map: null` and move on. |
|
|
@@ -369,6 +362,5 @@ If any of those are not true, report `DONE_WITH_CONCERNS` and list each gap.
|
|
|
369
362
|
## When NOT to use this skill
|
|
370
363
|
|
|
371
364
|
- The user wants a brochure produced from photos they already have on disk → skip extraction, go straight to `property-brochure`.
|
|
372
|
-
- 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.
|
|
373
365
|
- The user wants a quick price/specs lookup, not the full asset bundle → use `WebFetch` directly. The folder structure is overkill.
|
|
374
366
|
- The user wants market data, comparables, or transaction history → that's a different research task; this skill is asset staging, not analysis.
|
package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/SKILL.md
CHANGED
|
@@ -19,9 +19,9 @@ The report has its own typographic identity — a luxury serif stack pinned in t
|
|
|
19
19
|
|
|
20
20
|
## Inputs (never invented)
|
|
21
21
|
|
|
22
|
-
- **`design_tokens_path`** — path to a `DESIGN.md` that tokenises the agent's brand
|
|
23
|
-
- **`logo_light_path`** / **`logo_dark_path`** — PNG/SVG. Light = white-on-dark version (for the teal-toned cover); dark = full-colour version (for body-page headers). When supplied, the renderer emits an `<img>` for the logo; when omitted, it falls back to a Cormorant-Garamond text wordmark using `brand.name` + `brand.tagline`. The text-wordmark fallback is acceptable for brands whose logo is essentially a serif-typeset name
|
|
24
|
-
- **`property_urls`** — list of up to 10 source URLs (
|
|
22
|
+
- **`design_tokens_path`** — path to a `DESIGN.md` that tokenises the agent's brand. Resolve it from `brand_source` at runtime: when `brand_source` is a URL, the path is `<brand_dir>/DESIGN.md` for whatever brand directory the orchestrator created (or already had on disk); when `brand_source` is a directory path, the file is at `<brand_source>/DESIGN.md`. Read the canonical hex values directly; never substitute "close" colours. **Only colour tokens are consumed** — the report imports `primary` (e.g. teal-900), `primary_dark`, `accent` (e.g. gold-500), `paper`, `paper_banded`, and `rule`. Any typography, spacing, or radius tokens in the agent's DESIGN.md are *ignored by design*.
|
|
23
|
+
- **`logo_light_path`** / **`logo_dark_path`** — PNG/SVG. Light = white-on-dark version (for the teal-toned cover); dark = full-colour version (for body-page headers). When supplied, the renderer emits an `<img>` for the logo; when omitted, it falls back to a Cormorant-Garamond text wordmark using `brand.name` + `brand.tagline`. The text-wordmark fallback is acceptable for brands whose logo is essentially a serif-typeset name; for richer marks, supply the files.
|
|
24
|
+
- **`property_urls`** — list of up to 10 source URLs from any UK estate-agent or portal site (Loop-CRM tenants, Rightmove, Zoopla, OnTheMarket, etc.). Each must resolve to a single property listing page. Reject more than 10; the layout breaks at >10 cards.
|
|
25
25
|
- **`market_data`** — flat dict of numbers (average asking, average sold, £/sqft, YoY growth, demand rating, days-on-market, property-type distribution, sample size, period). Source from a market intelligence API (PropertyData / Land Registry / ONS) or paste from an existing report. **The period is the *generated* date, not whatever appears in the URL slug** — the Market Trak `oct-2025` slug describes a snapshot from May 2026 (Oct 2025 was the trailing window). Use the report-page's stated `Generated` value.
|
|
26
26
|
|
|
27
27
|
## How the skill renders
|
|
@@ -90,7 +90,7 @@ The disclaimer block on the final page must name:
|
|
|
90
90
|
- **Logo invisible in preview.** The IDE preview panel can't always resolve relative `img/` paths or large base64 data URIs. The deliverable PDF is the source of truth; viewing the HTML in a real browser (or via `python3 -m http.server`) is the second source of truth. Don't burn iterations chasing preview-panel artefacts.
|
|
91
91
|
- **Date drift from URL slug.** A Market Trak URL like `…-oct-2025?…` does not mean the report is October 2025. Always trust the `Generated:` field on the source page.
|
|
92
92
|
- **Page 3 / page 4 overflow.** The default Cormorant Garamond + Lora stack is slightly taller-set than a sans default. KPI tile padding and panel padding need to come down (~5 mm not 7 mm) for serif typography to fit alongside the photo strip on page 3 and two listing cards on page 4.
|
|
93
|
-
- **Property-socials skipped.** A report that drops raw `loop-app.b-cdn.net/propertyimages/...jpg`
|
|
93
|
+
- **Property-socials skipped.** A report that drops the raw listing-CDN image straight into a tile (whether `loop-app.b-cdn.net/propertyimages/...jpg`, `media.rightmove.co.uk/...`, or any other host) breaks the brand contract — the tiles have no overlay, no scrim, no address copy. Always run the OG pipeline; if it can't run, surface the gap, don't substitute.
|
|
94
94
|
- **Anchor links dead in PDF.** Chrome `--print-to-pdf` preserves `<a href>` as live PDF annotations. Verify by opening the PDF in Preview and clicking a listing — if the link is dead, the HTML wrapped a `<div>` instead of an `<a>`.
|
|
95
95
|
|
|
96
96
|
## Out of scope
|
package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-socials/SKILL.md
CHANGED
|
@@ -19,8 +19,9 @@ shots — it does not re-design anything.
|
|
|
19
19
|
that page. Do not pick new colours.
|
|
20
20
|
- **Copy** — `property.json` is canonical for address, price, qualifier,
|
|
21
21
|
bedrooms/baths/receptions, agent name + phone. The page's
|
|
22
|
-
`<meta name="description">` is the sub-headline. The
|
|
23
|
-
|
|
22
|
+
`<meta name="description">` is the sub-headline. The property's display
|
|
23
|
+
name (`property.json -> property_name`, or the first address line if the
|
|
24
|
+
property has no distinct name) is the headline.
|
|
24
25
|
- **Hero images** — `images/<slug>-hero-1-main.webp`, `hero-2-kitchen.webp`,
|
|
25
26
|
`hero-3-garden.webp` are the curated set. Use them by name; do not pick
|
|
26
27
|
numbered shots from the raw set unless the curated heroes are missing.
|
|
@@ -4,6 +4,7 @@ description: "Founding-a-business agent. Drives an operator from raw idea to fun
|
|
|
4
4
|
requires:
|
|
5
5
|
- projects
|
|
6
6
|
- work
|
|
7
|
+
- deep-research
|
|
7
8
|
metadata: {"platform":{"always":false,"embed":["admin"],"pluginKey":"venture-studio","optional":true,"recommended":true}}
|
|
8
9
|
---
|
|
9
10
|
|
|
@@ -62,8 +63,8 @@ The script's three effects:
|
|
|
62
63
|
2. **Creates the `Project` node.** Tier `full` (data-room work is multi-phase). Project name is the business's working name; description references the data-room root path.
|
|
63
64
|
3. **Enumerates the eight artefact Tasks** in section order — one transaction, atomic with the Project. The work-item list the script pre-seeds:
|
|
64
65
|
- **Stage 1 — Office-hours design doc** → produces `01-narrative/office-hours-design.md` (skill: `office-hours`)
|
|
65
|
-
- **Brand pack** → produces brand identity files into `06-product-ip/brand/` (skill: `brand-pack`)
|
|
66
66
|
- **Stage 2 — Wedge validation + landing page + PRD** → produces `01-narrative/{PMF, LANDING, PRD}.md` (skill: `zero-to-prototype`)
|
|
67
|
+
- **Brand pack** → produces brand guidelines + summary + color palette + typography system + tone-of-voice (voice/messaging/copy) + logo guidelines into `06-product-ip/brand/` (skill: `brand-pack`)
|
|
67
68
|
- **Stage 3 — Business plan** → produces `01-narrative/business-plan.md` (skill: `investor-data-room` Stage 3)
|
|
68
69
|
- **Stage 3b — Term sheet** → produces `html/prospectus/term_sheet.html` (skill: `investor-data-room` Stage 3b)
|
|
69
70
|
- **Stage 4 — Deck blueprint** → produces `01-narrative/deck-blueprint.md` (skill: `investor-data-room` Stage 4)
|
|
@@ -96,6 +97,10 @@ When the operator's intent matches a row but the scaffold does not yet exist, ru
|
|
|
96
97
|
- If a section reveals a new artefact the operator wants (e.g. a competitor-claims-rebuttal in `08-market/`), `work-create` a new Task under the same Project, then proceed.
|
|
97
98
|
- The Project's health signal (green/amber/red) is computed from Task state. Use `project-get` at the start of each turn to surface what's outstanding.
|
|
98
99
|
|
|
100
|
+
## Research routing
|
|
101
|
+
|
|
102
|
+
Every structured-research task — market sizing (TAM/SAM/SOM + CAGR), compliance research (DMCC / ICO ADM / EU AI Act), competitor scans, comparable rounds and exit comparables, named-acquirer enumeration — routes through the `research-assistant` specialist with the five `deep-research` skills (`deep-research`, `book-mirror`, `strategic-reading`, `academic-verify`, `data-research`). Dispatch the specialist; do not call `WebSearch` or `WebFetch` directly from a venture-studio skill. The specialist returns structured findings with citations the data-room artefacts can quote verbatim.
|
|
103
|
+
|
|
99
104
|
## Tone
|
|
100
105
|
|
|
101
106
|
Founder-facing. Direct, evidence-based, no flattery. You are the chief of staff for a one-person founding team — your job is to keep every artefact tracked and every deadline visible, while the operator focuses on the parts only they can do (customer conversations, founder signal, vision).
|
|
@@ -64,8 +64,8 @@ PAYLOAD=$(cat <<JSON
|
|
|
64
64
|
"tier": "full",
|
|
65
65
|
"workItems": [
|
|
66
66
|
{"name": "Stage 1 — Office-hours design doc", "description": "Produces 01-narrative/office-hours-design.md via the office-hours skill."},
|
|
67
|
-
{"name": "Brand pack", "description": "Produces brand identity (palette, typography, logo) into 06-product-ip/brand/ via the brand-pack skill."},
|
|
68
67
|
{"name": "Stage 2 — Wedge validation + landing page + PRD", "description": "Produces 01-narrative/{PMF,LANDING,PRD}.md via the zero-to-prototype skill."},
|
|
68
|
+
{"name": "Brand pack", "description": "Produces brand guidelines + summary + color palette + typography system + tone-of-voice (voice/messaging/copy) + logo guidelines into 06-product-ip/brand/ via the brand-pack skill."},
|
|
69
69
|
{"name": "Stage 3 — Business plan", "description": "Produces 01-narrative/business-plan.md via investor-data-room Stage 3."},
|
|
70
70
|
{"name": "Stage 3b — Term sheet", "description": "Produces html/prospectus/term_sheet.html via investor-data-room Stage 3b."},
|
|
71
71
|
{"name": "Stage 4 — Deck blueprint", "description": "Produces 01-narrative/deck-blueprint.md via investor-data-room Stage 4."},
|
|
@@ -39,7 +39,7 @@ Before generating anything, gather the following. Ask all questions in a single
|
|
|
39
39
|
- Website URL (fetch it if provided — extract existing colors, fonts, tone)
|
|
40
40
|
- Inspiration brands (brands they admire aesthetically)
|
|
41
41
|
|
|
42
|
-
If the user provides a URL,
|
|
42
|
+
If the user provides a URL — their own site, a competitor brand, or an inspiration brand — dispatch the `research-assistant` specialist (with `deep-research` for site copy + visual scan, `WebFetch` available through the specialist) rather than calling `fetch` or `WebFetch` directly from this skill. The specialist returns: dominant colors (CSS or visual description), font choices, tone of copy, and any existing brand signals. Pre-fill your recommendations from the specialist's structured findings.
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: investor-data-room
|
|
3
|
-
description: Use when a UK-domiciled founder needs to produce a full seed-raise pack from idea to deliverables: graph-structured data room,
|
|
3
|
+
description: Use when a UK-domiciled founder needs to produce a full seed-raise pack from idea to deliverables: graph-structured data room, 16-section business plan, persuasive prospectus + formal term sheet (with FCA self-certification appendices), 13-slide deck blueprint, print-ready HTML+PDF for each. Trigger phrases include "build me a data room", "draft a business plan", "deck from the business plan", "draft an investment prospectus", "generate a term sheet", "from office hours to investor pack", "set up the fundraise repo". The skill never speculates on financial figures or cap-table values: every number traces to a Companies House filing, a financial model worksheet, or a source citation. Public-facing artefacts contain zero internal workings (no "reconciliation pending", no "open Q" markers, no comparison-to-baseline commentary). Design tokens are harmonised across business plan, prospectus, term sheet, and deck via the operator's project design-tokens spec.
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -25,13 +25,15 @@ Complete when the data room contains:
|
|
|
25
25
|
README.md # data-room index, status snapshot, doctrine
|
|
26
26
|
01-narrative/
|
|
27
27
|
office-hours-design.md # ideation working scratchpad
|
|
28
|
-
business-plan.md #
|
|
29
|
-
deck-blueprint.md #
|
|
28
|
+
business-plan.md # 16-section business plan
|
|
29
|
+
deck-blueprint.md # 13-slide blueprint
|
|
30
|
+
exit-thesis.md # named acquirers + recent exit comparables
|
|
30
31
|
02-corporate-legal/
|
|
31
32
|
README.md # incorporation filings, articles, board minutes
|
|
32
33
|
incorporation-<co-house-no>-<date>.pdf # IN01 + statement of capital + cap table
|
|
33
34
|
03-cap-table/
|
|
34
35
|
README.md # pre/post-investment cap table with PSC notes
|
|
36
|
+
comparables.md # recent comparable rounds (company / pre-money / post-money / multiple / source) cited by the term-sheet valuation
|
|
35
37
|
04-financials/
|
|
36
38
|
README.md
|
|
37
39
|
model_worksheet.md # opening cash, capex, burn, MRR ramp, two-round
|
|
@@ -78,7 +80,9 @@ Skip stages that are already complete; do not regenerate stale artefacts blindly
|
|
|
78
80
|
|
|
79
81
|
## Stage 1 — Office-hours ideation
|
|
80
82
|
|
|
81
|
-
Drive a conversational discovery session using the sibling `office-hours` skill.
|
|
83
|
+
Drive a conversational discovery session using the sibling `office-hours` skill. Market sizing and competitor recon during discovery dispatch the `research-assistant` specialist with `deep-research` + `data-research` rather than calling `WebSearch` directly — every market figure that ends up in `08-market/sources.md` must trace to a structured-research citation.
|
|
84
|
+
|
|
85
|
+
Output a single `office-hours-design.md` capturing:
|
|
82
86
|
|
|
83
87
|
- Problem statement
|
|
84
88
|
- Demand evidence (with numbers and dates)
|
|
@@ -113,22 +117,23 @@ References: `references/data-room-structure.md` for the section-by-section purpo
|
|
|
113
117
|
|
|
114
118
|
## Stage 3 — Business plan synthesis
|
|
115
119
|
|
|
116
|
-
Generate `01-narrative/business-plan.md` with **
|
|
120
|
+
Generate `01-narrative/business-plan.md` with **16 sections** following the canonical structure:
|
|
117
121
|
|
|
118
122
|
1. Executive Summary
|
|
119
123
|
2. Vision and Mission (Vision / Mission / Doctrine triad)
|
|
120
124
|
3. The Company (legal entity table + pre-investment cap table)
|
|
121
|
-
4. The Market (TAM/SAM/SOM + structural tailwind + self-employed wedge + domestic adjacency + international upside + pricing)
|
|
125
|
+
4. The Market (TAM/SAM/SOM bottoms-up with geography-tier floor + CAGR with citation + 3-yr market-expansion thesis + market-share trajectory to 3–8% SAM in 5 yrs + structural tailwind + self-employed wedge + domestic adjacency + international upside + pricing)
|
|
122
126
|
5. The Product (what it is + wedge product + upsell path + substrate moat + conversation ingestion + network + Anthropic asymmetric capture + human-services layer)
|
|
123
|
-
6. The Business Model (revenue streams + unit economics)
|
|
127
|
+
6. The Business Model (revenue streams + unit economics — ACV, CAC, LTV, **LTV:CAC**, gross margin, **burn multiple**, churn — each a named line)
|
|
124
128
|
7. Go-to-Market (Wedge → Beachhead → Blitzscale framework + demand evidence + GTM partners + horse-before-cart logic + geography)
|
|
125
129
|
8. Competition (three failing categories + RANL differentiation + most-direct-competitor counter)
|
|
126
130
|
9. Operations (technology stack + data sovereignty + IP ownership chain + compliance posture summary)
|
|
127
131
|
10. Compliance and regulatory positioning (UK consumer protection + UK data/AI regime + EU AI Act + adjacent UK obligations + moat-not-tax close)
|
|
128
132
|
11. Team (founders + strategic shareholders + hiring plan)
|
|
129
|
-
12. Financial Plan (12.1 opening balance sheet through 12.7 use of funds)
|
|
133
|
+
12. Financial Plan (12.1 opening balance sheet through 12.7 use of funds; valuation per round cites `03-cap-table/comparables.md`)
|
|
130
134
|
13. Risks and Mitigations
|
|
131
135
|
14. Milestones (the N-month thesis)
|
|
136
|
+
14b. Exit thesis (target exit value + 5–8-year horizon + exit routes — strategic / PE / IPO — + 3–5 named acquirers with one-line rationale each)
|
|
132
137
|
15. The bottom line (summary table + close)
|
|
133
138
|
+ Appendices (titled documents only; no internal-only file pointers)
|
|
134
139
|
|
|
@@ -140,7 +145,14 @@ Generate `01-narrative/business-plan.md` with **15 sections** following the cano
|
|
|
140
145
|
- **Financial figures derive from the model worksheet.** Cite "Appendix A" by title.
|
|
141
146
|
- **No em-dashes between alphabetic words** in user-facing prose (recurring style violation in this project's history; see `references/internal-workings-scrub.md`).
|
|
142
147
|
|
|
143
|
-
|
|
148
|
+
**Research routing across Stage 3.** Every figure sourced from the wider world routes through the `research-assistant` specialist — never raw `WebSearch` / `WebFetch` from this skill:
|
|
149
|
+
|
|
150
|
+
- **Section 4 (Market)** — TAM/SAM/SOM citations, CAGR sourcing, market-share trajectory baselines, competitor rebuttal facts: dispatch `research-assistant` with `data-research`.
|
|
151
|
+
- **Section 10 (Compliance)** — DMCC Act (UK consumer protection for estate-agency), ICO ADM framework (Articles 22A–22D under UK GDPR + ICO 2025 strategy), EU AI Act (force date, high-risk classification for property-financing decisions): dispatch `research-assistant` with `academic-verify` to retrieve the primary regulatory texts. Cite each in the body.
|
|
152
|
+
- **Section 12 (Financial — valuation comparables)** — recent comparable rounds that feed `03-cap-table/comparables.md`: dispatch `research-assistant` with `data-research`.
|
|
153
|
+
- **Section 14b (Exit thesis)** — 3–5 named acquirers (strategic / PE / IPO) with one-line rationale each, plus recent comparable exits (company / acquirer / multiple / year / source) that feed the exit section of `03-cap-table/comparables.md`: dispatch `research-assistant` with `data-research`.
|
|
154
|
+
|
|
155
|
+
The specialist returns structured findings; the skill quotes those findings verbatim into the relevant section and into `08-market/sources.md` / `03-cap-table/comparables.md`.
|
|
144
156
|
|
|
145
157
|
References: `references/business-plan-template.md` for the section-by-section template; `references/compliance-research-checklist.md` for the UK + EU regulatory regimes to verify.
|
|
146
158
|
|
|
@@ -172,20 +184,21 @@ References: `references/termsheet-template.md`.
|
|
|
172
184
|
|
|
173
185
|
## Stage 4 — Deck blueprint synthesis
|
|
174
186
|
|
|
175
|
-
Generate `01-narrative/deck-blueprint.md` as a **
|
|
187
|
+
Generate `01-narrative/deck-blueprint.md` as a **13-slide brief** the deck designer can execute. Each slide has Purpose, Headline (one-line message), Body (bullets + figures pulled from the business plan), Visual suggestion, and Source reference. The 13 slides:
|
|
176
188
|
|
|
177
189
|
1. Cover (raise headline + founders)
|
|
178
190
|
2. Vision (Vision / Mission / Doctrine)
|
|
179
|
-
3. The Market (TAM + tailwind + wedge)
|
|
191
|
+
3. The Market (TAM + tailwind + wedge + **CAGR with citation**)
|
|
180
192
|
4. Business Model (subscription + service layer + unit economics)
|
|
181
193
|
5. Go-to-Market (Wedge → Beachhead → Blitzscale + named partners)
|
|
182
194
|
6. The Product (substrate + wedge + network + asymmetric capture + services layer)
|
|
183
195
|
7. Competition (three failing categories + most-direct counter)
|
|
184
196
|
8. The Team (founders + strategic shareholders)
|
|
185
|
-
9. Economics (P&L summary + cash flow + break-even)
|
|
197
|
+
9. Economics (P&L summary + cash flow + break-even + **LTV:CAC and burn multiple**)
|
|
186
198
|
10. The Raise (size, valuation, dilution, instrument, use of funds, IP transfer, follow-on round)
|
|
187
|
-
11.
|
|
188
|
-
12.
|
|
199
|
+
11. Exit (target exit value + 5–8-year horizon + routes — strategic / PE / IPO — + 3–5 named acquirers with one-line rationale)
|
|
200
|
+
12. Milestones (M0 to M-final timeline)
|
|
201
|
+
13. Other Information (compliance + platform dependency + contact)
|
|
189
202
|
|
|
190
203
|
Production notes attached: format (16:9 landscape, PDF + source deck), design tokens reference (the operator's project design-tokens spec, path supplied at Stage 5 invocation), chart-source consistency with the financial model, speaker-note attribution.
|
|
191
204
|
|