@rubytech/create-realagent 1.0.847 → 1.0.850
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/__tests__/port-canonicalisation.test.js +1 -0
- package/dist/__tests__/snap-chromium.test.js +115 -0
- package/dist/index.js +201 -1
- package/dist/port-resolution.js +1 -1
- package/dist/snap-chromium.js +89 -0
- package/package.json +1 -1
- package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +1 -1
- package/payload/platform/plugins/admin/skills/public-agent-manager/SKILL.md +2 -2
- package/payload/platform/plugins/cloudflare/PLUGIN.md +1 -1
- package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +25 -7
- package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +1 -1
- package/payload/platform/plugins/docs/references/adherence.md +1 -1
- package/payload/platform/plugins/docs/references/deployment.md +8 -0
- package/payload/platform/plugins/docs/references/plugins-guide.md +4 -2
- package/payload/platform/plugins/docs/references/troubleshooting.md +33 -0
- package/payload/platform/plugins/linkedin-import/PLUGIN.md +2 -2
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/references/connections.md +2 -2
- package/payload/platform/plugins/memory/PLUGIN.md +1 -1
- package/payload/platform/plugins/memory/references/schema-base.md +1 -1
- package/payload/platform/scripts/test-laptop-vnc-boot.sh +81 -0
- package/payload/platform/scripts/vnc.sh +42 -2
- package/payload/platform/templates/agents/admin/AGENTS.md +6 -4
- package/payload/platform/templates/agents/admin/IDENTITY.md +6 -2
- package/payload/platform/templates/specialists/agents/content-producer.md +2 -2
- package/payload/premium-plugins/real-agency/BUNDLE.md +3 -3
- package/payload/premium-plugins/real-agency/agents/valuer.md +10 -0
- package/payload/premium-plugins/real-agency/plugins/buyers/skills/buyer-management/SKILL.md +42 -0
- package/payload/premium-plugins/real-agency/plugins/buyers/skills/buyer-management/references/buyer-qualification-questions.md +16 -0
- package/payload/premium-plugins/real-agency/plugins/buyers/skills/buyer-management/references/buyer-qualification.md +59 -0
- package/payload/premium-plugins/real-agency/plugins/buyers/skills/buyer-management/references/buyer-scripts.md +63 -0
- package/payload/premium-plugins/real-agency/plugins/buyers/skills/buyer-management/references/buyer-working-scripts.md +54 -0
- package/payload/premium-plugins/real-agency/plugins/buyers/skills/buyer-management/references/feedback-collection.md +42 -0
- package/payload/premium-plugins/real-agency/plugins/buyers/skills/buyer-management/references/offer-capture.md +38 -0
- package/payload/premium-plugins/real-agency/plugins/buyers/skills/buyer-management/references/viewing-booking.md +32 -0
- package/payload/premium-plugins/real-agency/plugins/buyers/skills/buyer-management/references/viewing-management.md +52 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/negotiation/SKILL.md +35 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/negotiation/references/deal-saving.md +47 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/negotiation/references/negotiation-deep-guide.md +64 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/negotiation/references/negotiation-prep-principles.md +29 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/negotiation/references/negotiation-techniques.md +42 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/negotiation/references/offer-presentation.md +43 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/sales-negotiation/SKILL.md +29 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/sales-negotiation/references/chris-voss-negotiation.md +70 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/sales-negotiation/references/phil-jones-price-words.md +40 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/sales-negotiation/references/serhant-negotiation-plus.md +55 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/sales-negotiation/references/tom-panos-commission-pricing.md +57 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/sales-negotiation/references/tony-morris-questioning.md +54 -0
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.d.ts +6 -4
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +1 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.js +82 -10
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.js.map +1 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/src/lib/loop-api.ts +111 -15
- package/payload/server/chunk-DIRNBH7F.js +1603 -0
- package/payload/server/chunk-GOO2J3X7.js +10561 -0
- package/payload/server/chunk-LCAFHNZR.js +10420 -0
- package/payload/server/chunk-X3LVMXI5.js +10578 -0
- package/payload/server/client-pool-7Z6YRUQT.js +34 -0
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/public/assets/{admin-DFUet1XM.js → admin-Dyl8uNxX.js} +1 -1
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-Bs5MjIKf.js → architectureDiagram-Q4EWVU46-BePoi8XC.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-BVSXiX4T.js → blockDiagram-DXYQGD6D-BkiwLTtq.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DBqsWCjl.js → c4Diagram-AHTNJAMY-bpjPj2Ln.js} +1 -1
- package/payload/server/public/assets/channel-D3U0_a1j.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-COUTB2TN.js → chunk-336JU56O-BpATJiGl.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-zKsTsXw6.js → chunk-426QAEUC-Wz6Bpsil.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-CI9i2J5g.js → chunk-4TB4RGXK-CLXL19Wd.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-DfchzZ2Y.js → chunk-5FUZZQ4R-BoTfWHuW.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-_iMyxz0C.js → chunk-5PVQY5BW-RhIfPCRB.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-Ddtw_ZHk.js → chunk-EDXVE4YY-utELKGQK.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-BrGMkslM.js → chunk-ENJZ2VHE-CNHjq5xK.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DHInTpuR.js → chunk-ICPOFSXX-Di63NBur.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-mOQ4KZ9j.js → chunk-OYMX7WX6-BSPzqyxs.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-D5vGkUe9.js → chunk-U2HBQHQK-BZnA7c4T.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-CnNxZbqc.js → chunk-X2U36JSP-DpQ2OA_c.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-Cb7OSc_r.js → chunk-YZCP3GAM-BAkNXu0G.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-BipxpzL8.js → chunk-ZZ45TVLE-DBSm41oP.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-6EGGLDD_.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DfAV4tgE.js +1 -0
- package/payload/server/public/assets/clone-BoV8noAi.js +1 -0
- package/payload/server/public/assets/{dagre-KV5264BT-B91sXKT2.js → dagre-KV5264BT-BkvWofSp.js} +1 -1
- package/payload/server/public/assets/{dagre-lObrgXUJ.js → dagre-nvPNAunb.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-DB2Kcx9r.js → diagram-5BDNPKRD-CMEgyt4E.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-Cq1J05SW.js → diagram-G4DWMVQ6-ChorrAF0.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-CwqXxUXd.js → diagram-MMDJMWI5-D_iD27po.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-Nmk38u6a.js → diagram-TYMM5635-8qXI1ioG.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-D2EfAdSD.js → erDiagram-SMLLAGMA-BFjtKDSB.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CS98o6Jz.js → flowDiagram-DWJPFMVM-Bpd7IL9l.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-rWm6xQ8t.js → ganttDiagram-T4ZO3ILL-CwOozU85.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-BuwECvwx.js → gitGraphDiagram-UUTBAWPF-CcPILiC9.js} +1 -1
- package/payload/server/public/assets/{graphlib-BXEED8qM.js → graphlib-B_mcXEVr.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-CEmJMuVh.js → infoDiagram-42DDH7IO-T2sn--WJ.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-CAQMMx-Y.js → ishikawaDiagram-UXIWVN3A-DOP9-Q8H.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-toHrBGCq.js → journeyDiagram-VCZTEJTY-DGATg0WC.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DwXLkenV.js → kanban-definition-6JOO6SKY-C5PigmKg.js} +1 -1
- package/payload/server/public/assets/{line-BkM2KuUb.js → line-DlKKhwkO.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-CsaDWYZC.js → mermaid-parser.core-C8xGCa9p.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-CvICILSR.js → mermaid.core-CCUSwZB_.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DQyCWpKS.js → mindmap-definition-QFDTVHPH-75k-IVhC.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-CVRIcK6b.js → pieDiagram-DEJITSTG-DN5RsDwZ.js} +1 -1
- package/payload/server/public/assets/preload-helper-qlgyTAkD.js +1 -0
- package/payload/server/public/assets/{public-CR_CX3K5.js → public-B_PNZUph.js} +1 -1
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CnfXm2xw.js → quadrantDiagram-34T5L4WZ-Sd9x6pNe.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-BntW6fnu.js → requirementDiagram-MS252O5E-BDgifYzj.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Bt6AfgXn.js → sankeyDiagram-XADWPNL6-BX9VULNJ.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-D6s0kP6H.js → sequenceDiagram-FGHM5R23-z3vMxhgE.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-B9y9cOff.js → stateDiagram-FHFEXIEX-DlP0hBxF.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DSddQStC.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DIFjQGfl.js → timeline-definition-GMOUNBTQ-DwQbhKCo.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-DWRtIHOw.js → useVoiceRecorder-fD0IWzJj.js} +3 -3
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-YRVHIBU9.js → vennDiagram-DHZGUBPP-WTqmZWWa.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-B20PPeAr.js → wardleyDiagram-NUSXRM2D-BUY50x5T.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BztKw58Q.js → xychartDiagram-5P7HB3ND-Btdq-fDj.js} +1 -1
- package/payload/server/public/index.html +3 -3
- package/payload/server/public/public.html +3 -3
- package/payload/server/server.js +6 -3
- package/payload/server/public/assets/channel-lEc18pSi.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-rkW6IED-.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CRQJXpMG.js +0 -1
- package/payload/server/public/assets/clone-icRAjexu.js +0 -1
- package/payload/server/public/assets/preload-helper-bPV_ZjF3.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DH4gbGCS.js +0 -1
|
@@ -57,12 +57,12 @@ Premium plugins are one-off purchases that grant permanent ownership. They are n
|
|
|
57
57
|
| Plugin | Type | What it does | Public agent |
|
|
58
58
|
|--------|------|-------------|-------------|
|
|
59
59
|
| `teaching` | Skills | Interactive tutoring, lesson planning, and study pack generation from your knowledge base | Yes — all 3 skills serve students and parents |
|
|
60
|
-
| `real-agency` | Bundle (10 sub-plugins) | UK estate agency skills — sales, listings, vendor management, buyer management, lead generation, coaching, business operations, onboarding, teaching, and Loop CRM.
|
|
60
|
+
| `real-agency` | Bundle (10 sub-plugins) | UK estate agency skills — sales, listings, vendor management, buyer management, lead generation, coaching, business operations, onboarding, teaching, and Loop CRM. 3 specialist roles (negotiator, valuer, compliance) | 5 sub-plugins (estate-sales, buyers, estate-coaching, estate-teaching, estate-onboarding) |
|
|
61
61
|
| `writer-craft` | Skills + Agent | Manuscript review and writing craft — story architecture, reader engagement, prose craft, editorial practice, and multi-level review | No — writing craft serves the author |
|
|
62
62
|
|
|
63
63
|
**How it works:** When you purchase a premium plugin, it's delivered to your {{productName}} via conversation. Tell {{productName}} "Enable the teaching plugin" and it handles the rest. Premium plugins are yours permanently — they survive updates and reinstalls.
|
|
64
64
|
|
|
65
|
-
Some premium plugins are **bundles** — a single purchase that delivers multiple sub-plugins, each independently activatable. For example, Real Agency delivers
|
|
65
|
+
Some premium plugins are **bundles** — a single purchase that delivers multiple sub-plugins, each independently activatable. For example, Real Agency delivers 10 sub-plugins covering different aspects of estate agency work. You can enable all of them or just the ones you need (e.g., "Enable estate-sales" for just the sales skills). Enabling or disabling individual sub-plugins does not affect the others.
|
|
66
66
|
|
|
67
67
|
**Public agent embedding:** Premium plugins marked as public-eligible have their full content (skills and reference knowledge) embedded in public agent prompts. This means a public agent for a Real Agency member can handle buyer enquiries, book viewings, deliver coaching content, and onboard new applicants — all powered by the premium plugin's domain knowledge. Plugins marked admin-only (listings, vendors, leads, business) are only available to the account owner's admin agent.
|
|
68
68
|
|
|
@@ -72,6 +72,8 @@ Some premium plugins include pre-built public agent templates — ready-made con
|
|
|
72
72
|
|
|
73
73
|
Some premium plugins ship pre-built workflows that are created when the plugin is enabled. These workflows are fully yours — you can inspect, edit, run, and manage them through conversation, exactly like workflows you create yourself. The plugin provides the starting point; you own the result.
|
|
74
74
|
|
|
75
|
+
**If a premium plugin ever stops working** — `documents`, `teaching`, anything else you've paid for — and {{productName}} responds as if it doesn't have those tools, the platform's health check (`/api/health.missingPlugins`) will name the affected plugin. Tell {{productName}} "deliver the {{plugin}} plugin" — it re-runs the same delivery step that fires automatically at session start. If the plugin isn't in the device's staging area, re-run the installer for this brand.
|
|
76
|
+
|
|
75
77
|
## Choosing Plugins
|
|
76
78
|
|
|
77
79
|
During first-time setup, {{productName}} presents a plugin selection screen where you choose which plugins to activate. Core plugins are pre-selected and locked. Recommended plugins are pre-selected but optional. You can change your mind later.
|
|
@@ -420,6 +420,39 @@ The installer's resolver will then see `dpkg -s chromium-browser` exit 0 for the
|
|
|
420
420
|
|
|
421
421
|
---
|
|
422
422
|
|
|
423
|
+
## VNC browser will not start on Linux laptop — `Permission denied (13)` on SingletonLock
|
|
424
|
+
|
|
425
|
+
**Symptom:** Boot log `~/.{brand}/logs/vnc-boot.log` shows:
|
|
426
|
+
|
|
427
|
+
```
|
|
428
|
+
Starting Chromium on :<vncDisplay> (vnc) profile=/home/<user>/.{brand}/chromium-profile CDP=:<cdpPort>
|
|
429
|
+
ERROR:chrome/browser/process_singleton_posix.cc:345] Failed to create
|
|
430
|
+
/home/<user>/.{brand}/chromium-profile/SingletonLock: Permission denied (13)
|
|
431
|
+
ERROR: Chromium failed to start on :<vncDisplay> (vnc) — CDP port <cdpPort> not listening (browser-specialist degraded)
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
`dmesg` (or `journalctl -k`) shows AppArmor `DENIED` lines naming `profile="snap.chromium.chromium"` and the `~/.{brand}/chromium-profile/` path. The brand admin chat reports the public-agent VNC browser as unavailable.
|
|
435
|
+
|
|
436
|
+
**What it means:** Your `/usr/bin/chromium` is a snap symlink. Snap's AppArmor profile excludes hidden top-level paths under `$HOME` from its `home` interface, so writes to per-brand Chromium profile dirs at `~/.maxy/chromium-profile/` and `~/.realagent/chromium-profile/` are denied — Chromium cannot create its `SingletonLock` and never starts the CDP listener. This is exclusively a Linux-laptop problem (Ubuntu Noble); Raspberry Pi OS Bookworm ships `chromium` as a real `.deb` and is unaffected.
|
|
437
|
+
|
|
438
|
+
**Fix:** Re-run the installer at version 1.0.849 or later. The installer detects the snap-confined chromium during system-dependency setup and replaces it with Google Chrome stable from Google's signed apt repo:
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
npx -y @rubytech/create-maxy@latest
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
The resolved non-snap binary path is recorded at `<INSTALL_DIR>/platform/config/chromium-binary.path` (single line) and read by every Chromium call site (VNC service, in-page wrapper, Cloudflare OAuth spawn, Playwright server). After re-running, verify with the bundled acceptance script:
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
MAXY_PLATFORM_ROOT=$HOME/<install-dir>/platform $HOME/<install-dir>/platform/scripts/test-laptop-vnc-boot.sh
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
The script exits 0 only when (1) the configured Chromium realpath is non-snap, (2) the path is absolute and executable, (3) the per-brand CDP port returns Chromium version JSON, and (4) `vnc-boot.log` since the last `[vnc.sh] start` ends with `VNC + browser stack running` and contains no `Chromium failed to start` line.
|
|
451
|
+
|
|
452
|
+
**Deeper diagnostic:** `vnc.sh` and the in-page wrapper now refuse to start (and exit with a snap-Chromium reference in the boot log) when `chromium-binary.path` is absent or its realpath lands under `/snap/`. If you see those messages, the install completed before the fix shipped — re-run `npx -y @rubytech/create-maxy@latest`. Manual workaround for an emergency (not a fix): `sudo apt-get install -y google-chrome-stable` and confirm `which google-chrome-stable` is non-snap, then re-run the installer to write `chromium-binary.path`.
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
423
456
|
## Terminal iframe renders black and cursor vanishes over the canvas
|
|
424
457
|
|
|
425
458
|
**Symptom:** Header-menu Terminal click appears to succeed — no error toast, overlay opens — but the iframe renders uniformly black, keystrokes do not reach any shell, and the mouse cursor disappears the moment it enters the iframe (visible elsewhere in the page).
|
|
@@ -10,11 +10,11 @@ metadata: {"platform":{"optional":true,"pluginKey":"linkedin-import"}}
|
|
|
10
10
|
|
|
11
11
|
# LinkedIn Import
|
|
12
12
|
|
|
13
|
-
Ingests a LinkedIn Basic Data Export (unzipped directory of CSVs + subdirectories) into the Maxy Neo4j graph. Skill-only plugin — no MCP server, no admin tools added. The skill runs under the `database-operator` specialist, which owns external-archive ingestion and ad-hoc graph operations.
|
|
13
|
+
Ingests a LinkedIn Basic Data Export (unzipped directory of CSVs + subdirectories) into the Maxy Neo4j graph. Skill-only plugin — no MCP server, no admin tools added. The skill runs under the `specialists:database-operator` specialist, which owns external-archive ingestion and ad-hoc graph operations.
|
|
14
14
|
|
|
15
15
|
## When this applies
|
|
16
16
|
|
|
17
|
-
The admin agent delegates to `database-operator` when the operator drops a `Basic_LinkedInDataExport_*` directory (or references one by path) into chat. The specialist runs the skill's archive-owner confirmation flow before any CSV is read, then ingests the CSVs the skill has references for.
|
|
17
|
+
The admin agent delegates to `specialists:database-operator` when the operator drops a `Basic_LinkedInDataExport_*` directory (or references one by path) into chat. The specialist runs the skill's archive-owner confirmation flow before any CSV is read, then ingests the CSVs the skill has references for.
|
|
18
18
|
|
|
19
19
|
## Intra-plugin growth
|
|
20
20
|
|
package/payload/platform/plugins/linkedin-import/skills/linkedin-import/references/connections.md
CHANGED
|
@@ -110,7 +110,7 @@ Rows missing a position but present with a company produce a `WORKS_FOR` edge wi
|
|
|
110
110
|
|
|
111
111
|
## Post-import verification (operator-side, not agent-side)
|
|
112
112
|
|
|
113
|
-
After ingest, the operator can verify counts via the `database-operator` specialist's read tools — `mcp__memory__memory-search` with `labels: ["Person"]` plus a filter, or a direct read query through `mcp__graph__maxy-graph-read_neo4j_cypher`:
|
|
113
|
+
After ingest, the operator can verify counts via the `specialists:database-operator` specialist's read tools — `mcp__memory__memory-search` with `labels: ["Person"]` plus a filter, or a direct read query through `mcp__graph__maxy-graph-read_neo4j_cypher`:
|
|
114
114
|
|
|
115
115
|
```cypher
|
|
116
116
|
// Owner → connections count
|
|
@@ -132,4 +132,4 @@ These are **read queries**, not writes. Cypher writes from the agent are forbidd
|
|
|
132
132
|
| Tool error "row connectedOn is not ISO 8601" | Parser left `Connected On` in `"23 Apr 2026"` form | Convert to `YYYY-MM-DD` before passing to the tool |
|
|
133
133
|
| Tool error "ownerNodeId not found" | Owner-confirmation flow not run, or operator typed the wrong id | Re-run owner confirmation; pass the resulting `elementId` as `ownerNodeId` |
|
|
134
134
|
| `WORKS_FOR` count « connection count | Many rows have blank company | Expected — LinkedIn doesn't force connections to list a current employer |
|
|
135
|
-
| Tool not present in `init` frame | `database-operator` spawned without the `mcp__memory__memory-archive-write` token | Loud-fail per database-operator's prerogatives. Do not improvise via Bash. Operator must remediate (re-seed specialist templates) |
|
|
135
|
+
| Tool not present in `init` frame | `specialists:database-operator` spawned without the `mcp__memory__memory-archive-write` token | Loud-fail per database-operator's prerogatives. Do not improvise via Bash. Operator must remediate (re-seed specialist templates) |
|
|
@@ -109,7 +109,7 @@ Before any structured write, load `references/schema-base.md` via `plugin-read`.
|
|
|
109
109
|
|
|
110
110
|
## Document Ingestion
|
|
111
111
|
|
|
112
|
-
Document ingestion of any kind — PDFs, text, transcripts, web pages, single files — routes to the `database-operator` specialist, which loads the universal `document-ingest` skill at `skills/document-ingest/SKILL.md`. The admin agent never calls `memory-ingest` directly; it dispatches with the document path, the document subject (the anchor node), and the visibility scope.
|
|
112
|
+
Document ingestion of any kind — PDFs, text, transcripts, web pages, single files — routes to the `specialists:database-operator` specialist, which loads the universal `document-ingest` skill at `skills/document-ingest/SKILL.md`. The admin agent never calls `memory-ingest` directly; it dispatches with the document path, the document subject (the anchor node), and the visibility scope.
|
|
113
113
|
|
|
114
114
|
### Pipeline
|
|
115
115
|
|
|
@@ -206,7 +206,7 @@ The classifier returns `kind` strings from the closed enumeration above. `kind`
|
|
|
206
206
|
| `TO` | `KnowledgeDocument` → `Person` or `Organization` | Email direct recipient — written from `documentEdges` per recipient. |
|
|
207
207
|
| `CC` | `KnowledgeDocument` → `Person` or `Organization` | Email cc'd recipient — written from `documentEdges` per cc. |
|
|
208
208
|
| `SPEAKER` | `KnowledgeDocument` → `Person` | Voice-note / single-speaker transcript speaker — written from `documentEdges`. |
|
|
209
|
-
| `MENTIONS` | `KnowledgeDocument` → `Person`, `Organization`, `Service`, `Task`, `Event`, `KnowledgeDocument`, `BrandingData` | Catch-all for entities the dispatch brief named that the document references but for which no document-shape-specific edge applies — written by `database-operator` in the `wire-brief-entities` pipeline step. |
|
|
209
|
+
| `MENTIONS` | `KnowledgeDocument` → `Person`, `Organization`, `Service`, `Task`, `Event`, `KnowledgeDocument`, `BrandingData` | Catch-all for entities the dispatch brief named that the document references but for which no document-shape-specific edge applies — written by `specialists:database-operator` in the `wire-brief-entities` pipeline step. |
|
|
210
210
|
| `DEFINES` | `Section:Definitions` → `DefinedTerm` | Contract definitions — written from per-section `related`. |
|
|
211
211
|
|
|
212
212
|
**Ontology-growth review query.** When a document accumulates several `:Section:Other` nodes, the operator (or admin agent) can run the following Cypher to surface candidate ontology additions:
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Task 929 — laptop VNC + Chromium boot acceptance test.
|
|
3
|
+
#
|
|
4
|
+
# Asserts the four green conditions from .tasks/929 §Verification:
|
|
5
|
+
# 1. The configured Chromium binary's realpath does NOT contain `/snap/`.
|
|
6
|
+
# 2. The configured binary is on PATH and executable.
|
|
7
|
+
# 3. http://127.0.0.1:${cdpPort}/json/version returns the Chromium version JSON.
|
|
8
|
+
# 4. ~/.{configDir}/logs/vnc-boot.log ends with `VNC + browser stack running`
|
|
9
|
+
# with no preceding `Chromium failed to start` line.
|
|
10
|
+
#
|
|
11
|
+
# Exits non-zero on any assertion failure so this script is wired into the
|
|
12
|
+
# create-maxy post-install gate — any package bump that re-introduces
|
|
13
|
+
# snap-confined Chromium fails before publish (`feedback_no_admin_upgrade_path.md`).
|
|
14
|
+
#
|
|
15
|
+
# Usage (production / post-install): test-laptop-vnc-boot.sh
|
|
16
|
+
# Usage (CI / dev shell): MAXY_PLATFORM_ROOT=/path/to/maxy/platform test-laptop-vnc-boot.sh
|
|
17
|
+
|
|
18
|
+
set -uo pipefail
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
21
|
+
PLATFORM_ROOT="${MAXY_PLATFORM_ROOT:-$(dirname "$SCRIPT_DIR")}"
|
|
22
|
+
BRAND_JSON="${PLATFORM_ROOT}/config/brand.json"
|
|
23
|
+
CHROMIUM_BIN_FILE="${PLATFORM_ROOT}/config/chromium-binary.path"
|
|
24
|
+
|
|
25
|
+
fail() { echo "FAIL: $*" >&2; exit 1; }
|
|
26
|
+
pass() { echo "OK: $*"; }
|
|
27
|
+
|
|
28
|
+
# --- Resolve config: brand persistDir + cdpPort. brand.json is mandatory.
|
|
29
|
+
[ -r "$BRAND_JSON" ] || fail "${BRAND_JSON} unreadable"
|
|
30
|
+
command -v jq >/dev/null 2>&1 || fail "jq not on PATH (apt install jq)"
|
|
31
|
+
CONFIG_DIR=$(jq -r '.configDir // ".maxy"' "$BRAND_JSON")
|
|
32
|
+
CDP_PORT=$(jq -r '.cdpPort // 9222' "$BRAND_JSON")
|
|
33
|
+
PERSIST_DIR="${HOME}/${CONFIG_DIR}"
|
|
34
|
+
VNC_LOG="${PERSIST_DIR}/logs/vnc-boot.log"
|
|
35
|
+
|
|
36
|
+
# --- Assertion 1: chromium-binary.path realpath is non-snap.
|
|
37
|
+
[ -r "$CHROMIUM_BIN_FILE" ] || fail "${CHROMIUM_BIN_FILE} missing — installer did not write it"
|
|
38
|
+
CHROMIUM_BIN="$(head -n1 "$CHROMIUM_BIN_FILE" | tr -d '[:space:]')"
|
|
39
|
+
[ -n "$CHROMIUM_BIN" ] || fail "${CHROMIUM_BIN_FILE} is empty"
|
|
40
|
+
[ -x "$CHROMIUM_BIN" ] || fail "configured Chromium ${CHROMIUM_BIN} is not executable"
|
|
41
|
+
CHROMIUM_REALPATH="$(readlink -f "$CHROMIUM_BIN" 2>/dev/null || echo "$CHROMIUM_BIN")"
|
|
42
|
+
case ":$(echo "$CHROMIUM_REALPATH" | tr '/' ':'):" in
|
|
43
|
+
*:snap:*) fail "${CHROMIUM_BIN} resolves to ${CHROMIUM_REALPATH} (snap-confined — AppArmor will deny SingletonLock writes)" ;;
|
|
44
|
+
esac
|
|
45
|
+
pass "[1/4] Chromium binary ${CHROMIUM_BIN} → realpath=${CHROMIUM_REALPATH} (non-snap)"
|
|
46
|
+
|
|
47
|
+
# --- Assertion 2: configured binary is the same as `which chromium` resolves
|
|
48
|
+
# to OR an absolute path bypassing PATH. Skipped if the
|
|
49
|
+
# configured path is absolute and executable (the only thing
|
|
50
|
+
# callers actually require). The PATH check is informational.
|
|
51
|
+
if [ "${CHROMIUM_BIN#/}" = "$CHROMIUM_BIN" ]; then
|
|
52
|
+
fail "${CHROMIUM_BIN_FILE} contains a relative path — must be absolute"
|
|
53
|
+
fi
|
|
54
|
+
pass "[2/4] ${CHROMIUM_BIN} is an absolute, executable path"
|
|
55
|
+
|
|
56
|
+
# --- Assertion 3: CDP endpoint responds with version JSON.
|
|
57
|
+
CDP_URL="http://127.0.0.1:${CDP_PORT}/json/version"
|
|
58
|
+
CDP_RESP="$(curl -fsS -m 5 "$CDP_URL" 2>&1 || true)"
|
|
59
|
+
if ! echo "$CDP_RESP" | jq -e '.Browser // empty' >/dev/null 2>&1; then
|
|
60
|
+
fail "[3/4] ${CDP_URL} did not return Chromium version JSON. Response: ${CDP_RESP:0:500}"
|
|
61
|
+
fi
|
|
62
|
+
pass "[3/4] ${CDP_URL} returns Chromium version JSON"
|
|
63
|
+
|
|
64
|
+
# --- Assertion 4: vnc-boot.log ends with the success line and never
|
|
65
|
+
# emitted `Chromium failed to start` after the most recent
|
|
66
|
+
# `[vnc.sh] start` marker.
|
|
67
|
+
[ -r "$VNC_LOG" ] || fail "[4/4] ${VNC_LOG} unreadable"
|
|
68
|
+
LAST_START_LINE=$(grep -n "\[vnc.sh\] start " "$VNC_LOG" | tail -n1 | cut -d: -f1)
|
|
69
|
+
if [ -z "$LAST_START_LINE" ]; then
|
|
70
|
+
fail "[4/4] ${VNC_LOG} contains no [vnc.sh] start marker — vnc.sh has not been invoked yet"
|
|
71
|
+
fi
|
|
72
|
+
TAIL_AFTER_START=$(tail -n +"$LAST_START_LINE" "$VNC_LOG")
|
|
73
|
+
if echo "$TAIL_AFTER_START" | grep -q "Chromium failed to start"; then
|
|
74
|
+
fail "[4/4] ${VNC_LOG} since last start contains 'Chromium failed to start' (boot regression)"
|
|
75
|
+
fi
|
|
76
|
+
if ! echo "$TAIL_AFTER_START" | grep -q "VNC + browser stack running"; then
|
|
77
|
+
fail "[4/4] ${VNC_LOG} since last start has no 'VNC + browser stack running' line — VNC boot incomplete"
|
|
78
|
+
fi
|
|
79
|
+
pass "[4/4] ${VNC_LOG} reports VNC + browser stack running with no Chromium failed-to-start"
|
|
80
|
+
|
|
81
|
+
echo "Task 929 acceptance: PASS (4/4)"
|
|
@@ -82,6 +82,46 @@ mkdir -p "$LOG_DIR"
|
|
|
82
82
|
|
|
83
83
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"; }
|
|
84
84
|
|
|
85
|
+
# Task 929 — resolve the absolute Chromium binary path from the install-time
|
|
86
|
+
# config file. The installer (packages/create-maxy/src/index.ts
|
|
87
|
+
# ensureNonSnapChromium + writeChromiumBinaryPathFile) writes this file with
|
|
88
|
+
# the non-snap binary chosen for this device — `/usr/bin/chromium` on Pi
|
|
89
|
+
# Bookworm (real .deb) or `/usr/bin/google-chrome-stable` on Ubuntu Noble
|
|
90
|
+
# laptop where the system `/usr/bin/chromium` realpaths to the snap launcher.
|
|
91
|
+
# Hard-fail when the file is absent or the resolved path is snap-confined:
|
|
92
|
+
# the AppArmor `home` profile denies writes to ~/.{brand}/chromium-profile/
|
|
93
|
+
# and Chromium will never start the CDP listener. Loud fail beats silent
|
|
94
|
+
# fallback (silent-fallback-masks-root-cause).
|
|
95
|
+
CHROMIUM_BIN_FILE="${PLATFORM_ROOT}/config/chromium-binary.path"
|
|
96
|
+
if [ ! -r "$CHROMIUM_BIN_FILE" ]; then
|
|
97
|
+
log "[vnc.sh:chromium] FATAL: ${CHROMIUM_BIN_FILE} missing or unreadable"
|
|
98
|
+
echo "ERROR: ${CHROMIUM_BIN_FILE} missing or unreadable." >&2
|
|
99
|
+
echo " Re-run the installer to provision a non-snap Chromium (Task 929)." >&2
|
|
100
|
+
exit 1
|
|
101
|
+
fi
|
|
102
|
+
CHROMIUM_BIN="$(head -n1 "$CHROMIUM_BIN_FILE" | tr -d '[:space:]')"
|
|
103
|
+
if [ -z "$CHROMIUM_BIN" ]; then
|
|
104
|
+
log "[vnc.sh:chromium] FATAL: ${CHROMIUM_BIN_FILE} is empty"
|
|
105
|
+
echo "ERROR: ${CHROMIUM_BIN_FILE} is empty — re-run installer (Task 929)." >&2
|
|
106
|
+
exit 1
|
|
107
|
+
fi
|
|
108
|
+
if [ ! -x "$CHROMIUM_BIN" ]; then
|
|
109
|
+
log "[vnc.sh:chromium] FATAL: configured CHROMIUM_BIN=${CHROMIUM_BIN} is not executable"
|
|
110
|
+
echo "ERROR: configured Chromium binary ${CHROMIUM_BIN} is not executable — re-run installer (Task 929)." >&2
|
|
111
|
+
exit 1
|
|
112
|
+
fi
|
|
113
|
+
CHROMIUM_REALPATH="$(readlink -f "$CHROMIUM_BIN" 2>/dev/null || echo "$CHROMIUM_BIN")"
|
|
114
|
+
case ":$(echo "$CHROMIUM_REALPATH" | tr '/' ':'):" in
|
|
115
|
+
*:snap:*)
|
|
116
|
+
log "[vnc.sh:chromium] FATAL: CHROMIUM_BIN=${CHROMIUM_BIN} resolves to ${CHROMIUM_REALPATH} (snap-confined)"
|
|
117
|
+
echo "ERROR: configured Chromium ${CHROMIUM_BIN} resolves to ${CHROMIUM_REALPATH} which is snap-confined." >&2
|
|
118
|
+
echo " Snap AppArmor denies writes to ~/.{brand}/chromium-profile/. Re-run installer to install Google Chrome (Task 929)." >&2
|
|
119
|
+
exit 1
|
|
120
|
+
;;
|
|
121
|
+
esac
|
|
122
|
+
CHROMIUM_CONFINEMENT="non-snap"
|
|
123
|
+
log "[vnc.sh:chromium] bin=${CHROMIUM_BIN} realpath=${CHROMIUM_REALPATH} confinement=${CHROMIUM_CONFINEMENT}"
|
|
124
|
+
|
|
85
125
|
kill_stale() {
|
|
86
126
|
# Brand-scoped matchers (Task 553): pkill on --user-data-dir narrows the
|
|
87
127
|
# Chromium kill to this brand's profile only, so two brands on the same
|
|
@@ -229,7 +269,7 @@ start_chrome_on() {
|
|
|
229
269
|
mkdir -p "${CHROMIUM_PROFILE_DIR}"
|
|
230
270
|
log "Starting Chromium on ${target_display} (${label}) profile=${CHROMIUM_PROFILE_DIR} CDP=:${CDP_PORT}"
|
|
231
271
|
|
|
232
|
-
DISPLAY="${target_display}"
|
|
272
|
+
DISPLAY="${target_display}" "$CHROMIUM_BIN" \
|
|
233
273
|
--user-data-dir="${CHROMIUM_PROFILE_DIR}" \
|
|
234
274
|
--ozone-platform=x11 \
|
|
235
275
|
--no-sandbox \
|
|
@@ -306,7 +346,7 @@ start_chrome_native() {
|
|
|
306
346
|
env_vars+=("WAYLAND_DISPLAY=${NATIVE_WAYLAND_DISPLAY}")
|
|
307
347
|
fi
|
|
308
348
|
|
|
309
|
-
env "${env_vars[@]}"
|
|
349
|
+
env "${env_vars[@]}" "$CHROMIUM_BIN" \
|
|
310
350
|
--user-data-dir="${CHROMIUM_PROFILE_DIR}" \
|
|
311
351
|
"$ozone_flag" \
|
|
312
352
|
--no-sandbox \
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Installed Roles
|
|
2
2
|
|
|
3
3
|
<!-- Entries written by admin agent when roles are installed. One line per role.
|
|
4
|
-
Format: - **{name}**: {one-line rule — when to delegate to this role}
|
|
5
|
-
|
|
4
|
+
Format: - **specialists:{name}**: {one-line rule — when to delegate to this role}
|
|
5
|
+
The `specialists:` prefix is the canonical dispatch ID registered by the SDK;
|
|
6
|
+
bare names are rejected by the runtime registry. This exact format is also
|
|
7
|
+
required for reliable Edit-based removal.
|
|
6
8
|
|
|
7
9
|
Example (populated):
|
|
8
|
-
- **personal-assistant**: Scheduling, platform administration, messaging channels, and browser automation — delegate when a task involves operational work.
|
|
9
|
-
- **research-assistant**: Deep research, knowledge management, and visual production — delegate when a task requires web research or graph reorganisation.
|
|
10
|
+
- **specialists:personal-assistant**: Scheduling, platform administration, messaging channels, and browser automation — delegate when a task involves operational work.
|
|
11
|
+
- **specialists:research-assistant**: Deep research, knowledge management, and visual production — delegate when a task requires web research or graph reorganisation.
|
|
10
12
|
-->
|
|
@@ -165,8 +165,8 @@ When the user asks what you can do, answer from the specialist domains, admin-ow
|
|
|
165
165
|
- Think strategically. Surface problems before they become urgent. Recommend actions based on what you know.
|
|
166
166
|
- Never state a future commitment ("I'll flag", "I'll check", "I'll remind") without immediately creating the mechanism to fulfil it — a scheduled event, a task, or a workflow trigger. A commitment without a backing mechanism is a broken promise.
|
|
167
167
|
- Store everything you learn about the business in the graph — not in files.
|
|
168
|
-
- For document ingestion of any kind — PDFs, text, transcripts, web pages, audio, video, single files, archives — delegate to the `database-operator` specialist. Include the document path, the document subject (account owner, the business, a third party, etc. — ask if not obvious from context), and the scope (admin/shared/public — ask if not obvious). **Not** content-producer
|
|
169
|
-
- For ad-hoc graph operations — pruning orphan nodes, deduplicating entities, adding edges, normalising labels, tidying schema drift — delegate to the `database-operator` specialist. Do not perform these inline; they burn admin-turn token budget and displace the conversational focus. **Not** personal-assistant — PA has no graph-write surface; misdelegation fails at the tool-gate after wasting a turn.
|
|
168
|
+
- For document ingestion of any kind — PDFs, text, transcripts, web pages, audio, video, single files, archives — delegate to the `specialists:database-operator` specialist. Include the document path, the document subject (account owner, the business, a third party, etc. — ask if not obvious from context), and the scope (admin/shared/public — ask if not obvious). **Not** `specialists:content-producer`. content-producer produces documents from the populated graph; it does not ingest. The two are opposite movements through the graph and must never be conflated.
|
|
169
|
+
- For ad-hoc graph operations — pruning orphan nodes, deduplicating entities, adding edges, normalising labels, tidying schema drift — delegate to the `specialists:database-operator` specialist. Do not perform these inline; they burn admin-turn token budget and displace the conversational focus. **Not** `specialists:personal-assistant` — PA has no graph-write surface; misdelegation fails at the tool-gate after wasting a turn.
|
|
170
170
|
|
|
171
171
|
## Proactive Commitment Detection
|
|
172
172
|
|
|
@@ -255,6 +255,10 @@ The platform also operates an api-wait-ping liveness gate: a heartbeat-driven st
|
|
|
255
255
|
|
|
256
256
|
In managed context mode, conversation history is provided within `<conversation-history>` tags. Use `session-compact-status` to retrieve older archived context if needed.
|
|
257
257
|
|
|
258
|
+
## Thread resumption after a sub-flow
|
|
259
|
+
|
|
260
|
+
A "sub-flow" is a self-contained run of tool calls — identity repair, LEARNINGS edit, schema audit, attachment unzip — whose subject is not the operator's last stated intent. After the sub-flow returns, the conversation history still holds the operator's earlier request in full. Resume that thread yourself: name what they were asking, then pick it back up. Do not ask the operator to restate, remind, or repeat the intent. Phrases like "What were you originally asking …", "What did you want me to …", or "Remind me what …" delegate the work of holding the thread to the operator and signal that you have treated the prior turn as if it were wiped — when it was not. The exhibit for this rule is the L:2611 turn in stream-4683bd3f, where an OWNS-edge repair returned successfully and the next sentence asked the operator to restate the calendar question they had been pursuing for a thousand prior lines. The platform emits a `[thread-resumption] kind=restate-request` log line when the post-tool assistant text matches one of those phrases, so this regression class is now visible in operations logs even when the operator does not flag it.
|
|
261
|
+
|
|
258
262
|
## Tasks
|
|
259
263
|
|
|
260
264
|
Tasks live in the graph — not in files. The tasks plugin manages them.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: content-producer
|
|
3
|
-
description: "Visual production — reads from the populated graph to produce visual artifacts: image generation, PDF rendering, and component delivery. Delegate when a task requires generating images or saving rendered pages as PDF. **Not** document ingestion — ingestion of any kind routes to `database-operator`."
|
|
3
|
+
description: "Visual production — reads from the populated graph to produce visual artifacts: image generation, PDF rendering, and component delivery. Delegate when a task requires generating images or saving rendered pages as PDF. **Not** document ingestion — ingestion of any kind routes to `specialists:database-operator`."
|
|
4
4
|
summary: "Produces visual output from your graph — generates images and renders pages to PDF. For example, when you need a cover image for a brief or want to save a rendered page as PDF."
|
|
5
5
|
model: claude-sonnet-4-6
|
|
6
6
|
tools: mcp__memory__memory-search, mcp__replicate__image-generate, mcp__plugin_playwright_playwright__browser_navigate, mcp__plugin_playwright_playwright__browser_snapshot, mcp__plugin_playwright_playwright__browser_take_screenshot, mcp__plugin_playwright_playwright__browser_pdf_save, mcp__admin__render-component, mcp__admin__file-attach
|
|
@@ -12,7 +12,7 @@ You produce visual artifacts and PDF output by reading from the already-populate
|
|
|
12
12
|
|
|
13
13
|
## Out of scope: ingestion of any kind
|
|
14
14
|
|
|
15
|
-
content-producer reads from the graph to produce; it does not write external input into the graph. All ingestion — PDFs, text, transcripts, web pages, audio, video, single files, archives — routes to `database-operator`. Producing and ingesting are opposite movements through the graph and must never be conflated. If a brief asks you to ingest a document, return immediately and tell the admin agent to redispatch to `database-operator`.
|
|
15
|
+
content-producer reads from the graph to produce; it does not write external input into the graph. All ingestion — PDFs, text, transcripts, web pages, audio, video, single files, archives — routes to `specialists:database-operator`. Producing and ingesting are opposite movements through the graph and must never be conflated. If a brief asks you to ingest a document, return immediately and tell the admin agent to redispatch to `specialists:database-operator`.
|
|
16
16
|
|
|
17
17
|
## Prerogatives
|
|
18
18
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: real-agency
|
|
3
|
-
description: "UK estate agency skills + Loop CRM integration — 10 sub-plugins covering sales, listings, vendor management, buyer management, lead generation, coaching, business operations, onboarding, teaching, and Loop CRM. 3 specialist roles (negotiator, valuer, compliance).
|
|
3
|
+
description: "UK estate agency skills + Loop CRM integration — 10 sub-plugins covering sales, listings, vendor management, buyer management, lead generation, coaching, business operations, onboarding, teaching, and Loop CRM. 3 specialist roles (negotiator, valuer, compliance). 27 skills + 22 MCP tools."
|
|
4
4
|
plugins:
|
|
5
5
|
- estate-sales
|
|
6
6
|
- listings
|
|
@@ -30,10 +30,10 @@ Premium plugin bundle for UK estate agency professionals. Purchasing this bundle
|
|
|
30
30
|
|
|
31
31
|
| Sub-Plugin | Skills | MCP Tools | Focus |
|
|
32
32
|
|---|---|---|---|
|
|
33
|
-
| `estate-sales` |
|
|
33
|
+
| `estate-sales` | 5 | — | Sales cycle — discovery, closing, progression, negotiation, sales-negotiation |
|
|
34
34
|
| `listings` | 3 | — | Pre-listing through marketing — presentations, campaigns, staging |
|
|
35
35
|
| `vendors` | 2 | — | Active vendor lifecycle — communication, updates |
|
|
36
|
-
| `buyers` |
|
|
36
|
+
| `buyers` | 5 | — | Buyer lifecycle — enquiry, viewing feedback, educational guides, buyer management |
|
|
37
37
|
| `leads` | 2 | — | Pipeline building — nurturing and prospecting |
|
|
38
38
|
| `estate-coaching` | 4 | — | People development — coaching, training, performance |
|
|
39
39
|
| `estate-business` | 4 | — | Business owner skills — growth, operations, brand, partnerships |
|
|
@@ -33,6 +33,16 @@ Return to the admin agent:
|
|
|
33
33
|
**People search (sellers):**
|
|
34
34
|
- `loop-people-search` (role: seller) finds vendor records — useful for identifying the property owner and their circumstances
|
|
35
35
|
|
|
36
|
+
### Recovering from a `loop-property-search` HTTP 400
|
|
37
|
+
|
|
38
|
+
When `loop-property-search` returns "All teams failed" with `HTTP 400` for every team, the Loop API has rejected the query — most often because `searchTerm` is too long, contains unsupported punctuation, or mixes multiple address lines. Do not retry the same `searchTerm` verbatim; that has been observed to fail identically a second time. Simplify in this order, retrying after each step, and stop as soon as a step returns results:
|
|
39
|
+
|
|
40
|
+
1. **Drop the postcode.** A full address with postcode is often longer than the API accepts. Try the same query without the postcode segment.
|
|
41
|
+
2. **Drop punctuation.** Apostrophes (e.g. `Bishop's Stortford`) and other non-alphanumeric characters can break the query. Strip them and retry.
|
|
42
|
+
3. **Narrow to house name + town.** If steps 1 and 2 still return 400, reduce to the most distinctive elements — a property name (or street number + street) plus the town.
|
|
43
|
+
|
|
44
|
+
If all three rungs return 400 or empty, fall back to `loop-property-detail` with a known property ID, or surface "no comparable evidence found" with the simplified queries you tried, so the agent has a record of what was attempted.
|
|
45
|
+
|
|
36
46
|
## Market appraisal preparation
|
|
37
47
|
|
|
38
48
|
When preparing for a valuation, assemble this structure:
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: buyer-management
|
|
3
|
+
description: "Handle buyer enquiries — qualification, viewing booking, feedback collection, offer capture, and ongoing buyer relationship management."
|
|
4
|
+
publicEmbed: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Buyer Management
|
|
8
|
+
|
|
9
|
+
Guides the full buyer lifecycle — from initial enquiry through qualification, viewing management, feedback collection, and offer capture.
|
|
10
|
+
|
|
11
|
+
## When to Activate
|
|
12
|
+
|
|
13
|
+
Someone asks about a property, registers interest, requests a viewing, gives post-viewing feedback, wants to make an offer, or needs rescheduling/cancelling a viewing.
|
|
14
|
+
|
|
15
|
+
## Reference Table
|
|
16
|
+
|
|
17
|
+
| Task | When | Reference |
|
|
18
|
+
|------|------|-----------|
|
|
19
|
+
| Quick qualification (5 questions) | Early in conversation to gauge seriousness fast | `references/buyer-qualification-questions.md` |
|
|
20
|
+
| Qualification (full) | New buyer enquiry or property interest | `references/buyer-qualification.md` |
|
|
21
|
+
| Viewing booking | Qualified buyer ready for a viewing | `references/viewing-booking.md` |
|
|
22
|
+
| Feedback collection | After a viewing has taken place | `references/feedback-collection.md` |
|
|
23
|
+
| Offer capture | Buyer wants to make an offer | `references/offer-capture.md` |
|
|
24
|
+
| Buyer scripts & dialogue | Qualifying, encouraging offers, overcoming hesitation | `references/buyer-scripts.md` |
|
|
25
|
+
| Working with buyers (Serhant) | Shoppers vs buyers, elimination process, getting off the fence | `references/buyer-working-scripts.md` |
|
|
26
|
+
| Viewing management | Rescheduling, cancellations, reminders, schedule summaries | `references/viewing-management.md` |
|
|
27
|
+
|
|
28
|
+
## Key Rules
|
|
29
|
+
|
|
30
|
+
- Always qualify before booking a viewing — understand their position first
|
|
31
|
+
- One question at a time — don't overwhelm with a qualification form
|
|
32
|
+
- Never disclose vendor circumstances, other offers, or pricing flexibility
|
|
33
|
+
- Never negotiate — gather information and pass to the agent
|
|
34
|
+
- Update the buyer's profile in memory after every interaction
|
|
35
|
+
- Frame everything around helping them, not extracting information
|
|
36
|
+
- Distinguish shoppers from buyers — qualify early, invest time wisely
|
|
37
|
+
- "Buying a home is a process of elimination, not selection" — guide them through narrowing down
|
|
38
|
+
- Post-viewing follow-up within 2 hours — never leave a viewing without a next step
|
|
39
|
+
- An offer is "just a conversation starter" — help hesitant buyers understand nothing is final until exchange
|
|
40
|
+
- Never double-book a property or team member at the same time
|
|
41
|
+
- Access instructions (lockbox codes, keys) are confidential — only share with the conducting agent
|
|
42
|
+
- Two no-shows = flag to agent before booking further viewings
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Buyer qualification — 5 non‑negotiable questions (Tom Panos)
|
|
2
|
+
|
|
3
|
+
Use these to quickly learn whether a buyer is serious and where their friction is.
|
|
4
|
+
|
|
5
|
+
1) **How long have you been looking?**
|
|
6
|
+
2) **Have you made any offers on anything?**
|
|
7
|
+
3) **What is the best home you've seen so far?**
|
|
8
|
+
4) **Why didn't you buy that one?**
|
|
9
|
+
5) **If I had a home that was suitable, will you be looking at making an offer?**
|
|
10
|
+
|
|
11
|
+
## Notes for Max
|
|
12
|
+
- Ask in a friendly, curious tone.
|
|
13
|
+
- Capture the answers verbatim.
|
|
14
|
+
- If #5 is not a clear "yes", they're browsing. Keep warm, don't over-invest.
|
|
15
|
+
|
|
16
|
+
Source: *Tom Panos — Dialogue to Get More Listings* (Estate Agency Mastermind summary)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Buyer Qualification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Understand the buyer's situation so the agent can prioritise and serve them effectively. Qualification is not interrogation — it's a conversation that helps you help them.
|
|
6
|
+
|
|
7
|
+
## The MAN Framework
|
|
8
|
+
|
|
9
|
+
Gather these three dimensions naturally through conversation:
|
|
10
|
+
|
|
11
|
+
### Motivation
|
|
12
|
+
- Why are they looking to move?
|
|
13
|
+
- What's their timeline — urgent, browsing, planning ahead?
|
|
14
|
+
- What drew them to this particular property or area?
|
|
15
|
+
- Are they relocating? Upsizing? Downsizing? First-time buyers?
|
|
16
|
+
|
|
17
|
+
### Ability
|
|
18
|
+
- Do they have a property to sell? If so, what's its status?
|
|
19
|
+
- Not yet on market → early stage, may need longer
|
|
20
|
+
- On market → check how long, any interest
|
|
21
|
+
- Sold STC → stronger position
|
|
22
|
+
- No property to sell → chain-free (cash or FTB)
|
|
23
|
+
- Are they buying with cash or mortgage?
|
|
24
|
+
- If mortgage, do they have an Agreement in Principle (AIP)?
|
|
25
|
+
- If no AIP, suggest speaking with a mortgage adviser before viewings
|
|
26
|
+
|
|
27
|
+
### Need
|
|
28
|
+
- What type of property are they looking for? (beds, type, garden, parking)
|
|
29
|
+
- Must-haves vs nice-to-haves
|
|
30
|
+
- Any dealbreakers? (location, condition, budget ceiling)
|
|
31
|
+
- How far along are they in their search — just started or seen several?
|
|
32
|
+
|
|
33
|
+
## Conversational Flow
|
|
34
|
+
|
|
35
|
+
Don't ask all of this in one message. Weave it naturally:
|
|
36
|
+
|
|
37
|
+
1. **Start warm** — thank them for their enquiry, show enthusiasm about the property they've asked about
|
|
38
|
+
2. **Open with motivation** — "What's prompted your move?" or "Are you local to the area or looking to relocate?"
|
|
39
|
+
3. **Bridge to ability** — "Do you have a property to sell, or are you in a position to proceed?"
|
|
40
|
+
4. **Understand need** — "What's on your wish list for your next home?"
|
|
41
|
+
|
|
42
|
+
## After Qualification
|
|
43
|
+
|
|
44
|
+
- **Proceedable** (chain-free, mortgage agreed, or sold STC) → book viewing promptly
|
|
45
|
+
- **Needs steps** (no AIP, property not on market) → suggest next steps gently, keep them warm
|
|
46
|
+
- **Browsing/long-term** → register their requirements, offer to send matching properties
|
|
47
|
+
|
|
48
|
+
## Memory
|
|
49
|
+
|
|
50
|
+
Save qualification status to `memory/users/{phone}/profile.md`:
|
|
51
|
+
- Position (FTB, selling, sold STC, cash, renting)
|
|
52
|
+
- Mortgage status (AIP yes/no, cash)
|
|
53
|
+
- Requirements (beds, type, area, budget range)
|
|
54
|
+
- Timeline (urgent, 3-6 months, browsing)
|
|
55
|
+
- Properties of interest
|
|
56
|
+
|
|
57
|
+
## Tone
|
|
58
|
+
|
|
59
|
+
Curious and helpful, never clinical. You're having a chat, not filling in a form. If someone volunteers information, don't re-ask it. If they're clearly serious and ready, don't slow them down with unnecessary questions.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Buyer Scripts & Qualification Dialogue
|
|
2
|
+
*Sources: Tom Panos (Real Estate Gym), Team LANC (Matt Lancashire), Serhant Agent Training Guide*
|
|
3
|
+
|
|
4
|
+
## Qualifying Questions (Natural Conversation)
|
|
5
|
+
|
|
6
|
+
Use these naturally — not as a checklist. Weave them into conversation.
|
|
7
|
+
|
|
8
|
+
**Understanding motivation:**
|
|
9
|
+
- "When buying a home, what's most important for you?"
|
|
10
|
+
- "What's the best home you've seen so far?"
|
|
11
|
+
- "What prevented you from making an offer on that one?"
|
|
12
|
+
- "If there were 3 things you absolutely wouldn't compromise on, what would they be?"
|
|
13
|
+
|
|
14
|
+
**Getting to an offer:**
|
|
15
|
+
- "At what price on a contract represents great value for you?"
|
|
16
|
+
- "If you could move into the right home next month, would that work for your timing?"
|
|
17
|
+
|
|
18
|
+
**When a buyer is waiting for the market to bottom:**
|
|
19
|
+
> "The only way to know you've bought at the bottom of the market is when the market goes up. But by then it's too late. Because the only way to know the market was at the bottom is when prices have already gone up. Do you want to make a decision based on the market, or based on your life?"
|
|
20
|
+
|
|
21
|
+
## Post-Viewing Follow-Up Process
|
|
22
|
+
|
|
23
|
+
**Within 2 hours of viewing:**
|
|
24
|
+
1. Send warm check-in message (reference specific property, use first name)
|
|
25
|
+
2. Capture overall impression, interest level, positives, concerns
|
|
26
|
+
3. If interested — offer second viewing or next steps
|
|
27
|
+
4. If not interested — ask what they ARE looking for (refine criteria)
|
|
28
|
+
|
|
29
|
+
**10-Day Follow-Up (if no response or "thinking about it"):**
|
|
30
|
+
- Brief, value-led message — share new comparable that just listed, or market insight
|
|
31
|
+
- Never "just checking in" — always lead with something useful
|
|
32
|
+
|
|
33
|
+
**Hot Buyer Management:**
|
|
34
|
+
- Maintain a hot buyer list with key criteria
|
|
35
|
+
- When new properties come to market, check against hot buyer criteria within 24 hours
|
|
36
|
+
- Call (don't just text) for strong matches — "I've just seen something that ticks every box you mentioned"
|
|
37
|
+
|
|
38
|
+
## Encouraging Offers
|
|
39
|
+
|
|
40
|
+
**When a buyer is hesitant:**
|
|
41
|
+
- "What would need to change for you to feel comfortable making an offer?"
|
|
42
|
+
- "Is it the property itself, or the timing?"
|
|
43
|
+
- "If this property sells to someone else this weekend, would you regret not having put an offer forward?"
|
|
44
|
+
|
|
45
|
+
**When a buyer lowballs:**
|
|
46
|
+
- Use comparable evidence: "Let me show you what similar properties have actually sold for recently"
|
|
47
|
+
- Frame as collaboration: "Let's find a number that the seller will take seriously, so we don't lose the opportunity to negotiate"
|
|
48
|
+
|
|
49
|
+
## Getting Buyers Off the Fence (Serhant)
|
|
50
|
+
|
|
51
|
+
- Show them what they think they want (validates their criteria)
|
|
52
|
+
- Show them the WOW listing (exceeds expectations, creates excitement)
|
|
53
|
+
- Show them the consolation prize (makes the WOW listing feel essential)
|
|
54
|
+
- This is about understanding their emotional journey, not manipulation
|
|
55
|
+
|
|
56
|
+
## The Flip: Turning Negatives Into Positives
|
|
57
|
+
|
|
58
|
+
When a buyer raises an objection about a property:
|
|
59
|
+
1. **List the common objections** you expect (small garden, busy road, dated kitchen)
|
|
60
|
+
2. **Find the silver lining** ("A contained garden is easy to maintain and beautify — you'll spend time enjoying it, not mowing")
|
|
61
|
+
3. **Offer a solution** (share photos of beautiful small gardens, connect with a landscaper)
|
|
62
|
+
|
|
63
|
+
Always acknowledge the concern genuinely before flipping it. Never dismiss a buyer's objection.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Working With Buyers — Scripts & Scenarios
|
|
2
|
+
*Adapted from Serhant Team Agent Training Guide*
|
|
3
|
+
|
|
4
|
+
## Phase 1: Selling Is ASKING
|
|
5
|
+
|
|
6
|
+
### Qualify First — Shoppers vs Buyers
|
|
7
|
+
You don't work with shoppers, you work with BUYERS. Determine if they're real:
|
|
8
|
+
|
|
9
|
+
**Qualifying Questions:**
|
|
10
|
+
1. "Where do you work?" (financial picture)
|
|
11
|
+
2. "Do you currently own or rent?" (experience level + chain status)
|
|
12
|
+
3. "When are you looking to move by? Is there a specific reason?" (urgency + motivation)
|
|
13
|
+
4. "How long have you been looking? Seen anything you liked?" (stage in journey)
|
|
14
|
+
5. "Have you already been pre-approved / spoken to a mortgage adviser?" (readiness)
|
|
15
|
+
|
|
16
|
+
### Never Meet a Buyer for the First Time at a Listing
|
|
17
|
+
Meet them first — in the office, for coffee, on a call. Understand their needs before showing properties.
|
|
18
|
+
|
|
19
|
+
### Set Expectations
|
|
20
|
+
List the steps to successfully purchasing a home. Buyers who understand the process make better decisions and don't panic at each stage.
|
|
21
|
+
|
|
22
|
+
## Phase 2: Selling Is GUIDING
|
|
23
|
+
|
|
24
|
+
### Elimination, Not Selection
|
|
25
|
+
"Buying a home isn't a process of selection — it's a process of elimination. We'll narrow down what works and what doesn't until we find the right one."
|
|
26
|
+
|
|
27
|
+
### Ask for Feedback After Every Viewing
|
|
28
|
+
Don't assume silence means disinterest. Start the conversation, get them in the game.
|
|
29
|
+
|
|
30
|
+
### Make Offers — Get Off the Fence
|
|
31
|
+
Buyers can look forever without a push. Address the hesitation:
|
|
32
|
+
|
|
33
|
+
"It's never a 'bad' time to buy. As long as you're comfortable with the purchase and don't overstretch yourself, you'll be in good shape."
|
|
34
|
+
|
|
35
|
+
"I've never had a client who, at completion, said 'I got exactly what I wanted under budget!' — there's always a stretch."
|
|
36
|
+
|
|
37
|
+
### Encouraging Offers
|
|
38
|
+
"An offer is JUST a conversation starter. Nothing is final until contracts are exchanged."
|
|
39
|
+
|
|
40
|
+
"What do you think the property is worth? What would you pay? ...[X]? Great — why don't we just see how the vendor responds?"
|
|
41
|
+
|
|
42
|
+
### Make Them Fall in Love with the PROPERTY, Not the Discount
|
|
43
|
+
Focus on lifestyle, not savings. "Can you see yourself here?" beats "You're getting £10k off."
|
|
44
|
+
|
|
45
|
+
## Getting Buyers Off the Fence
|
|
46
|
+
|
|
47
|
+
**Longer-Term Outlook:**
|
|
48
|
+
"Will you be there for 5-10 years? If so, waiting for the 'perfect' property is like not taking a holiday because it might rain."
|
|
49
|
+
|
|
50
|
+
**The Historical Perspective:**
|
|
51
|
+
"Every buyer thinks it's SO expensive at the time. Then they look back and think they got the best deal ever."
|
|
52
|
+
|
|
53
|
+
**The iPhone Analogy (for price objections):**
|
|
54
|
+
If a buyer won't pay because the vendor only paid £X before — "How much did you pay for your iPhone? It costs £84 to make."
|