@rubytech/create-realagent-code 0.1.122 → 0.1.123
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/dist/index.js +20 -3
- package/package.json +1 -1
- package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +4 -1
- package/payload/platform/plugins/aeo/PLUGIN.md +1 -2
- package/payload/platform/plugins/aeo/mcp/dist/index.js +23 -8
- package/payload/platform/plugins/aeo/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/aeo/mcp/dist/tools/aeo-write-llms-txt.d.ts +5 -0
- package/payload/platform/plugins/aeo/mcp/dist/tools/aeo-write-llms-txt.d.ts.map +1 -1
- package/payload/platform/plugins/aeo/mcp/dist/tools/aeo-write-llms-txt.js +24 -0
- package/payload/platform/plugins/aeo/mcp/dist/tools/aeo-write-llms-txt.js.map +1 -1
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/SKILL.md +6 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/references/index.html +5 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/references/placeholders.md +32 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/references/template.html +6 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-socials/SKILL.md +6 -0
package/dist/index.js
CHANGED
|
@@ -2554,8 +2554,20 @@ function installServiceDarwin() {
|
|
|
2554
2554
|
const persistDir = resolve(process.env.HOME ?? "/", BRAND.configDir);
|
|
2555
2555
|
const logsDir = join(persistDir, "logs");
|
|
2556
2556
|
mkdirSync(logsDir, { recursive: true });
|
|
2557
|
-
//
|
|
2558
|
-
//
|
|
2557
|
+
// Mirror the Linux brand systemd unit's `Environment=` lines into .env.
|
|
2558
|
+
// Linux stamps every var explicitly on the unit; darwin has no systemd
|
|
2559
|
+
// EnvironmentFile primitive, so the wrapper sources .env before exec'ing
|
|
2560
|
+
// node. Any var the boot path requires (PORT, MAXY_UI_INTERNAL_PORT,
|
|
2561
|
+
// ACCOUNT_ID, MAXY_PLATFORM_ROOT, NEO4J_URI, CLAUDE_CONFIG_DIR, NODE_ENV)
|
|
2562
|
+
// must be written here or the server hard-fails before binding the listener.
|
|
2563
|
+
// VNC/X11 vars (DISPLAY, RFB_PORT, WEBSOCKIFY_PORT, CDP_PORT) are Pi-only
|
|
2564
|
+
// and excluded — darwin runs no kiosk display stack.
|
|
2565
|
+
const installAccountId = resolveInstallAccountId();
|
|
2566
|
+
if (!installAccountId) {
|
|
2567
|
+
throw new Error(`installServiceDarwin: no account discovered at ${INSTALL_DIR}/data/accounts/<uuid>/account.json — ` +
|
|
2568
|
+
`setupAccount() (seed-neo4j.sh) should have created one. Refusing to write .env ` +
|
|
2569
|
+
`without ACCOUNT_ID; the boot validator would FATAL on every kickstart.`);
|
|
2570
|
+
}
|
|
2559
2571
|
const envPath = join(persistDir, ".env");
|
|
2560
2572
|
try {
|
|
2561
2573
|
let envContent = "";
|
|
@@ -2564,13 +2576,18 @@ function installServiceDarwin() {
|
|
|
2564
2576
|
}
|
|
2565
2577
|
catch { /* first install */ }
|
|
2566
2578
|
for (const [key, value] of [
|
|
2579
|
+
["NODE_ENV", "production"],
|
|
2567
2580
|
["DISPLAY_MODE", DISPLAY_MODE],
|
|
2568
2581
|
["EMBED_MODEL", EMBED_MODEL],
|
|
2569
2582
|
["EMBED_DIMENSIONS", String(EMBED_DIMS)],
|
|
2570
2583
|
["NEO4J_URI", `bolt://localhost:${NEO4J_PORT}`],
|
|
2571
2584
|
["PORT", String(PORT)],
|
|
2572
2585
|
["MAXY_UI_INTERNAL_PORT", String(PORT + 1)],
|
|
2586
|
+
["ACCOUNT_ID", installAccountId],
|
|
2573
2587
|
["MAXY_PLATFORM_ROOT", `${INSTALL_DIR}/platform`],
|
|
2588
|
+
["CLAUDE_CONFIG_DIR", `${persistDir}/.claude`],
|
|
2589
|
+
["HOSTNAME", "127.0.0.1"],
|
|
2590
|
+
["KEEP_ALIVE_TIMEOUT", "61000"],
|
|
2574
2591
|
]) {
|
|
2575
2592
|
const re = new RegExp(`^${key}=.*$`, "m");
|
|
2576
2593
|
if (re.test(envContent)) {
|
|
@@ -2581,7 +2598,7 @@ function installServiceDarwin() {
|
|
|
2581
2598
|
}
|
|
2582
2599
|
}
|
|
2583
2600
|
writeFileSync(envPath, envContent);
|
|
2584
|
-
logFile(` .env: DISPLAY_MODE=${DISPLAY_MODE}, EMBED_MODEL=${EMBED_MODEL}, EMBED_DIMENSIONS=${EMBED_DIMS}, NEO4J_URI=bolt://localhost:${NEO4J_PORT}, PORT=${PORT}, MAXY_UI_INTERNAL_PORT=${PORT + 1}`);
|
|
2601
|
+
logFile(` .env: DISPLAY_MODE=${DISPLAY_MODE}, EMBED_MODEL=${EMBED_MODEL}, EMBED_DIMENSIONS=${EMBED_DIMS}, NEO4J_URI=bolt://localhost:${NEO4J_PORT}, PORT=${PORT}, MAXY_UI_INTERNAL_PORT=${PORT + 1}, ACCOUNT_ID=${installAccountId.slice(0, 8)}…, CLAUDE_CONFIG_DIR=${persistDir}/.claude`);
|
|
2585
2602
|
}
|
|
2586
2603
|
catch (err) {
|
|
2587
2604
|
console.error(` WARNING: failed to write .env to ${envPath}: ${err instanceof Error ? err.message : String(err)}`);
|
package/package.json
CHANGED
|
@@ -54,7 +54,8 @@ The operator message for `ambiguous-html` names the candidate files and asks the
|
|
|
54
54
|
4. **Choose the canonical path.** `index.html` present at top level → path is `/sites/<slug>/`. Otherwise the single top-level HTML file → path is `/sites/<slug>/<file>.html`.
|
|
55
55
|
5. **Emit.** One log line:
|
|
56
56
|
`[publish-site] url emitted=<path-slug> kind=<index|file>`
|
|
57
|
-
6. **
|
|
57
|
+
6. **Refresh `llms.txt` at the site root.** Call `mcp__aeo__aeo-write-llms-txt` with `{ siteName: "<slug>", siteDir: "<accountDir>/sites/<slug>" }`. The AEO tool reads the account's `KnowledgeDocument` set and writes `llms.txt` + `llms-full.txt` into `<siteDir>/`, so answer-engine crawlers always see the current page set at the moment of publish. `accountId` is implicit — the AEO plugin reads it from its own env. On success, emit `[publish-site] aeo-llms-txt-ok wrote=<indexPath> indexBytes=<n>`. **Best-effort invariant:** if the call fails (tool returns `isError`, throws, or the `aeo` plugin is not loaded for this account), emit `[publish-site] aeo-llms-txt-failed reason=<msg>` and continue. **Never unwind the `mv` on AEO failure** — the publish already succeeded, the URL is live, and a stale or missing `llms.txt` is strictly less bad than a failed publish.
|
|
58
|
+
7. **Resolve the public hostname and emit the full URL.** Call `mcp__admin__public-hostname` to fetch this account's hostname; the tool reads `cloudflared/config.yml` + `alias-domains.json` — the same files the platform server trusts to route. Concatenate `https://<hostname><path-slug>` and surface that one URL to the operator. If the tool returns `reason: no-tunnel`, relay the tool's remediation message verbatim — do not improvise the URL. The route at `/sites/*` (see [server/routes/sites.ts](../../../../ui/server/routes/sites.ts)) handles the trailing-slash redirect on the dir form, so the slug is correct as-emitted whether the operator's HTML uses an `index.html` entry-point or a publisher-named landing file.
|
|
58
59
|
|
|
59
60
|
## Log lines (grep targets)
|
|
60
61
|
|
|
@@ -62,6 +63,8 @@ The operator message for `ambiguous-html` names the candidate files and asks the
|
|
|
62
63
|
|---|---|
|
|
63
64
|
| After move | `[publish-site] move from=<src> to=<dest> files=<n>` |
|
|
64
65
|
| Path emission | `[publish-site] url emitted=<path-slug> kind=<index\|file>` |
|
|
66
|
+
| AEO llms.txt success | `[publish-site] aeo-llms-txt-ok wrote=<indexPath> indexBytes=<n>` |
|
|
67
|
+
| AEO llms.txt failure (best-effort, publish continues) | `[publish-site] aeo-llms-txt-failed reason=<msg>` |
|
|
65
68
|
| Refusal (any reason) | `[publish-site] refused reason=<unsafe-slug\|destination-occupied\|symlink-in-source\|zero-html\|ambiguous-html> <key=value pairs>` |
|
|
66
69
|
|
|
67
70
|
## Out of scope
|
|
@@ -39,7 +39,7 @@ This plugin makes the platform's content legible to answer engines — Claude, C
|
|
|
39
39
|
|
|
40
40
|
1. **JSON-LD** (`aeo-emit-jsonld`). Every typed graph entity that backs a page can be projected to a `<script type="application/ld+json">` block. The mapper covers `Organization`, `LocalBusiness`, `Person`, `Service`, `Product`, `Article`, `FAQPage`, `RealEstateListing`, `Event`. Other labels fall through to `schema:Thing` and are flagged as a doc gap.
|
|
41
41
|
|
|
42
|
-
2. **llms.txt** (`aeo-write-llms-txt`). The site emits `/llms.txt` (index of pages, one link per line) and `/llms-full.txt` (concatenated full text). Format follows the current draft at `https://llmstxt.org/`. Source is `KnowledgeDocument` nodes with a `url` property. Pages without a `url` are skipped and counted in the response.
|
|
42
|
+
2. **llms.txt** (`aeo-write-llms-txt`). The site emits `/llms.txt` (index of pages, one link per line) and `/llms-full.txt` (concatenated full text). Format follows the current draft at `https://llmstxt.org/`. Source is `KnowledgeDocument` nodes with a `url` property. Pages without a `url` are skipped and counted in the response. Called with `siteDir` (an absolute path to an existing site root), the tool writes both files to disk and the response carries `writtenPaths`; called without it, the tool returns the file bodies inline for on-demand callers. The publish-site skill calls this with `siteDir` set to the freshly-published `<accountDir>/sites/<slug>/` on every publish, so the pair stays fresh as `KnowledgeDocument` nodes change.
|
|
43
43
|
|
|
44
44
|
3. **Audit** (`aeo-audit-page`). Run the eight-heuristic scorecard against a URL or raw HTML. Each heuristic returns pass / warn / fail with one rewrite suggestion per fail. Score is `100 * (passes + 0.5 * warns) / 8`. Pass `persist: true` with a `targetKnowledgeDocumentId` to record an `:AEOAudit` node linked back to the document.
|
|
45
45
|
|
|
@@ -70,7 +70,6 @@ The audit nodes carry `accountId`, `target` (URL or `(inline html)`), `score`, `
|
|
|
70
70
|
|
|
71
71
|
- No LLM API calls. No citation monitor — out of scope. Multi-engine answer harvesting doesn't fit maxy-code's no-API-key architecture, and the monitor was archived without sprinting (Task 363). The audit plus the structured-answer template are the surface; check citation manually when needed.
|
|
72
72
|
- No automatic emission. `aeo-emit-jsonld` returns a script block; wiring it into the platform's page render path is per-renderer work, also filed as a follow-up.
|
|
73
|
-
- No publish-hook regeneration of `llms.txt`. The tool runs on demand. Hooking it into the publish event is a follow-up.
|
|
74
73
|
- No prose authoring. AEO audits structure; it does not rewrite content. Writer-craft owns voice.
|
|
75
74
|
|
|
76
75
|
## See also
|
|
@@ -74,28 +74,43 @@ eagerTool(server, "aeo-emit-jsonld", "Emit a schema.org JSON-LD block for a type
|
|
|
74
74
|
// ---------------------------------------------------------------------------
|
|
75
75
|
// aeo-write-llms-txt
|
|
76
76
|
// ---------------------------------------------------------------------------
|
|
77
|
-
eagerTool(server, "aeo-write-llms-txt", "Generate /llms.txt and /llms-full.txt for the account's published KnowledgeDocument pages. Index lists every page with title, url, summary. Full file concatenates each page's body, demoting any in-body H1s to H2 to keep one heading hierarchy.", {
|
|
77
|
+
eagerTool(server, "aeo-write-llms-txt", "Generate /llms.txt and /llms-full.txt for the account's published KnowledgeDocument pages. Index lists every page with title, url, summary. Full file concatenates each page's body, demoting any in-body H1s to H2 to keep one heading hierarchy. Pass siteDir (absolute path to an existing site root) to also write the two files to disk; in that mode the response carries writtenPaths and omits the inline file bodies. Used by the publish-site skill to refresh both files on every publish.", {
|
|
78
78
|
siteName: z.string().describe("Display name of the site (top H1 of llms.txt)"),
|
|
79
79
|
siteDescription: z
|
|
80
80
|
.string()
|
|
81
81
|
.optional()
|
|
82
82
|
.describe("One-line site description (emitted as a blockquote)"),
|
|
83
|
+
siteDir: z
|
|
84
|
+
.string()
|
|
85
|
+
.optional()
|
|
86
|
+
.describe("Absolute path to an existing site-root directory. When set, writes llms.txt and llms-full.txt into that directory. Tool fails (no silent mkdir) if the directory is missing or not a directory."),
|
|
83
87
|
}, async (args) => {
|
|
84
88
|
if (!accountId)
|
|
85
89
|
return refuseNoAccount("aeo-write-llms-txt");
|
|
86
90
|
try {
|
|
87
91
|
const result = await writeLlmsTxt({ accountId, ...args });
|
|
92
|
+
// When the caller asked us to write to disk, the inline file bodies
|
|
93
|
+
// are redundant (and can run to tens of KB). Omit them from the
|
|
94
|
+
// response so the MCP transport stays small for the publish hook.
|
|
95
|
+
const payload = result.writtenPaths
|
|
96
|
+
? {
|
|
97
|
+
pageCount: result.pageCount,
|
|
98
|
+
skippedNoUrl: result.skippedNoUrl,
|
|
99
|
+
sizeBytes: result.sizeBytes,
|
|
100
|
+
writtenPaths: result.writtenPaths,
|
|
101
|
+
}
|
|
102
|
+
: {
|
|
103
|
+
pageCount: result.pageCount,
|
|
104
|
+
skippedNoUrl: result.skippedNoUrl,
|
|
105
|
+
sizeBytes: result.sizeBytes,
|
|
106
|
+
llmsTxt: result.llmsTxt,
|
|
107
|
+
llmsFullTxt: result.llmsFullTxt,
|
|
108
|
+
};
|
|
88
109
|
return {
|
|
89
110
|
content: [
|
|
90
111
|
{
|
|
91
112
|
type: "text",
|
|
92
|
-
text: JSON.stringify(
|
|
93
|
-
pageCount: result.pageCount,
|
|
94
|
-
skippedNoUrl: result.skippedNoUrl,
|
|
95
|
-
sizeBytes: result.sizeBytes,
|
|
96
|
-
llmsTxt: result.llmsTxt,
|
|
97
|
-
llmsFullTxt: result.llmsFullTxt,
|
|
98
|
-
}, null, 2),
|
|
113
|
+
text: JSON.stringify(payload, null, 2),
|
|
99
114
|
},
|
|
100
115
|
],
|
|
101
116
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,7 @@ export interface WriteLlmsTxtInput {
|
|
|
22
22
|
accountId: string;
|
|
23
23
|
siteName: string;
|
|
24
24
|
siteDescription?: string;
|
|
25
|
+
siteDir?: string;
|
|
25
26
|
}
|
|
26
27
|
export interface WriteLlmsTxtResult {
|
|
27
28
|
llmsTxt: string;
|
|
@@ -32,6 +33,10 @@ export interface WriteLlmsTxtResult {
|
|
|
32
33
|
index: number;
|
|
33
34
|
full: number;
|
|
34
35
|
};
|
|
36
|
+
writtenPaths?: {
|
|
37
|
+
index: string;
|
|
38
|
+
full: string;
|
|
39
|
+
};
|
|
35
40
|
}
|
|
36
41
|
export declare function writeLlmsTxt(input: WriteLlmsTxtInput): Promise<WriteLlmsTxtResult>;
|
|
37
42
|
//# sourceMappingURL=aeo-write-llms-txt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aeo-write-llms-txt.d.ts","sourceRoot":"","sources":["../../src/tools/aeo-write-llms-txt.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"aeo-write-llms-txt.d.ts","sourceRoot":"","sources":["../../src/tools/aeo-write-llms-txt.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IAMzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAqBD,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAsH7B"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { stat, writeFile } from "node:fs/promises";
|
|
2
|
+
import { resolve as resolvePath } from "node:path";
|
|
1
3
|
import { getSession } from "../lib/neo4j.js";
|
|
2
4
|
const HEADER_RX = /^#\s/m;
|
|
3
5
|
function escapeMarkdown(text) {
|
|
@@ -83,12 +85,34 @@ export async function writeLlmsTxt(input) {
|
|
|
83
85
|
full: Buffer.byteLength(llmsFullTxt, "utf-8"),
|
|
84
86
|
};
|
|
85
87
|
process.stderr.write(`[aeo-llms-txt] site=${input.siteName} pages=${rows.length} skippedNoUrl=${skippedNoUrl} indexBytes=${sizeBytes.index} fullBytes=${sizeBytes.full}\n`);
|
|
88
|
+
let writtenPaths;
|
|
89
|
+
if (input.siteDir) {
|
|
90
|
+
const dir = resolvePath(input.siteDir);
|
|
91
|
+
let dirStat;
|
|
92
|
+
try {
|
|
93
|
+
dirStat = await stat(dir);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
const code = err?.code;
|
|
97
|
+
throw new Error(`siteDir does not exist (${code ?? "unknown"}): ${dir}`);
|
|
98
|
+
}
|
|
99
|
+
if (!dirStat.isDirectory()) {
|
|
100
|
+
throw new Error(`siteDir is not a directory: ${dir}`);
|
|
101
|
+
}
|
|
102
|
+
const indexPath = resolvePath(dir, "llms.txt");
|
|
103
|
+
const fullPath = resolvePath(dir, "llms-full.txt");
|
|
104
|
+
await writeFile(indexPath, llmsTxt, "utf-8");
|
|
105
|
+
await writeFile(fullPath, llmsFullTxt, "utf-8");
|
|
106
|
+
writtenPaths = { index: indexPath, full: fullPath };
|
|
107
|
+
process.stderr.write(`[aeo-llms-txt] wrote site=${dir} indexBytes=${sizeBytes.index} fullBytes=${sizeBytes.full}\n`);
|
|
108
|
+
}
|
|
86
109
|
return {
|
|
87
110
|
llmsTxt,
|
|
88
111
|
llmsFullTxt,
|
|
89
112
|
pageCount: rows.length,
|
|
90
113
|
skippedNoUrl,
|
|
91
114
|
sizeBytes,
|
|
115
|
+
writtenPaths,
|
|
92
116
|
};
|
|
93
117
|
}
|
|
94
118
|
//# sourceMappingURL=aeo-write-llms-txt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aeo-write-llms-txt.js","sourceRoot":"","sources":["../../src/tools/aeo-write-llms-txt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"aeo-write-llms-txt.js","sourceRoot":"","sources":["../../src/tools/aeo-write-llms-txt.ts"],"names":[],"mappings":"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"}
|
package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/SKILL.md
CHANGED
|
@@ -107,6 +107,12 @@ Read the seller brief once before writing any copy. Then walk the `{{ placeholde
|
|
|
107
107
|
| Live editing, snapshot capture, PDF deliverable, web bundle | [references/build.md](references/build.md) |
|
|
108
108
|
| `index.html` landing page — sections, hero rotator, mobile/drawer | [references/index-landing.md](references/index-landing.md) |
|
|
109
109
|
|
|
110
|
+
### Structured-data (JSON-LD) step
|
|
111
|
+
|
|
112
|
+
One token is special: `{{ jsonld_script_block }}` is filled by calling the `aeo-emit-jsonld` MCP tool, not by hand. The tool reads `property.json` fields and returns a verbatim `<script type="application/ld+json">` block to paste into the token. Without this block the page silently fails answer-engine indexing (`aeo-audit-page → jsonld-present: fail`).
|
|
113
|
+
|
|
114
|
+
Call once per render, with `label: "RealEstateListing"` and the property bag from `property.json`. Full token contract and call shape: [references/placeholders.md → Category 10](references/placeholders.md). The tool returns `{ scriptBlock }`; substitute `scriptBlock` into `{{ jsonld_script_block }}` in both `brochure.html` and `web/index.html`. If the tool throws `MissingPropertyError`, the source `property.json` is incomplete — fix the data, not the brochure.
|
|
115
|
+
|
|
110
116
|
### Substitution completion gate
|
|
111
117
|
|
|
112
118
|
A brochure with any `{{ x }}` still in the rendered HTML is **shipped broken**. Before any snapshot capture or PDF build, run:
|
|
@@ -64,6 +64,11 @@
|
|
|
64
64
|
Same content as {{ backpage_tagline }} in the brochure; the two should mirror
|
|
65
65
|
each other. Used by social previews and search. -->
|
|
66
66
|
<meta name="description" content="{{ meta_description }}">
|
|
67
|
+
<!-- REPLACE {{ jsonld_script_block }}: structured-data block produced by the
|
|
68
|
+
aeo-emit-jsonld MCP tool. See references/placeholders.md → Category 10.
|
|
69
|
+
Required for answer-engine indexing — this is the page's
|
|
70
|
+
schema.org RealEstateListing projection. -->
|
|
71
|
+
{{ jsonld_script_block }}
|
|
67
72
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
68
73
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
69
74
|
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;1,400&family=Lora:ital,wght@0,400;0,500;1,400&family=Inter:wght@400;500&display=swap" rel="stylesheet">
|
|
@@ -229,6 +229,38 @@ The landing page mirrors the brochure's content but in a continuous-scroll form.
|
|
|
229
229
|
| `{{ page_title }}` | "<Property name> · <street>, <locality> · For Sale" | Browser tab. |
|
|
230
230
|
| `{{ meta_description }}` | Same single-sentence pitch as `{{ backpage_tagline }}`. |
|
|
231
231
|
|
|
232
|
+
## Category 10 — Structured data (JSON-LD)
|
|
233
|
+
|
|
234
|
+
One token appears in `<head>` on both `brochure.html` and `web/index.html`. It carries the schema.org projection of the property so answer engines (Claude, ChatGPT, Perplexity, Gemini) can read the listing without parsing prose. The substitution step calls the `aeo-emit-jsonld` MCP tool and pastes the returned `scriptBlock` into the token; no manual JSON is written.
|
|
235
|
+
|
|
236
|
+
| Token | Source | Format / length | Notes |
|
|
237
|
+
|---|---|---|---|
|
|
238
|
+
| `{{ jsonld_script_block }}` | `aeo-emit-jsonld` MCP tool, inline mode | The tool returns `{ scriptBlock: "<script type=\"application/ld+json\">…</script>" }` — paste verbatim. | Required on every brochure. Empty string is a defect — answer engines will fail `jsonld-present`. |
|
|
239
|
+
|
|
240
|
+
**How to call the tool** — once per brochure, after `property.json` is loaded:
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
aeo-emit-jsonld({
|
|
244
|
+
accountId: <current account id>,
|
|
245
|
+
label: "RealEstateListing",
|
|
246
|
+
properties: {
|
|
247
|
+
name: property.property_name || property.address.line_1,
|
|
248
|
+
description: property.meta_description || property.backpage_tagline,
|
|
249
|
+
price: property.price.amount, // number, not formatted string
|
|
250
|
+
priceCurrency: property.price.currency, // "GBP"
|
|
251
|
+
streetAddress: property.address.line_1,
|
|
252
|
+
addressLocality: property.address.locality,
|
|
253
|
+
postalCode: property.address.postcode,
|
|
254
|
+
url: property.listing_url, // canonical public URL
|
|
255
|
+
image: property.hero_image_url, // absolute URL to hero
|
|
256
|
+
},
|
|
257
|
+
})
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The tool returns `{ scriptBlock }`. Substitute the string verbatim into `{{ jsonld_script_block }}`. If the call throws `MissingPropertyError`, the property record is incomplete — fix the source data, not the brochure.
|
|
261
|
+
|
|
262
|
+
**Why inline mode (label + properties), not entityId** — brochures are produced from `property.json` on disk, not from a Neo4j entity. The tool accepts both surfaces; inline is the right one for this pipeline. If a brochure is ever produced from a graph entity directly, switch to `entityId` and skip the property bag.
|
|
263
|
+
|
|
232
264
|
## Completion check
|
|
233
265
|
|
|
234
266
|
The substitution step that runs `property-brochure` should end with this verification gate:
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Property Folio — Template</title>
|
|
7
|
+
<!-- {{ jsonld_script_block }}: structured-data block produced by the
|
|
8
|
+
aeo-emit-jsonld MCP tool. See references/placeholders.md → Category 10.
|
|
9
|
+
Even though brochure.html is print-only, the JSON-LD ships in <head>
|
|
10
|
+
so any HTML served from the bundle root carries the same schema.org
|
|
11
|
+
RealEstateListing projection as web/index.html. -->
|
|
12
|
+
{{ jsonld_script_block }}
|
|
7
13
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
14
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
15
|
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400;1,500;1,600&family=Lora:ital,wght@0,400;0,500;0,600;1,400;1,500&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
|
package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-socials/SKILL.md
CHANGED
|
@@ -141,3 +141,9 @@ Critical layout rules:
|
|
|
141
141
|
- Wiring `<meta property="og:image">` into `page.html`. Surface the snippet for
|
|
142
142
|
the operator; the page is regenerated by a separate skill and edits there
|
|
143
143
|
belong in that pipeline, not this one.
|
|
144
|
+
- **JSON-LD / schema.org structured data on `page.html`.** Emitted upstream by
|
|
145
|
+
`property-brochure` via the `aeo-emit-jsonld` MCP tool — the
|
|
146
|
+
`{{ jsonld_script_block }}` token lives in the brochure's `references/index.html`
|
|
147
|
+
and is filled at brochure-render time. `property-socials` does not produce any
|
|
148
|
+
indexable HTML page (`socials.html` is operator-only collateral; `og.html` is a
|
|
149
|
+
screenshot template), so there is nothing to inline here.
|