@rubytech/create-maxy-code 0.1.61 → 0.1.63

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.
Files changed (148) hide show
  1. package/dist/__tests__/installer-specialist-registration.test.js +112 -0
  2. package/dist/index.js +22 -0
  3. package/dist/specialist-registration.js +78 -0
  4. package/package.json +1 -1
  5. package/payload/platform/plugins/admin/PLUGIN.md +22 -0
  6. package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +50 -13
  7. package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +22 -21
  8. package/payload/platform/plugins/contacts/PLUGIN.md +9 -0
  9. package/payload/platform/plugins/docs/references/admin-session.md +55 -7
  10. package/payload/platform/plugins/email/PLUGIN.md +9 -0
  11. package/payload/platform/plugins/epc/PLUGIN.md +5 -0
  12. package/payload/platform/plugins/loop/PLUGIN.md +27 -0
  13. package/payload/platform/plugins/memory/PLUGIN.md +37 -0
  14. package/payload/platform/plugins/memory/mcp/dist/index.js +3 -3
  15. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  16. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/live-schema-source.test.js +137 -75
  17. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/live-schema-source.test.js.map +1 -1
  18. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.d.ts +0 -17
  19. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.d.ts.map +1 -1
  20. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.js +32 -4
  21. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.js.map +1 -1
  22. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts +65 -0
  23. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts.map +1 -0
  24. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +182 -0
  25. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -0
  26. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js +8 -8
  27. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js.map +1 -1
  28. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.d.ts +2 -0
  29. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.d.ts.map +1 -0
  30. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js +241 -0
  31. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js.map +1 -0
  32. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts.map +1 -1
  33. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +9 -0
  34. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
  35. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.d.ts +1 -1
  36. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.d.ts.map +1 -1
  37. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.js +9 -1
  38. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.js.map +1 -1
  39. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.d.ts.map +1 -1
  40. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js +10 -2
  41. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js.map +1 -1
  42. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.d.ts +1 -1
  43. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.d.ts.map +1 -1
  44. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.js +5 -1
  45. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.js.map +1 -1
  46. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.d.ts +1 -1
  47. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.d.ts.map +1 -1
  48. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.js +5 -1
  49. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.js.map +1 -1
  50. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
  51. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +4 -0
  52. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
  53. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.d.ts.map +1 -1
  54. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js +4 -0
  55. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js.map +1 -1
  56. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.d.ts.map +1 -1
  57. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js +4 -0
  58. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js.map +1 -1
  59. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.d.ts.map +1 -1
  60. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.js +4 -0
  61. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.js.map +1 -1
  62. package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.d.ts.map +1 -1
  63. package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js +4 -0
  64. package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js.map +1 -1
  65. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.d.ts.map +1 -1
  66. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js +4 -0
  67. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js.map +1 -1
  68. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.d.ts.map +1 -1
  69. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.js +4 -0
  70. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.js.map +1 -1
  71. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
  72. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +5 -0
  73. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
  74. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.d.ts.map +1 -1
  75. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js +4 -0
  76. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js.map +1 -1
  77. package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.d.ts.map +1 -1
  78. package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.js +4 -0
  79. package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.js.map +1 -1
  80. package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.d.ts.map +1 -1
  81. package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.js +4 -0
  82. package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.js.map +1 -1
  83. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
  84. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +5 -0
  85. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
  86. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
  87. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +6 -0
  88. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
  89. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.d.ts.map +1 -1
  90. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js +4 -0
  91. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js.map +1 -1
  92. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
  93. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +4 -0
  94. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  95. package/payload/platform/plugins/memory/mcp/vitest.config.ts +10 -3
  96. package/payload/platform/plugins/outlook/PLUGIN.md +7 -0
  97. package/payload/platform/plugins/preval/.claude-plugin/plugin.json +1 -1
  98. package/payload/platform/plugins/preval/PLUGIN.md +22 -12
  99. package/payload/platform/plugins/preval/hooks/preval-prompt-required.sh +140 -0
  100. package/payload/platform/plugins/preval/skills/property-preval/SKILL.md +77 -19
  101. package/payload/platform/plugins/preval/skills/property-preval/references/__tests__/adherence.test.py +373 -0
  102. package/payload/platform/plugins/preval/skills/property-preval/references/render.py +390 -47
  103. package/payload/platform/plugins/preval/skills/property-preval/references/template-inputs.schema.json +32 -21
  104. package/payload/platform/plugins/preval/skills/property-preval/references/template.html +0 -1
  105. package/payload/platform/plugins/property-data/PLUGIN.md +22 -0
  106. package/payload/platform/plugins/replicate/PLUGIN.md +3 -0
  107. package/payload/platform/plugins/scheduling/PLUGIN.md +8 -0
  108. package/payload/platform/plugins/tasks/PLUGIN.md +14 -0
  109. package/payload/platform/plugins/telegram/PLUGIN.md +3 -0
  110. package/payload/platform/plugins/waitlist/PLUGIN.md +7 -0
  111. package/payload/platform/plugins/whatsapp/PLUGIN.md +12 -0
  112. package/payload/platform/plugins/workflows/PLUGIN.md +8 -0
  113. package/payload/platform/services/claude-session-manager/dist/index.js +39 -1
  114. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  115. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +21 -0
  116. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  117. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +148 -41
  118. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  119. package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts +23 -0
  120. package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts.map +1 -0
  121. package/payload/platform/services/claude-session-manager/dist/specialist-drift.js +141 -0
  122. package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -0
  123. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +13 -2
  124. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -1
  125. package/payload/platform/services/claude-session-manager/dist/tool-surface.js +135 -37
  126. package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
  127. package/payload/premium-plugins/real-agent/agents/compliance.md +1 -1
  128. package/payload/premium-plugins/real-agent/plugins/epc/PLUGIN.md +5 -0
  129. package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +27 -0
  130. package/payload/premium-plugins/real-agent/plugins/preval/.claude-plugin/plugin.json +1 -1
  131. package/payload/premium-plugins/real-agent/plugins/preval/PLUGIN.md +22 -12
  132. package/payload/premium-plugins/real-agent/plugins/preval/hooks/preval-prompt-required.sh +140 -0
  133. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/SKILL.md +77 -19
  134. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/__tests__/adherence.test.py +373 -0
  135. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/render.py +390 -47
  136. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/template-inputs.schema.json +32 -21
  137. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/template.html +0 -1
  138. package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +22 -0
  139. package/payload/server/public/assets/{admin-DhN3G8W7.js → admin-ymReS1mN.js} +1 -1
  140. package/payload/server/public/assets/{data-B2ZVXOcE.js → data-D6U2e85B.js} +1 -1
  141. package/payload/server/public/assets/{graph-BAMGPHrK.js → graph-C274PN27.js} +1 -1
  142. package/payload/server/public/assets/{graph-labels-D9eBbvxo.js → graph-labels-DQFzd1FY.js} +1 -1
  143. package/payload/server/public/assets/{page-DjdVMWCz.js → page-D-OLjort.js} +1 -1
  144. package/payload/server/public/assets/{page-CV27Al6Z.js → page-DFFt9_Q0.js} +1 -1
  145. package/payload/server/public/data.html +3 -3
  146. package/payload/server/public/graph.html +3 -3
  147. package/payload/server/public/index.html +4 -4
  148. package/payload/server/server.js +1 -1
@@ -1,6 +1,10 @@
1
1
  import { getSession } from "../lib/neo4j.js";
2
2
  import { trashNode } from "../../../../../lib/graph-trash/dist/index.js";
3
+ import { withWriteEvent } from "../lib/log-ingest.js";
3
4
  export async function profileDelete(params) {
5
+ return withWriteEvent({ tool: "profile-delete", accountId: params.accountId, labels: ["Preference"], name: `${params.category}.${params.key}` }, () => profileDeleteImpl(params));
6
+ }
7
+ async function profileDeleteImpl(params) {
4
8
  const { accountId, userId, category, key } = params;
5
9
  const session = getSession();
6
10
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"profile-delete.js","sourceRoot":"","sources":["../../src/tools/profile-delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AA0BzE,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B;IAE3B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IAEpD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B;;6CAEuC,EACvC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CACrC,CAAC;QAEF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAClE,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAW,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;YAC7B,OAAO;YACP,SAAS;YACT,SAAS,EAAE,GAAG;YACd,EAAE,EAAE,gBAAgB;SACrB,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,QAAQ;YACR,GAAG;SACJ,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"profile-delete.js","sourceRoot":"","sources":["../../src/tools/profile-delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA0BtD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B;IAE3B,OAAO,cAAc,CACnB,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,GAAG,EAAE,EAAE,EACzH,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAChC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,MAA2B;IAE3B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IAEpD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B;;6CAEuC,EACvC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CACrC,CAAC;QAEF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAClE,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAW,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;YAC7B,OAAO;YACP,SAAS;YACT,SAAS,EAAE,GAAG;YACd,EAAE,EAAE,gBAAgB;SACrB,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,QAAQ;YACR,GAAG;SACJ,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"profile-update.d.ts","sourceRoot":"","sources":["../../src/tools/profile-update.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAiD9E,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,UAAU,GAAG,aAAa,CAAC;IACpC,IAAI,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC;;;;;;;;;;;;;;;;;OAiBG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC;CAC1B;AAED,UAAU,mBAAmB;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,cAAc,GAAG,QAAQ,CAAC;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAkV9B"}
1
+ {"version":3,"file":"profile-update.d.ts","sourceRoot":"","sources":["../../src/tools/profile-update.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAkD9E,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,UAAU,GAAG,aAAa,CAAC;IACpC,IAAI,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC;;;;;;;;;;;;;;;;;OAiBG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC;CAC1B;AAED,UAAU,mBAAmB;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,cAAc,GAAG,QAAQ,CAAC;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAM9B"}
@@ -4,6 +4,7 @@ import { randomUUID } from "node:crypto";
4
4
  import { notTrashed } from "../../../../../lib/graph-trash/dist/index.js";
5
5
  import { validateWrite } from "../lib/schema-validator.js";
6
6
  import { loadEnabledPluginProfileKeys } from "./profile-read.js";
7
+ import { withWriteEvent } from "../lib/log-ingest.js";
7
8
  // Cross-process agreement: these values must match neo4j-store.ts
8
9
  const INITIAL_CONFIDENCE = 0.5;
9
10
  const REINFORCEMENT_INCREMENT = 0.15;
@@ -47,6 +48,9 @@ const PERSON_SYSTEM_MANAGED_PROPS = new Set([
47
48
  "createdBySession",
48
49
  ]);
49
50
  export async function profileUpdate(params) {
51
+ return withWriteEvent({ tool: "profile-update", accountId: params.accountId, labels: ["Preference"], name: `${params.category}.${params.key}` }, () => profileUpdateImpl(params), (r) => ({ elementId: r.preferenceId }));
52
+ }
53
+ async function profileUpdateImpl(params) {
50
54
  const { accountId, userId, category, key, value, source = "behavioural", mode = "reinforce", conversationId, profileFields, personFields, mergeSourceIds, notApplicable = false, validator, } = params;
51
55
  const validCategories = validCategoriesFor(accountId);
52
56
  if (!validCategories.has(category)) {
@@ -1 +1 @@
1
- {"version":3,"file":"profile-update.js","sourceRoot":"","sources":["../../src/tools/profile-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAqB,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEjE,kEAAkE;AAClE,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,uBAAuB,GAAG,IAAI,CAAC;AACrC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAEpC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,eAAe;IACf,YAAY;IACZ,UAAU;IACV,UAAU;IACV,SAAS;IACT,aAAa;CACd,CAAC,CAAC;AAEH,mEAAmE;AACnE,4EAA4E;AAC5E,uEAAuE;AACvE,mEAAmE;AACnE,SAAS,kBAAkB,CAAC,SAAiB;IAC3C,MAAM,KAAK,GAAG,4BAA4B,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC7C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5E,+DAA+D;AAC/D,oEAAoE;AACpE,sEAAsE;AACtE,uEAAuE;AACvE,kEAAkE;AAClE,uEAAuE;AACvE,yEAAyE;AACzE,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC;IAC1C,WAAW;IACX,QAAQ;IACR,OAAO;IACP,WAAW;IACX,WAAW;IACX,WAAW;IACX,gBAAgB;IAChB,eAAe;IACf,kBAAkB;CACnB,CAAC,CAAC;AAiEH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B;IAE3B,MAAM,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,EACR,GAAG,EACH,KAAK,EACL,MAAM,GAAG,aAAa,EACtB,IAAI,GAAG,WAAW,EAClB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,EACd,aAAa,GAAG,KAAK,EACrB,SAAS,GACV,GAAG,MAAM,CAAC;IAEX,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,qBAAqB,QAAQ,sBAAsB,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,sBAAsB,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACzE,CAAC;IACJ,CAAC;IAED,8DAA8D;IAC9D,sEAAsE;IACtE,yEAAyE;IACzE,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,8HAA8H,CAC/H,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,yDAAyD,IAAI,wEAAwE,CACtI,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,6DAA6D;IAC7D,oEAAoE;IACpE,wEAAwE;IACxE,gEAAgE;IAChE,EAAE;IACF,yCAAyC;IACzC,2EAA2E;IAC3E,qEAAqE;IACrE,sEAAsE;IACtE,oEAAoE;IACpE,+DAA+D;IAC/D,mEAAmE;IACnE,6BAA6B;IAC7B,IAAI,gBAAgB,GAAmC,IAAI,CAAC;IAC5D,IAAI,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;gBAAE,SAAS;YAC5C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAC7D,IAAI,2BAA2B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CACb,iCAAiC,CAAC,iLAAiL,CACpN,CAAC;YACJ,CAAC;YACD,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACb,yIAAyI,CAC1I,CAAC;YACJ,CAAC;YACD,+DAA+D;YAC/D,aAAa,CACX,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,EACvD,SAAS,EACT,EAAE,IAAI,EAAE,QAAQ,EAAE,CACnB,CAAC;YACF,gBAAgB,GAAG,QAAQ,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,wDAAwD;QACxD,MAAM,aAAa,GAAG,GAAG,QAAQ,KAAK,GAAG,MAAM,KAAK,EAAE,CAAC;QACvD,IAAI,SAAS,GAAoB,IAAI,CAAC;QACtC,IAAI,CAAC;YACH,SAAS,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,+DAA+D;YAC/D,0DAA0D;QAC5D,CAAC;QAED,kDAAkD;QAClD,IAAI,aAAa,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;gBACzB,WAAW;gBACX,QAAQ;gBACR,WAAW;gBACX,WAAW;gBACX,gBAAgB;aACjB,CAAC,CAAC;YACH,MAAM,UAAU,GAA4B,EAAE,CAAC;YAC/C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC5C,CAAC;YAED,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,MAAM,OAAO,CAAC,GAAG,CACf;;;WAGC,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,CAC/C,CAAC;YACJ,CAAC;QACH,CAAC;QAED,2DAA2D;QAC3D,uDAAuD;QACvD,+DAA+D;QAC/D,sEAAsE;QACtE,kEAAkE;QAClE,mEAAmE;QACnE,mEAAmE;QACnE,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC;;;;SAIC,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,CACrD,CAAC;YACF,MAAM,QAAQ,GAAI,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAsD,CAAC;YAChH,MAAM,SAAS,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;YAC1F,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CACb,2EAA2E,MAAM,cAAc,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,SAAS,8IAA8I,CAC3R,CAAC;YACJ,CAAC;YACD,mEAAmE;YACnE,gDAAgD;YAChD,qDAAqD;YACrD,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0CAA0C,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,SAAS,IAAI,CACxF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,6DAA6D;QAC7D,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,OAAO,MAAM,YAAY,CACvB,OAAO,EACP,SAAS,EACT,MAAM,EACN,QAAQ,EACR,GAAG,EACH,KAAK,EACL,MAAM,EACN,SAAS,EACT,cAAe,EACf,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,oEAAoE;QACpE,yEAAyE;QACzE,uEAAuE;QACvE,sEAAsE;QACtE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CACtC;;cAEQ,UAAU,CAAC,MAAM,CAAC;;OAEzB,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CACrC,CAAC;QAEF,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,mCAAmC;YACnC,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAW,CAAC;YAC3E,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAW,CAAC;YAEjF,IAAI,aAAqB,CAAC;YAC1B,IAAI,MAAiD,CAAC;YAEtD,4DAA4D;YAC5D,mEAAmE;YACnE,mEAAmE;YACnE,kEAAkE;YAClE,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC3B,aAAa,GAAG,GAAG,CAAC;gBACpB,MAAM,GAAG,SAAS,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,QAAQ,IAAI,EAAE,CAAC;oBACb,KAAK,WAAW;wBACd,6DAA6D;wBAC7D,aAAa,GAAG,IAAI,CAAC,GAAG,CACtB,GAAG,EACH,kBAAkB,GAAG,uBAAuB,GAAG,CAAC,GAAG,GAAG,kBAAkB,CAAC,CAC1E,CAAC;wBACF,MAAM,GAAG,YAAY,CAAC;wBACtB,MAAM;oBACR,KAAK,QAAQ;wBACX,aAAa,GAAG,kBAAkB,CAAC;wBACnC,MAAM,GAAG,SAAS,CAAC;wBACnB,MAAM;oBACR,KAAK,YAAY;wBACf,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,GAAG,uBAAuB,CAAC,CAAC;wBAC5E,MAAM,GAAG,cAAc,CAAC;wBACxB,MAAM;oBACR;wBACE,aAAa,GAAG,kBAAkB,CAAC;wBACnC,MAAM,GAAG,SAAS,CAAC;gBACvB,CAAC;YACH,CAAC;YAED,MAAM,UAAU,GAAG,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;YACvD,MAAM,WAAW,GAA4B;gBAC3C,SAAS;gBACT,YAAY,EAAE,UAAU;gBACxB,KAAK,EAAE,UAAU;gBACjB,MAAM;gBACN,UAAU,EAAE,aAAa;gBACzB,UAAU,EAAE,GAAG;gBACf,SAAS,EAAE,GAAG;gBACd,aAAa,EAAE,aAAa,KAAK,IAAI;aACtC,CAAC;YACF,IAAI,SAAS,IAAI,aAAa,KAAK,IAAI;gBAAE,WAAW,CAAC,SAAS,GAAG,SAAS,CAAC;YAE3E,MAAM,OAAO,CAAC,GAAG,CACf;;;;;;;;cAQM,SAAS,IAAI,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,EAAE;SAC/E,EACD,WAAW,CACZ,CAAC;YAEF,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sCAAsC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,MAAM,UAAU,QAAQ,IAAI,GAAG,IAAI,CAC3G,CAAC;YACJ,CAAC;YAED,+CAA+C;YAC/C,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,OAAO,CAAC,GAAG,CACf;;;;WAIC,EACD,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,CAC7C,CAAC;YACJ,CAAC;YAED,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;QACzE,CAAC;QAED,uDAAuD;QACvD,4DAA4D;QAC5D,uDAAuD;QACvD,MAAM,YAAY,GAAG,UAAU,EAAE,CAAC;QAClC,MAAM,WAAW,GAA4B;YAC3C,YAAY;YACZ,SAAS;YACT,MAAM;YACN,QAAQ;YACR,GAAG;YACH,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;YAC1C,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,kBAAkB;YAC7D,MAAM;YACN,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;YACd,KAAK,EAAE,OAAO;YACd,aAAa,EAAE,aAAa,KAAK,IAAI;SACtC,CAAC;QACF,IAAI,SAAS,IAAI,aAAa,KAAK,IAAI;YAAE,WAAW,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3E,MAAM,OAAO,CAAC,GAAG,CACf;;;;OAIC,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,CAC1C,CAAC;QAEF,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sCAAsC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,MAAM,UAAU,QAAQ,IAAI,GAAG,IAAI,CAC3G,CAAC;QACJ,CAAC;QAED,+CAA+C;QAC/C,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,OAAO,CAAC,GAAG,CACf;;;;SAIC,EACD,EAAE,YAAY,EAAE,cAAc,EAAE,CACjC,CAAC;QACJ,CAAC;QAED,OAAO;YACL,YAAY;YACZ,MAAM,EAAE,SAAS;YACjB,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,kBAAkB;SAC9D,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,OAAsC,EACtC,SAAiB,EACjB,MAAc,EACd,QAAgB,EAChB,GAAW,EACX,KAAa,EACb,MAAc,EACd,SAA0B,EAC1B,cAAwB,EACxB,GAAW;IAEX,MAAM,GAAG,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAEvC,IAAI,CAAC;QACH,qEAAqE;QACrE,0EAA0E;QAC1E,yEAAyE;QACzE,oEAAoE;QACpE,uEAAuE;QACvE,6CAA6C;QAC7C,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,GAAG,CACjC;;kFAE4E,UAAU,CAAC,MAAM,CAAC;wEAC5B,UAAU,CAAC,MAAM,CAAC;;;OAGnF,EACD,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,CACzC,CAAC;QAEF,IAAI,aAAa,CAAC,OAAO,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM,EAAE,CAAC;YAC3D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAW,CAAC,CAAC,CAAC;YAClF,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACjE,MAAM,IAAI,KAAK,CACb,iBAAiB,OAAO,CAAC,MAAM,OAAO,cAAc,CAAC,MAAM,qGAAqG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrL,CAAC;QACJ,CAAC;QAED,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAChD,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAW,CAAC,EACxD,kBAAkB,CACnB,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,KAAK,MAAM,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YACtC,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAa,EAAE,CAAC;gBAC9C,IAAI,EAAE;oBAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,MAAM,YAAY,GAAG,UAAU,EAAE,CAAC;QAClC,MAAM,WAAW,GAA4B;YAC3C,YAAY;YACZ,SAAS;YACT,MAAM;YACN,QAAQ;YACR,GAAG;YACH,KAAK;YACL,UAAU,EAAE,aAAa;YACzB,MAAM;YACN,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;YACd,KAAK,EAAE,OAAO;SACf,CAAC;QACF,IAAI,SAAS;YAAE,WAAW,CAAC,SAAS,GAAG,SAAS,CAAC;QAEjD,MAAM,GAAG,CAAC,GAAG,CACX;;;;OAIC,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,CAC1C,CAAC;QAEF,mDAAmD;QACnD,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,GAAG,CAAC,GAAG,CACX;;;;SAIC,EACD,EAAE,YAAY,EAAE,MAAM,EAAE,CACzB,CAAC;QACJ,CAAC;QAED,mEAAmE;QACnE,yDAAyD;QACzD,mEAAmE;QACnE,qEAAqE;QACrE,mDAAmD;QACnD,MAAM,GAAG,CAAC,GAAG,CACX;;;;OAIC,EACD,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,CACzC,CAAC;QAEF,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;QAEnB,OAAO;YACL,YAAY;YACZ,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,aAAa;YACzB,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC,MAAM;SAC1C,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"profile-update.js","sourceRoot":"","sources":["../../src/tools/profile-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAqB,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,kEAAkE;AAClE,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,uBAAuB,GAAG,IAAI,CAAC;AACrC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAEpC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,eAAe;IACf,YAAY;IACZ,UAAU;IACV,UAAU;IACV,SAAS;IACT,aAAa;CACd,CAAC,CAAC;AAEH,mEAAmE;AACnE,4EAA4E;AAC5E,uEAAuE;AACvE,mEAAmE;AACnE,SAAS,kBAAkB,CAAC,SAAiB;IAC3C,MAAM,KAAK,GAAG,4BAA4B,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC7C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5E,+DAA+D;AAC/D,oEAAoE;AACpE,sEAAsE;AACtE,uEAAuE;AACvE,kEAAkE;AAClE,uEAAuE;AACvE,yEAAyE;AACzE,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC;IAC1C,WAAW;IACX,QAAQ;IACR,OAAO;IACP,WAAW;IACX,WAAW;IACX,WAAW;IACX,gBAAgB;IAChB,eAAe;IACf,kBAAkB;CACnB,CAAC,CAAC;AAiEH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B;IAE3B,OAAO,cAAc,CACnB,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,GAAG,EAAE,EAAE,EACzH,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAC/B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CACvC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,MAA2B;IAE3B,MAAM,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,EACR,GAAG,EACH,KAAK,EACL,MAAM,GAAG,aAAa,EACtB,IAAI,GAAG,WAAW,EAClB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,EACd,aAAa,GAAG,KAAK,EACrB,SAAS,GACV,GAAG,MAAM,CAAC;IAEX,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,qBAAqB,QAAQ,sBAAsB,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,sBAAsB,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACzE,CAAC;IACJ,CAAC;IAED,8DAA8D;IAC9D,sEAAsE;IACtE,yEAAyE;IACzE,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,8HAA8H,CAC/H,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,yDAAyD,IAAI,wEAAwE,CACtI,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,6DAA6D;IAC7D,oEAAoE;IACpE,wEAAwE;IACxE,gEAAgE;IAChE,EAAE;IACF,yCAAyC;IACzC,2EAA2E;IAC3E,qEAAqE;IACrE,sEAAsE;IACtE,oEAAoE;IACpE,+DAA+D;IAC/D,mEAAmE;IACnE,6BAA6B;IAC7B,IAAI,gBAAgB,GAAmC,IAAI,CAAC;IAC5D,IAAI,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;gBAAE,SAAS;YAC5C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAC7D,IAAI,2BAA2B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CACb,iCAAiC,CAAC,iLAAiL,CACpN,CAAC;YACJ,CAAC;YACD,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACb,yIAAyI,CAC1I,CAAC;YACJ,CAAC;YACD,+DAA+D;YAC/D,aAAa,CACX,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,EACvD,SAAS,EACT,EAAE,IAAI,EAAE,QAAQ,EAAE,CACnB,CAAC;YACF,gBAAgB,GAAG,QAAQ,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,wDAAwD;QACxD,MAAM,aAAa,GAAG,GAAG,QAAQ,KAAK,GAAG,MAAM,KAAK,EAAE,CAAC;QACvD,IAAI,SAAS,GAAoB,IAAI,CAAC;QACtC,IAAI,CAAC;YACH,SAAS,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,+DAA+D;YAC/D,0DAA0D;QAC5D,CAAC;QAED,kDAAkD;QAClD,IAAI,aAAa,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;gBACzB,WAAW;gBACX,QAAQ;gBACR,WAAW;gBACX,WAAW;gBACX,gBAAgB;aACjB,CAAC,CAAC;YACH,MAAM,UAAU,GAA4B,EAAE,CAAC;YAC/C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC5C,CAAC;YAED,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,MAAM,OAAO,CAAC,GAAG,CACf;;;WAGC,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,CAC/C,CAAC;YACJ,CAAC;QACH,CAAC;QAED,2DAA2D;QAC3D,uDAAuD;QACvD,+DAA+D;QAC/D,sEAAsE;QACtE,kEAAkE;QAClE,mEAAmE;QACnE,mEAAmE;QACnE,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC;;;;SAIC,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,CACrD,CAAC;YACF,MAAM,QAAQ,GAAI,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAsD,CAAC;YAChH,MAAM,SAAS,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;YAC1F,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CACb,2EAA2E,MAAM,cAAc,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,SAAS,8IAA8I,CAC3R,CAAC;YACJ,CAAC;YACD,mEAAmE;YACnE,gDAAgD;YAChD,qDAAqD;YACrD,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0CAA0C,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,SAAS,IAAI,CACxF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,6DAA6D;QAC7D,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,OAAO,MAAM,YAAY,CACvB,OAAO,EACP,SAAS,EACT,MAAM,EACN,QAAQ,EACR,GAAG,EACH,KAAK,EACL,MAAM,EACN,SAAS,EACT,cAAe,EACf,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,oEAAoE;QACpE,yEAAyE;QACzE,uEAAuE;QACvE,sEAAsE;QACtE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CACtC;;cAEQ,UAAU,CAAC,MAAM,CAAC;;OAEzB,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CACrC,CAAC;QAEF,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,mCAAmC;YACnC,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAW,CAAC;YAC3E,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAW,CAAC;YAEjF,IAAI,aAAqB,CAAC;YAC1B,IAAI,MAAiD,CAAC;YAEtD,4DAA4D;YAC5D,mEAAmE;YACnE,mEAAmE;YACnE,kEAAkE;YAClE,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC3B,aAAa,GAAG,GAAG,CAAC;gBACpB,MAAM,GAAG,SAAS,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,QAAQ,IAAI,EAAE,CAAC;oBACb,KAAK,WAAW;wBACd,6DAA6D;wBAC7D,aAAa,GAAG,IAAI,CAAC,GAAG,CACtB,GAAG,EACH,kBAAkB,GAAG,uBAAuB,GAAG,CAAC,GAAG,GAAG,kBAAkB,CAAC,CAC1E,CAAC;wBACF,MAAM,GAAG,YAAY,CAAC;wBACtB,MAAM;oBACR,KAAK,QAAQ;wBACX,aAAa,GAAG,kBAAkB,CAAC;wBACnC,MAAM,GAAG,SAAS,CAAC;wBACnB,MAAM;oBACR,KAAK,YAAY;wBACf,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,GAAG,uBAAuB,CAAC,CAAC;wBAC5E,MAAM,GAAG,cAAc,CAAC;wBACxB,MAAM;oBACR;wBACE,aAAa,GAAG,kBAAkB,CAAC;wBACnC,MAAM,GAAG,SAAS,CAAC;gBACvB,CAAC;YACH,CAAC;YAED,MAAM,UAAU,GAAG,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;YACvD,MAAM,WAAW,GAA4B;gBAC3C,SAAS;gBACT,YAAY,EAAE,UAAU;gBACxB,KAAK,EAAE,UAAU;gBACjB,MAAM;gBACN,UAAU,EAAE,aAAa;gBACzB,UAAU,EAAE,GAAG;gBACf,SAAS,EAAE,GAAG;gBACd,aAAa,EAAE,aAAa,KAAK,IAAI;aACtC,CAAC;YACF,IAAI,SAAS,IAAI,aAAa,KAAK,IAAI;gBAAE,WAAW,CAAC,SAAS,GAAG,SAAS,CAAC;YAE3E,MAAM,OAAO,CAAC,GAAG,CACf;;;;;;;;cAQM,SAAS,IAAI,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,EAAE;SAC/E,EACD,WAAW,CACZ,CAAC;YAEF,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sCAAsC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,MAAM,UAAU,QAAQ,IAAI,GAAG,IAAI,CAC3G,CAAC;YACJ,CAAC;YAED,+CAA+C;YAC/C,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,OAAO,CAAC,GAAG,CACf;;;;WAIC,EACD,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,CAC7C,CAAC;YACJ,CAAC;YAED,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;QACzE,CAAC;QAED,uDAAuD;QACvD,4DAA4D;QAC5D,uDAAuD;QACvD,MAAM,YAAY,GAAG,UAAU,EAAE,CAAC;QAClC,MAAM,WAAW,GAA4B;YAC3C,YAAY;YACZ,SAAS;YACT,MAAM;YACN,QAAQ;YACR,GAAG;YACH,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;YAC1C,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,kBAAkB;YAC7D,MAAM;YACN,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;YACd,KAAK,EAAE,OAAO;YACd,aAAa,EAAE,aAAa,KAAK,IAAI;SACtC,CAAC;QACF,IAAI,SAAS,IAAI,aAAa,KAAK,IAAI;YAAE,WAAW,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3E,MAAM,OAAO,CAAC,GAAG,CACf;;;;OAIC,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,CAC1C,CAAC;QAEF,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sCAAsC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,MAAM,UAAU,QAAQ,IAAI,GAAG,IAAI,CAC3G,CAAC;QACJ,CAAC;QAED,+CAA+C;QAC/C,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,OAAO,CAAC,GAAG,CACf;;;;SAIC,EACD,EAAE,YAAY,EAAE,cAAc,EAAE,CACjC,CAAC;QACJ,CAAC;QAED,OAAO;YACL,YAAY;YACZ,MAAM,EAAE,SAAS;YACjB,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,kBAAkB;SAC9D,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,OAAsC,EACtC,SAAiB,EACjB,MAAc,EACd,QAAgB,EAChB,GAAW,EACX,KAAa,EACb,MAAc,EACd,SAA0B,EAC1B,cAAwB,EACxB,GAAW;IAEX,MAAM,GAAG,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAEvC,IAAI,CAAC;QACH,qEAAqE;QACrE,0EAA0E;QAC1E,yEAAyE;QACzE,oEAAoE;QACpE,uEAAuE;QACvE,6CAA6C;QAC7C,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,GAAG,CACjC;;kFAE4E,UAAU,CAAC,MAAM,CAAC;wEAC5B,UAAU,CAAC,MAAM,CAAC;;;OAGnF,EACD,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,CACzC,CAAC;QAEF,IAAI,aAAa,CAAC,OAAO,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM,EAAE,CAAC;YAC3D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAW,CAAC,CAAC,CAAC;YAClF,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACjE,MAAM,IAAI,KAAK,CACb,iBAAiB,OAAO,CAAC,MAAM,OAAO,cAAc,CAAC,MAAM,qGAAqG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrL,CAAC;QACJ,CAAC;QAED,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAChD,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAW,CAAC,EACxD,kBAAkB,CACnB,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,KAAK,MAAM,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YACtC,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAa,EAAE,CAAC;gBAC9C,IAAI,EAAE;oBAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,MAAM,YAAY,GAAG,UAAU,EAAE,CAAC;QAClC,MAAM,WAAW,GAA4B;YAC3C,YAAY;YACZ,SAAS;YACT,MAAM;YACN,QAAQ;YACR,GAAG;YACH,KAAK;YACL,UAAU,EAAE,aAAa;YACzB,MAAM;YACN,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;YACd,KAAK,EAAE,OAAO;SACf,CAAC;QACF,IAAI,SAAS;YAAE,WAAW,CAAC,SAAS,GAAG,SAAS,CAAC;QAEjD,MAAM,GAAG,CAAC,GAAG,CACX;;;;OAIC,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,CAC1C,CAAC;QAEF,mDAAmD;QACnD,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,GAAG,CAAC,GAAG,CACX;;;;SAIC,EACD,EAAE,YAAY,EAAE,MAAM,EAAE,CACzB,CAAC;QACJ,CAAC;QAED,mEAAmE;QACnE,yDAAyD;QACzD,mEAAmE;QACnE,qEAAqE;QACrE,mDAAmD;QACnD,MAAM,GAAG,CAAC,GAAG,CACX;;;;OAIC,EACD,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,CACzC,CAAC;QAEF,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;QAEnB,OAAO;YACL,YAAY;YACZ,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,aAAa;YACzB,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC,MAAM;SAC1C,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -5,11 +5,18 @@ export default defineConfig({
5
5
  environment: "node",
6
6
  // narrow to `src/tools/__tests__/` so vitest does not pick up
7
7
  // pre-existing `src/lib/__tests__/` files that use Node's built-in
8
- // `node:test` runner (schema-loader / schema-validator / live-schema-source
8
+ // `node:test` runner (schema-loader / schema-validator / llm-classifier
9
9
  // tests). Those files run under their own harness; broadening
10
10
  // this glob to `src/**/__tests__/**` would surface them as parse failures
11
- // here without porting them — out of scope for this task.
12
- include: ["src/tools/__tests__/**/*.test.ts"],
11
+ // here without porting them.
12
+ //
13
+ // `live-schema-source.test.ts` is whitelisted explicitly because Task 167
14
+ // ported it to vitest (drift-summary surface change). The other lib
15
+ // tests stay node:test.
16
+ include: [
17
+ "src/tools/__tests__/**/*.test.ts",
18
+ "src/lib/__tests__/live-schema-source.test.ts",
19
+ ],
13
20
  testTimeout: 10_000,
14
21
  },
15
22
  });
@@ -4,18 +4,25 @@ description: Microsoft 365 / Outlook.com via Microsoft Graph (read-only first cu
4
4
  tools:
5
5
  - name: outlook-account-register
6
6
  publicAllowlist: false
7
+ adminAllowlist: false
7
8
  - name: outlook-mail-list
8
9
  publicAllowlist: false
10
+ adminAllowlist: false
9
11
  - name: outlook-mail-search
10
12
  publicAllowlist: false
13
+ adminAllowlist: false
11
14
  - name: outlook-calendar-list
12
15
  publicAllowlist: false
16
+ adminAllowlist: false
13
17
  - name: outlook-calendar-event
14
18
  publicAllowlist: false
19
+ adminAllowlist: false
15
20
  - name: outlook-contacts-list
16
21
  publicAllowlist: false
22
+ adminAllowlist: false
17
23
  - name: outlook-mailbox-info
18
24
  publicAllowlist: false
25
+ adminAllowlist: false
19
26
  always: false
20
27
  embed: ["admin"]
21
28
  metadata: {"platform":{"optional":true}}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "real-agent-preval",
3
- "description": "Single-address pre-valuation pitch pack. One full UK address in, 5-page A4 PDF out (cover · subject valuation · market context · comparables · recently with <brand>). Consumes the real-agent-property-data and real-agent-epc MCPs — no MCP tools of its own.",
3
+ "description": "Single-address pre-valuation pitch pack. One full UK address in, 5-page A4 PDF out (cover · subject valuation · market context · comparables · recently with <brand>). Consumes the real-agent-property-data MCP — no MCP tools of its own. EPC certificate fields (total_floor_area_m2, current_energy_rating, lodgement_date) are pasted by the operator into inputs.json before invocation.",
4
4
  "version": "0.1.0",
5
5
  "author": {
6
6
  "name": "Rubytech LLC"
@@ -1,8 +1,12 @@
1
1
  ---
2
2
  name: real-agent-preval
3
- description: "Single-address pre-valuation pitch pack. One full UK address in, 5-page A4 PDF out (cover · subject valuation · market context · comparables · recently with <brand>). Consumes the real-agent-property-data and real-agent-epc MCPs — no MCP tools of its own."
3
+ description: "Single-address pre-valuation pitch pack. One full UK address in, 5-page A4 PDF out (cover · subject valuation · market context · comparables · recently with <brand>). Consumes the real-agent-property-data MCP — no MCP tools of its own. EPC certificate fields (total_floor_area_m2, current_energy_rating, lodgement_date) are pasted by the operator into inputs.json before invocation."
4
4
  skills:
5
5
  - skills/property-preval/SKILL.md
6
+ hooks:
7
+ PreToolUse:
8
+ - matcher: "Write|Edit|MultiEdit"
9
+ command: "${CLAUDE_PLUGIN_ROOT}/hooks/preval-prompt-required.sh"
6
10
  always: false
7
11
  metadata: {"platform":{"optional":true,"embed":["admin"]}}
8
12
  ---
@@ -16,30 +20,36 @@ Consumer sub-plugin. No MCP server, no new tools — only a skill (`property-pre
16
20
  A 5-page A4 PDF and the source HTML, written to `~/Documents/Maxy/preval/<postcode-compact>-<YYYY-MM-DD>/`:
17
21
 
18
22
  - **Page 1 — Cover.** Full-bleed subject hero photo with gradient scrim. Light brand wordmark top-left. Address in display-italic. Postcode chip. Four-up meta strip (Report · Address · Postcode · Generated). Lifted from the `property-market-report` cover contract.
19
- - **Page 2 — Subject valuation.** KPI strip (floor area, bedrooms, EPC rating, type). Valuation panel: headline range = `subject.sqft × sold £/sqft 70pc band` (Land Registry), asking £/sqft cross-check, operator adjustments (`subject.adjustments[]`) shown as a stacked list with colour-coded percentages, final indicative range pill. Falls back to "Estimate requires floor area" benchmark-only mode when sqft is missing.
23
+ - **Page 2 — Subject valuation.** KPI strip (floor area, bedrooms, EPC rating, type). Valuation panel: headline range = `derived sqft × sold £/sqft 70pc band` (Land Registry), asking £/sqft cross-check, operator adjustments (`subject.adjustments[]`) shown as a stacked list with colour-coded percentages, final indicative range pill. Floor area is derived from `subject.total_floor_area_m2` (operator-pasted from the EPC certificate) — a null value aborts the run with `epc-certificate-not-supplied`.
20
24
  - **Page 3 — Market context.** Market summary headline + paragraphs with drop cap. KPI strip (avg asking £, avg sold £, £/sqft). Price-growth panel (YoY) + demand pill with gauge. 7-year sparkline of £ and £/sqft. Same patterns as `property-market-report`.
21
25
  - **Page 4 — Comparables.** Full-width Land Registry sold-transactions table (≤ 6 rows), stacked above a full-width live-asking-comparables tile grid (≤ 4 tiles). Never side-by-side — corrects the cramped two-column layout in v1 preval.
22
26
  - **Page 5 — Recently with `<brand>` + sources.** Operator-curated `agent_listings[]` rendered as a clickable tile grid with status badges (Sold / Under offer / For sale), then the sources & methodology block. The vendor reads this page and knows who to call.
23
27
 
24
28
  ## Tool dependencies
25
29
 
26
- The skill fans out to **13** MCP calls in parallel:
27
-
28
- - **12 PropertyData** tools (postcode-keyed): `prices`, `prices-per-sqf`, `sold-prices`, `sold-prices-per-sqf`, `growth`, `growth-psf`, `demand`, `demand-rent`, `property-types`, `crime`, `flood-risk`, `council-tax`.
29
- - **1 EPC** tool (address-keyed): `epc-lookup-by-address` for subject floor area + energy rating + lodgement date.
30
+ The skill fans out to **12** PropertyData MCP calls in parallel (postcode-keyed): `prices`, `prices-per-sqf`, `sold-prices`, `sold-prices-per-sqf`, `growth`, `growth-psf`, `demand`, `demand-rent`, `property-types`, `crime`, `flood-risk`, `council-tax`.
30
31
 
31
32
  `property-data-address-match-uprn` and `property-data-planning-applications` are deliberately not called (CRM hygiene and dev-precedent reports, respectively).
32
33
 
34
+ The three EPC certificate fields the page-2 KPI strip needs — `total_floor_area_m2`, `current_energy_rating`, `lodgement_date` — are pasted by the operator into `subject` in `inputs.json` before invocation. There is no MCP fan-out for EPC; the PreToolUse hook and `render.py` both abort with `epc-certificate-not-supplied` if any of the three fields is null.
35
+
33
36
  ## Failure handling
34
37
 
35
- - **PropertyData key-not-registered** abort with the `property-data-key-register` prompt. Market data is essential; the pack cannot render without it.
36
- - **EPC unavailable** — any of `key-not-registered`, `http-404 (no record)`, `http-429`, `http-500`, network failure, or EPC MCP not configured — is treated as a single class. The skill prompts the operator with the specific cause and offers two paths:
37
- 1. Paste `subject.sqft` directly pack renders with EPC KPI cells showing "—" + cause sub-label, but the valuation maths still runs on the pasted sqft.
38
- 2. Declinevaluation panel switches to "Estimate requires floor area" benchmark-only mode; the pack still renders all five pages.
39
- - **PropertyData http-429** back off and retry only the throttled tool (4 calls per 10 seconds upstream throttle).
38
+ Every failure is fail-loud. The skill emits `[preval] aborted reason=<cause> …` and exits 2; no partial `index.html` or PDF is left on disk.
39
+
40
+ - **PropertyData `key-not-registered`**abort `reason=property-data-key-not-registered` with the `property-data-key-register` remediation hint.
41
+ - **PropertyData `http-429`** back off and retry the single throttled tool once. A second `http-429` aborts `reason=property-data-rate-limited`.
42
+ - **PropertyData `http-5xx` / network failure** abort `reason=property-data-unavailable`.
43
+ - **Any of the 12 PropertyData log lines missing** within 60s of `[preval] start` → abort `reason=observability-missing tool=<name>`. A silent tool drop must never proceed to render.
44
+ - **Subject EPC certificate field missing** — any of `subject.total_floor_area_m2`, `subject.current_energy_rating`, `subject.lodgement_date` is null → abort `reason=epc-certificate-not-supplied`. The operator pastes all three from the EPC certificate into `inputs.json` before re-invoking. There is no mid-run prompt and no MCP fallback.
45
+ - See `skills/property-preval/SKILL.md` § Hard breakpoints for the full table of abort causes.
40
46
 
41
47
  ## External dependencies
42
48
 
43
49
  - Requires `real-agent-property-data` enabled on the account with a registered PropertyData API key (`property-data-key-register`).
44
- - Requires `real-agent-epc` enabled with a registered EPC API key (`epc-key-register`) failure modes above; not strictly blocking thanks to the paste-sqft fallback.
50
+ - Requires the operator to paste the three EPC certificate fields (`total_floor_area_m2`, `current_energy_rating`, `lodgement_date`) into `subject` in `inputs.json` before invocation. There is no automated EPC lookup.
45
51
  - Requires Google Chrome at `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome` for headless `--print-to-pdf`. Same Chrome dependency as `property-market-report`.
52
+
53
+ ## Hooks
54
+
55
+ - `hooks/preval-prompt-required.sh` — PreToolUse gate on `Write|Edit|MultiEdit` of `**/preval/**/inputs.json`. Blocks (exit 2) before the file lands on disk if any of `epc-certificate-not-supplied`, `agent-listings-invented`, `market-summary-invented`, or `brand-invented` applies. The same five causes (plus `cover-hero-not-subject`) are re-checked by `render.py`'s `_assert_inputs` gate — defence in depth against silent fallback completions. Paths outside `preval/inputs.json` pass through.
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env bash
2
+ # PreToolUse hook — defence-in-depth gate for property-preval's inputs.json.
3
+ #
4
+ # Fires on Write/Edit when the target path ends in `/preval/.../inputs.json`.
5
+ # Blocks (exit 2) before the payload reaches disk if any of the five named
6
+ # adherence violations is present. The render.py validator catches the same
7
+ # violations downstream — this hook stops the bad payload one step earlier,
8
+ # while the agent still has the opportunity to prompt the operator.
9
+ #
10
+ # Aborts named here mirror the AdherenceError causes raised by render.py:
11
+ # - epc-certificate-not-supplied
12
+ # - agent-listings-invented
13
+ # - market-summary-invented
14
+ # - brand-invented
15
+ #
16
+ # (cover-hero-not-subject is checked by render.py only — the slug heuristic
17
+ # needs the on-disk path to be inspectable, which isn't reliable from the
18
+ # tool args alone.)
19
+ #
20
+ # Error philosophy: fail closed on the four named contract violations; fail
21
+ # open on anything else (missing python3, malformed stdin, file not under
22
+ # preval/). Failing open lets unrelated tool calls proceed; the named
23
+ # violations are the only ones the hook owns.
24
+
25
+ set -u
26
+
27
+ if [ -t 0 ]; then
28
+ exit 0
29
+ fi
30
+
31
+ if ! command -v python3 >/dev/null 2>&1; then
32
+ cat >/dev/null
33
+ echo "[preval-prompt-required] action=fail reason=python3-missing" >&2
34
+ exit 0
35
+ fi
36
+
37
+ INPUT=$(cat)
38
+
39
+ INPUT="$INPUT" python3 <<'PY'
40
+ import json, os, sys
41
+
42
+ INPUT = os.environ.get("INPUT", "")
43
+
44
+ def passthrough(reason):
45
+ print(f"[preval-prompt-required] action=passthrough reason={reason}", file=sys.stderr)
46
+ sys.exit(0)
47
+
48
+ def block(cause, remediation):
49
+ print(f"[preval-prompt-required] action=block cause={cause}", file=sys.stderr)
50
+ print(f"[preval] {cause}: {remediation}", file=sys.stderr)
51
+ sys.exit(2)
52
+
53
+ try:
54
+ payload = json.loads(INPUT) if INPUT else {}
55
+ except Exception:
56
+ passthrough("malformed-stdin")
57
+
58
+ tool_name = payload.get("tool_name") or ""
59
+ if tool_name not in ("Write", "Edit", "MultiEdit"):
60
+ passthrough(f"tool={tool_name}")
61
+
62
+ tool_input = payload.get("tool_input") or {}
63
+ file_path = tool_input.get("file_path") or ""
64
+ norm = file_path.replace("\\", "/").lower()
65
+ if "/preval/" not in norm or not norm.endswith("/inputs.json"):
66
+ passthrough("path-not-preval-inputs")
67
+
68
+ if tool_name == "Write":
69
+ content = tool_input.get("content") or ""
70
+ elif tool_name == "Edit":
71
+ content = tool_input.get("new_string") or ""
72
+ else: # MultiEdit
73
+ edits = tool_input.get("edits") or []
74
+ content = edits[-1].get("new_string", "") if edits else ""
75
+
76
+ try:
77
+ data = json.loads(content)
78
+ except Exception:
79
+ passthrough("content-not-json")
80
+
81
+ if not isinstance(data, dict):
82
+ passthrough("content-not-object")
83
+
84
+ overrides = data.get("agent_overrides") or {}
85
+
86
+ subject = data.get("subject") or {}
87
+ missing_epc = [
88
+ f for f in ("total_floor_area_m2", "current_energy_rating", "lodgement_date")
89
+ if not subject.get(f)
90
+ ]
91
+ if missing_epc:
92
+ block(
93
+ "epc-certificate-not-supplied",
94
+ f"subject is missing EPC certificate field(s) {missing_epc}. "
95
+ "Paste total_floor_area_m2, current_energy_rating, and lodgement_date "
96
+ "from the EPC certificate into subject before re-invoking. "
97
+ "No mid-run prompt — the operator supplies the certificate before invocation.",
98
+ )
99
+
100
+ if not overrides.get("listings_status_curated"):
101
+ for listing in data.get("agent_listings") or []:
102
+ origin = (listing or {}).get("origin")
103
+ if not origin or origin == "operator":
104
+ continue
105
+ try:
106
+ src_path = os.path.expanduser(str(origin))
107
+ if not os.path.isfile(src_path):
108
+ continue
109
+ with open(src_path) as f:
110
+ source = json.load(f)
111
+ except Exception:
112
+ continue
113
+ if source.get("status") in (None, "") and listing.get("status"):
114
+ block(
115
+ "agent-listings-invented",
116
+ f"agent_listings entry {listing.get('slug')} has status "
117
+ f"'{listing['status']}' but source {src_path} carries status:null. "
118
+ "Prompt the operator and set agent_overrides.listings_status_curated: true.",
119
+ )
120
+
121
+ ms = data.get("market_summary") or {}
122
+ if ms.get("origin") not in ("operator", "operator-edited-llm-stub"):
123
+ block(
124
+ "market-summary-invented",
125
+ "market_summary.origin must be 'operator' or 'operator-edited-llm-stub'. "
126
+ "Have the operator draft or accept the paragraphs before writing inputs.json.",
127
+ )
128
+
129
+ brand = data.get("brand") or {}
130
+ if brand.get("name") and not overrides.get("brand_selected_by_operator"):
131
+ block(
132
+ "brand-invented",
133
+ f"brand.name ('{brand['name']}') was set without "
134
+ "agent_overrides.brand_selected_by_operator: true. Ask the operator which "
135
+ "estate agent is pitching; presence of a DESIGN.md on disk does not authorise selection.",
136
+ )
137
+
138
+ print("[preval-prompt-required] action=allow", file=sys.stderr)
139
+ sys.exit(0)
140
+ PY
@@ -26,7 +26,7 @@ Never substitute the agent's body or display fonts even if their `DESIGN.md` spe
26
26
  - Optional `beds`, `type`, `tenure`, `condition` (well / average / needs work).
27
27
  - `adjustments[]` — operator-curated array of `{label, delta_pct}` covering esoteric factors that shift the headline range (e.g. `{"label":"South-facing garden","delta_pct":3}`, `{"label":"Needs full reno","delta_pct":-8}`). Deltas sum linearly into the final range.
28
28
  - `narrative` — one short paragraph the operator writes about the property.
29
- - **Floor area is auto-pulled from the EPC register** via `real-agent-epc` (`epc-lookup-by-address`) and surfaced as `sqft_m2` + derived `sqft`. If EPC has no record (pre-2008 property never sold or let; Scotland/NI; unmatched), operator pastes `subject.sqft` directly. Without a floor area the renderer prints "Estimate requires floor area" and shows only the £/sqft benchmark never invents a number.
29
+ - **EPC certificate fields are pasted by the operator before invocation.** The three required fields are `subject.total_floor_area_m2`, `subject.current_energy_rating`, and `subject.lodgement_date` copied verbatim from the EPC certificate. The renderer derives `sqft` from `total_floor_area_m2 × 10.7639`. There is no mid-run paste prompt and no benchmark-only render a null in any of the three aborts the run with `reason=epc-certificate-not-supplied`.
30
30
  - **`agent_listings`** — the agent's recent sold / under-offer / live listings to feature on the closing page. Up to 6 entries of `{url, address, price, beds, type, image, status, slug}` where `status ∈ {"Sold","Under offer","For sale"}`. Operator picks the comps that make the strongest pitch; this is *not* the PropertyData sample.
31
31
  - **`market_summary`** — `headline` (one display-italic line), `paragraphs[]` (2–3 short paragraphs), `demand_gauge_position` (percentage string like `"62%"`), `price_growth_note`, `demand_note`. The operator drafts or accepts an LLM stub.
32
32
 
@@ -48,9 +48,7 @@ Parallel fan-out keyed on the derived postcode + the subject address:
48
48
  11. `property-data-flood-risk` — area flood risk (full postcode only).
49
49
  12. `property-data-council-tax` — band D + per-property bands (full postcode only).
50
50
 
51
- **EPC (1 callfree, rate-limited):**
52
-
53
- 13. `epc-lookup-by-address(address, postcode)` — subject floor area + energy ratings + lodgement date.
51
+ EPC certificate fields are operator paste-in see `subject.total_floor_area_m2`, `subject.current_energy_rating`, `subject.lodgement_date` in the Inputs section. There is no EPC MCP fan-out.
54
52
 
55
53
  `address-match-uprn` and `planning-applications` are deliberately omitted (CRM hygiene and dev-precedent reports respectively).
56
54
 
@@ -67,7 +65,7 @@ Return the PDF path to the operator.
67
65
  ## Pages
68
66
 
69
67
  1. **Cover** — full-bleed `subject.cover_hero` with vertical gradient scrim; light logo top-left; eyebrow "`<brand.name>` · Pre-valuation"; address in display-italic; postcode chip; four-up meta strip (Report · Address · Postcode · Generated). Lifted from property-market-report's cover contract.
70
- 2. **Subject valuation** — KPI strip (sqft, beds, EPC rating, type). Centre panel: headline range = `sqft × sold_psf_low–high` (Land Registry 70pc band) with `sqft × asking_psf` shown as a cross-check. Operator `adjustments[]` displayed as a stacked list (label · delta% · running £). Final range pill at the foot. If `sqft` missing the panel switches to the "requires floor area" mode (£/sqft benchmark only). One paragraph of `subject.narrative` under the panel.
68
+ 2. **Subject valuation** — KPI strip (sqft, beds, EPC rating, type). Centre panel: headline range = `sqft × sold_psf_low–high` (Land Registry 70pc band) with `sqft × asking_psf` shown as a cross-check. Operator `adjustments[]` displayed as a stacked list (label · delta% · running £). Final range pill at the foot. One paragraph of `subject.narrative` under the panel. `sqft` is required a null value aborts the run, never renders a benchmark-only panel.
71
69
  3. **Market context** — KPI cube (avg asking, avg sold, £/sqft, YoY); pill + gauge for demand; 7y growth sparkline (£ solid + £/sqft dashed); summary paragraphs. Same patterns as property-market-report's page 2.
72
70
  4. **Comparables (full-width, stacked)** — Nearest sold table (top 6) full-width across the page; Live asking tile grid (top 4) full-width below. Vertically stacked, never side-by-side — corrects the cramped two-column layout in the v1 preval where the asking tiles got pushed to ~40mm columns of italic addresses.
73
71
  5. **Recently with `<brand.name>` + sources** — agent's own listings as a clickable tile grid (`<a>` per card, status badge: Sold / Under offer / For sale), then the sources / methodology / accuracy / investment block. Closes with `Real Agent · Generated <date> · <postcode>` in the footer.
@@ -75,11 +73,13 @@ Return the PDF path to the operator.
75
73
  ## How to execute
76
74
 
77
75
  1. Match the postcode out of the address (`/[A-Z]{1,2}[0-9][A-Z0-9]?\s?[0-9][A-Z]{2}/i`). Stop if no match.
78
- 2. Run the 13 fan-out tools (12 PropertyData + 1 EPC) in parallel. Failure handling differs by source:
79
- - **PropertyData `key-not-registered`** → abort with the `property-data-key-register` prompt. The pack cannot render without market data.
80
- - **PropertyData `http-429`** → back off, retry only the throttled tool. Do not re-run the whole fan-out.
81
- - **EPC failure of any kind** — `key-not-registered`, `http-404 (no record on file)`, `http-429`, `http-500`, network failure, or MCP not configured on the account — is treated as a single class: **prompt the operator** with the relevant cause (e.g. "EPC API key not registered — register with `epc-key-register`, or paste subject.sqft to continue"; "No EPC on file for this address — paste subject.sqft to continue"; "EPC API unavailable — paste subject.sqft to continue"). If the operator pastes `subject.sqft`, the pack renders normally with the EPC-derived KPI cells switching to "—" + "No EPC on file" / "EPC API unavailable" sub-labels. If the operator declines to paste, the valuation panel switches to the "Estimate requires floor area" benchmark-only mode and the pack still renders the other four pages.
76
+ 2. Run the 12 PropertyData fan-out tools in parallel. Every failure is fail-loud no mid-run paste prompts, no benchmark-only render, no degraded pack on disk:
77
+ - **PropertyData `key-not-registered`** → abort `reason=property-data-key-not-registered` with the `property-data-key-register` remediation hint.
78
+ - **PropertyData `http-429`** → back off and retry the single throttled tool **once**. A second `http-429` aborts `reason=property-data-rate-limited`.
79
+ - **PropertyData `http-5xx` / network failure** abort `reason=property-data-unavailable`.
80
+ - **Watchdog: any of the 12 PropertyData log lines missing** within 60 s of `[preval] start` → `render.py` aborts `reason=observability-missing tool=<name>` naming the silent tool. A silent tool drop must never proceed to render.
82
81
  3. Compute valuation range:
82
+ - `sqft = round(subject.total_floor_area_m2 × 10.7639)` (operator-pasted m² × the standard conversion factor).
83
83
  - `sold_psf_low` = `sold-prices-per-sqf` `70pc_range[0]`
84
84
  - `sold_psf_high` = `sold-prices-per-sqf` `70pc_range[1]`
85
85
  - `low = sqft × sold_psf_low`, `mid = sqft × sold_psf`, `high = sqft × sold_psf_high`
@@ -96,23 +96,81 @@ Deltas sum linearly (`-8 + 3 = -5%`, applied as `× 0.95`). Compound interpretat
96
96
 
97
97
  - `[preval] start address="<addr>" postcode=<pc>` at run start.
98
98
  - `[preval] done pdf=<path> pages=<n> ms=<n>` at run end.
99
- - Each fan-out call emits its own `[property-data] tool=<name>` or `[epc] tool=<name>` line in `server.log` (inherited contracts; no new instrumentation here).
99
+ - `[preval] aborted reason=<cause> address="<addr>" postcode=<pc> ms=<n>` on any abort (one line, then exit 2; no `done`).
100
+ - Each fan-out call emits its own `[property-data] tool=<name>` line in `server.log` (inherited contract; no new instrumentation here). `render.py`'s observability watchdog tails these lines and aborts with `observability-missing tool=<name>` if any of the 12 expected names is absent 60 s after `[preval] start`.
101
+
102
+ ## Hard breakpoints
103
+
104
+ Each row aborts the run with the named cause. No PDF or `index.html` is left on disk. Operator sees a single-line cause + one-line remediation hint, nothing else.
105
+
106
+ | Forbidden state | `reason=` cause |
107
+ |---|---|
108
+ | `subject.total_floor_area_m2` / `current_energy_rating` / `lodgement_date` null or missing | `epc-certificate-not-supplied` (operator pastes the three fields from the EPC certificate before re-invoking) |
109
+ | `subject.cover_hero` missing, unreachable, below 1200×800, or symlinked into another property's folder | `subject-cover-hero-missing` / `subject-cover-hero-unreadable` / `subject-cover-hero-too-small` / `subject-cover-hero-symlinked-foreign` |
110
+ | `brand` not resolved from an on-disk `DESIGN.md` (required token missing) | `brand-unresolved` |
111
+ | `agent_listings` empty | `agent-listings-empty` |
112
+ | `market_summary.paragraphs` < 2 entries | `market-summary-too-thin` |
113
+ | PropertyData any-call `http-429` after 1 retry | `property-data-rate-limited` |
114
+ | PropertyData any-call `key-not-registered` | `property-data-key-not-registered` (operator runs `property-data-key-register`) |
115
+ | Any of the 12 PropertyData log lines missing 60 s after `[preval] start` | `observability-missing tool=<name>` (the silent tool is named in the abort hint) |
116
+
117
+ ## Forbidden behaviours
118
+
119
+ The skill is the contract; if any of these slip through, the pack must not render:
120
+
121
+ - Silent fallback selection — switching to a benchmark-only / "Estimate requires floor area" panel when an input is missing.
122
+ - Inventing inputs — fabricating `brand`, `subject.cover_hero`, `market_summary.paragraphs`, `agent_listings`, or any field the operator did not supply.
123
+ - Reusing a hero photo from a different property as a placeholder.
124
+ - Defaulting `agent_listings[].status` to `"For sale"` when the source is null.
125
+ - Mid-run prompts for a paste-in. The three EPC certificate fields and every other operator-supplied input are pasted into `inputs.json` **before** invocation; there is no retry / paste-and-resume path.
126
+ - Omitting the `[preval]` start / done / aborted log emissions.
127
+ - Leaving partial output (`index.html`, `<stem>.pdf`) on disk after an abort.
128
+
129
+ ## Failure diagnostics
130
+
131
+ - `pages=6` (or ≠ 5) in the `done` line → template overflow on one page. Diagnose with `pdftoppm -png -f <n> -l <n> <pdf>`, then trim that panel's padding only.
132
+ - `start` with no matching `done` or `aborted` within 60s → renderer crashed mid-run. Inspect with `grep -B2 -A20 '\[preval\] start address="<echoed>"' server.log`.
133
+ - `[preval] aborted reason=<cause>` → look up `<cause>` in the **Hard breakpoints** table for the remediation hint.
134
+
135
+ ## Adherence — non-negotiable
136
+
137
+ These rules override every session-level "skip clarifying questions", "make the reasonable call", or "work without stopping" directive the operator has set. The named breakpoints below are documented contract points, not casual asks — the renderer and the PreToolUse hook both enforce them and a run that violates one aborts with a named cause.
138
+
139
+ - **Prompt at named breakpoints — no exceptions.** Named breakpoints: EPC certificate fields not supplied, cover_hero not depicting the subject, brand identity (which estate agent is pitching), `agent_listings` empty or carrying invented statuses, `market_summary` not operator-supplied. The load-bearing inputs themselves (EPC certificate fields, cover_hero, brand tokens, two paragraphs) are gated by `render.py`'s `_assert_inputs`; this section layers provenance on top.
140
+ - **Never invent inputs.** Brand identity, brand tokens, cover hero, narrative, market summary paragraphs, agent listings, listing statuses, subject tenure / beds / type / condition — all operator-supplied. Defaulting from "area pattern", a sister property's photo, "the only DESIGN.md I found on disk", "the LLM stub I drafted myself", or "status:null in the source so I picked For sale" is invention. The presence of a single `~/estate-agents/<slug>/DESIGN.md` on disk does not authorise its selection — only an operator instruction does. If more than one `~/estate-agents/<slug>/` exists and the operator has not named which one is pitching, abort.
141
+ - **`agent_overrides` is the only bypass channel.** Every override the operator authorises lands in `inputs.json` as a named boolean (`brand_selected_by_operator`, `listings_status_curated`) so the audit trail sits next to the disputed value. Setting an override without a real operator instruction is a violation of the same contract.
142
+ - **Emit the three `[preval]` log lines — every run.** `[preval] start address="…" postcode=…`, then `[preval] done pdf=… pages=… ms=…` on success or `[preval] aborted reason=<cause> ms=…` on any abort. A run that emits neither `done` nor `aborted` is itself a defect.
143
+
144
+ ### Named abort causes
145
+
146
+ | Cause | Trigger | Operator remediation |
147
+ |---|---|---|
148
+ | `cover-hero-not-subject` | `subject.cover_hero` resolves to a `*/properties/*/` directory whose slug doesn't contain the subject's primary street token | Supply the subject's own photo |
149
+ | `agent-listings-invented` | An `agent_listings[].status` is set when the source `property.json` (named by `agent_listings[].origin`) carries `status: null`, and `agent_overrides.listings_status_curated` is not `true` | Operator signs off on each listing status, then sets the override |
150
+ | `market-summary-invented` | `market_summary.origin` is missing or not in `{"operator", "operator-edited-llm-stub"}` | Operator drafts or accepts the paragraphs; set `origin` accordingly |
151
+ | `brand-invented` | `brand.name` is set without `agent_overrides.brand_selected_by_operator: true` | Operator names which estate agent is pitching; set the override |
152
+ | `epc-certificate-not-supplied` | Any of `subject.total_floor_area_m2`, `subject.current_energy_rating`, or `subject.lodgement_date` is null or missing | Operator copies the three fields verbatim from the EPC certificate into `subject` in `inputs.json` before re-invoking |
153
+ | `observability-missing tool=<name>` | One of the 12 expected `[property-data] tool=<name>` log lines did not appear within 60 s of `[preval] start` | Re-invoke and confirm every PropertyData tool returns; if a tool is genuinely down, surface a `property-data-*` cause first |
154
+ | `log-destination-unavailable` | Neither `~/.maxy/logs/server.log` nor `<out_dir>/preval.log` is writable | Fix filesystem permissions before re-running |
155
+
156
+ ## Self-check before declaring done
100
157
 
101
- ## Failure signatures
158
+ Answer all seven inline at the end of every run, with line references from `server.log` or `<out_dir>/preval.log` — not paraphrase:
102
159
 
103
- - `pages=6` (or ≠ 5) in the `done` line → template overflow on one page. Diagnose with `pdftoppm -png -f <n> -l <n> <pdf>` to see which page bled, then trim that panel's padding only.
104
- - `start` with no matching `done` within 60s renderer crashed. Inspect with `grep -B2 -A20 '\[preval\] start address="<echoed>"' server.log`.
105
- - `[epc] status=http-404` property has no EPC; prompt "no EPC on file for this address — paste subject.sqft to continue".
106
- - `[epc] status=key-not-registered` prompt "EPC API key not registered run `epc-key-register`, or paste subject.sqft to continue".
107
- - `[epc] status=http-429` | `http-5xx` | `bad-response` | `network-error` → prompt "EPC API unavailable — paste subject.sqft to continue". The MCP-not-installed case (no `[epc] …` line at all and the tool call surfaces as "tool not found") is the same prompt with cause "EPC MCP not configured on this account".
108
- - `[property-data] … status=http-429` → 4-calls-in-10-seconds throttle. Retry only the throttled tool after the back-off; do not re-run the whole fan-out.
160
+ 1. `[preval] start` emitted? (cite the log line)
161
+ 2. All 12 expected `[property-data] tool=<name>` log lines present, or `[preval] aborted` emitted with a named cause? (cite the lines)
162
+ 3. EPC certificate fields (`subject.total_floor_area_m2`, `subject.current_energy_rating`, `subject.lodgement_date`) all populated from the operator paste? (cite the `inputs.json` excerpt)
163
+ 4. Every input field traceable to a real source operator paste (including the EPC certificate), on-disk `DESIGN.md`, MCP response? Anything sourced from "area pattern", a sister property file, or LLM imagination is a defect.
164
+ 5. `[preval] done pages=5` emitted? (cite the log line)
165
+ 6. PDF page count = 5 asserted? (cite the assertion result)
166
+ 7. No fields invented from area pattern, sister-property files, or LLM imagination? List the three most fabrication-prone fields (`brand.name`, `market_summary.paragraphs`, `agent_listings[].status`) and the source for each in this run.
109
167
 
110
168
  ## Out of scope
111
169
 
112
170
  - Multi-address batch preval (CSV in → many PDFs out).
113
171
  - Loop CRM auto-publish of the PDF onto a contact's record.
114
172
  - Pulling `agent_listings` from Loop CRM automatically — operator paste-in for now; CRM wire-up is a separate task.
115
- - Caching of MCP responses (13 credits per pack is acceptable).
173
+ - Caching of MCP responses (12 credits per pack is acceptable).
116
174
  - A separate cover letter / pitch letter — the cover page *is* the pitch.
117
175
  - Compound adjustments (linear sum is the contract; see above).
118
- - Subject sqft from sources other than EPC and the operator paste-in fallback (e.g. Loop CRM floor plans, Rightmove sqft scrape) — separate task if pursued.
176
+ - Subject EPC fields from sources other than the operator paste-in (e.g. Loop CRM floor plans, Rightmove sqft scrape, restored EPC API) — separate task if pursued.