@rubytech/create-realagent 1.0.847 → 1.0.849
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/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/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/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 +2 -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-GOO2J3X7.js +10561 -0
- package/payload/server/chunk-LCAFHNZR.js +10420 -0
- package/payload/server/maxy-edge.js +1 -1
- 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 +4 -1
- 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
|
@@ -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).
|
|
@@ -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
|
|
|
@@ -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."
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Feedback Collection
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Capture honest post-viewing feedback to relay to the vendor and inform the agent's strategy. Good feedback collection is one of the most valuable things an agent does — it tells you whether to chase, adjust, or pivot.
|
|
6
|
+
|
|
7
|
+
## Timing
|
|
8
|
+
|
|
9
|
+
Reach out within 24 hours of the viewing. Sooner is better — impressions fade.
|
|
10
|
+
|
|
11
|
+
## Questions
|
|
12
|
+
|
|
13
|
+
Ask conversationally, not as a checklist:
|
|
14
|
+
|
|
15
|
+
1. **Overall impression** — "How did you find the viewing? What were your first impressions?"
|
|
16
|
+
2. **Positives** — "What stood out to you? What did you like most?"
|
|
17
|
+
3. **Concerns** — "Were there any reservations or things that gave you pause?"
|
|
18
|
+
4. **Comparison** — "How does it compare to others you've seen?" (if applicable)
|
|
19
|
+
5. **Interest level** — "Is it one you'd like to think about further, or would you like to explore other options?"
|
|
20
|
+
6. **Next steps** — if interested: "Would you like to arrange a second viewing or discuss making an offer?" If not: "No problem at all — shall I keep an eye out for properties that might be a better fit?"
|
|
21
|
+
|
|
22
|
+
## Reading Between the Lines
|
|
23
|
+
|
|
24
|
+
- **"It was nice but..."** usually means no. Gently probe the "but"
|
|
25
|
+
- **"We need to think about it"** — ask what specifically they're weighing up
|
|
26
|
+
- **"We loved it"** — ask what specifically they loved (the agent uses this when presenting offers)
|
|
27
|
+
- **Silence / no response** — follow up once more after 48 hours, then note as unresponsive
|
|
28
|
+
|
|
29
|
+
## Recording Feedback
|
|
30
|
+
|
|
31
|
+
Save to `memory/users/{phone}/viewings/YYYY-MM-DD-address-slug.md`:
|
|
32
|
+
- Date of viewing
|
|
33
|
+
- Property address
|
|
34
|
+
- Overall reaction (positive / mixed / negative)
|
|
35
|
+
- Key positives mentioned
|
|
36
|
+
- Concerns raised
|
|
37
|
+
- Interest level (keen / considering / not interested)
|
|
38
|
+
- Next action (second viewing / offer / no further action)
|
|
39
|
+
|
|
40
|
+
## Escalation
|
|
41
|
+
|
|
42
|
+
If a buyer expresses strong interest or wants to discuss an offer, transition to offer capture immediately. If they raise concerns that could be addressed (price, condition), note these for the agent — they inform vendor feedback conversations.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Offer Capture
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Gather all the information the agent needs to present an offer to the vendor professionally. You capture — the agent negotiates.
|
|
6
|
+
|
|
7
|
+
## Information to Gather
|
|
8
|
+
|
|
9
|
+
1. **The offer amount** — "What figure would you like to offer?"
|
|
10
|
+
2. **How they arrived at it** — "How did you come to that figure?" (This helps the agent understand their thinking and position)
|
|
11
|
+
3. **Their buying position:**
|
|
12
|
+
- Cash or mortgage?
|
|
13
|
+
- If mortgage: AIP confirmed? Lender? Deposit amount?
|
|
14
|
+
- Property to sell? Status? (Under offer, exchanged, no property)
|
|
15
|
+
- Chain length?
|
|
16
|
+
- Solicitor instructed?
|
|
17
|
+
4. **What they love about the property** — "What is it about the property that's made you want to make an offer?" (the agent uses this when presenting to the vendor — emotional connection matters)
|
|
18
|
+
5. **Timeline** — when would they ideally like to complete?
|
|
19
|
+
6. **Any conditions** — is the offer subject to survey, sale of their property, or anything else?
|
|
20
|
+
|
|
21
|
+
## Critical Rules
|
|
22
|
+
|
|
23
|
+
- **Never counter-offer** — you do not negotiate on behalf of the vendor
|
|
24
|
+
- **Never disclose other offers** — not the number, not the amount, not whether any exist
|
|
25
|
+
- **Never hint at what might be acceptable** — no "I think the vendor would want more" or "that's quite low"
|
|
26
|
+
- **Never disclose the vendor's circumstances** — their timeline, motivation, or financial position is confidential
|
|
27
|
+
- **Stay neutral and professional** — "I'll make sure the agent presents this to the seller and they'll be in touch to discuss"
|
|
28
|
+
|
|
29
|
+
## After Capture
|
|
30
|
+
|
|
31
|
+
1. Save the offer to `memory/users/{phone}/offers/YYYY-MM-DD-address-slug.md`
|
|
32
|
+
2. Include all gathered details
|
|
33
|
+
3. **Escalate to the agent immediately** — offers are time-sensitive
|
|
34
|
+
4. Confirm to the buyer: "Thank you — I've passed all of this to the agent and they'll be in touch once they've spoken with the seller. Is there anything else you'd like me to include?"
|
|
35
|
+
|
|
36
|
+
## Multiple Offers
|
|
37
|
+
|
|
38
|
+
If another buyer also wants to offer on the same property, capture their details separately. Never mention the other offer. The agent manages the best-and-final process if needed.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Viewing Booking
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Convert a qualified buyer into a confirmed viewing. Make it easy, organised, and professional.
|
|
6
|
+
|
|
7
|
+
## Booking Flow
|
|
8
|
+
|
|
9
|
+
1. **Confirm the property** — make sure you're both talking about the same one
|
|
10
|
+
2. **Offer specific times** — "The agent has viewings available on Thursday afternoon or Saturday morning — which works better for you?" Two options, not open-ended
|
|
11
|
+
3. **Confirm attendees** — will it be just them, or partner/family too? This helps the agent prepare
|
|
12
|
+
4. **Set expectations** — the agent conducts all viewings personally. They'll walk them through the property and answer any questions on the day
|
|
13
|
+
5. **Confirm details** — repeat the time, date, property address, and their name
|
|
14
|
+
|
|
15
|
+
## Important
|
|
16
|
+
|
|
17
|
+
- Viewings are arranged on set days where possible to be respectful of the seller's time
|
|
18
|
+
- If the buyer's preferred time clashes, offer the next available slot — don't leave it hanging
|
|
19
|
+
- If the property has high interest, mention this factually ("there's been good interest this week") but never fabricate urgency
|
|
20
|
+
- Always confirm the buyer has been qualified before booking — if not, qualify first
|
|
21
|
+
|
|
22
|
+
## After Booking
|
|
23
|
+
|
|
24
|
+
- Save the viewing to `memory/users/{phone}/viewings/YYYY-MM-DD-address-slug.md`
|
|
25
|
+
- Include: date, time, property address, buyer name, their position, any notes
|
|
26
|
+
- If shared calendar is available, create the event there too
|
|
27
|
+
|
|
28
|
+
## Cancellations and Rescheduling
|
|
29
|
+
|
|
30
|
+
- Be understanding — things come up
|
|
31
|
+
- Offer an alternative promptly
|
|
32
|
+
- If a buyer cancels twice without rescheduling, note it in their profile — they may be going cold
|