@rubytech/create-maxy-code 0.1.36 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/package-lock.json +752 -512
- package/payload/platform/plugins/admin/PLUGIN.md +12 -0
- package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +109 -0
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +114 -0
- package/payload/platform/plugins/admin/skills/unzip-attachment/SKILL.md +1 -1
- package/payload/platform/plugins/contacts/PLUGIN.md +11 -0
- package/payload/platform/plugins/docs/references/internals.md +10 -0
- package/payload/platform/plugins/docs/references/platform.md +9 -4
- package/payload/platform/plugins/email/PLUGIN.md +11 -0
- package/payload/platform/plugins/linkedin-import/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/linkedin-import/PLUGIN.md +5 -5
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/SKILL.md +3 -1
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/references/connections.md +2 -2
- package/payload/platform/plugins/loop/PLUGIN.md +11 -0
- package/payload/platform/plugins/memory/PLUGIN.md +11 -0
- package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +2 -0
- package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +2 -0
- package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +6 -4
- package/payload/platform/plugins/outlook/PLUGIN.md +11 -0
- package/payload/platform/plugins/replicate/PLUGIN.md +11 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +11 -0
- package/payload/platform/plugins/tasks/PLUGIN.md +11 -0
- package/payload/platform/plugins/telegram/PLUGIN.md +11 -0
- package/payload/platform/plugins/waitlist/PLUGIN.md +11 -0
- package/payload/platform/plugins/whatsapp/PLUGIN.md +11 -0
- package/payload/platform/plugins/workflows/PLUGIN.md +11 -0
- package/payload/platform/scripts/seed-neo4j.sh +14 -0
- package/payload/platform/scripts/verify-skill-tool-surface.sh +5 -3
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +16 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +63 -3
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +34 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +132 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts +13 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.js +7 -3
- package/payload/platform/services/claude-session-manager/dist/session-store.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +37 -4
- package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js +128 -27
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +5 -14
- package/payload/platform/templates/specialists/agents/database-operator.md +27 -70
- package/payload/platform/templates/specialists/agents/librarian.md +55 -0
- package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +11 -0
- package/payload/server/public/assets/{Checkbox-C_5g1tvd.js → Checkbox-DAki3vDW.js} +1 -1
- package/payload/server/public/assets/{admin-CMhAQf3x.js → admin-CyAZtsYZ.js} +1 -1
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-PATAR9cB.js → architectureDiagram-Q4EWVU46-C-hla3Ip.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-BTtUDSn8.js → blockDiagram-DXYQGD6D-CbzjtNs3.js} +1 -1
- package/payload/server/public/assets/{brand--hRSJcTa.css → brand-Cun0PBrA.css} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DagJLqud.js → c4Diagram-AHTNJAMY-B87UblA0.js} +1 -1
- package/payload/server/public/assets/channel-CTNo72W7.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-r_17ZSte.js → chunk-336JU56O-2a2pVlSg.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-BeZHE5Od.js → chunk-426QAEUC-j9NOD8_a.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-BOKuzFDs.js → chunk-4TB4RGXK-Cs872xAq.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-CFPql_Mb.js → chunk-5FUZZQ4R-BnDFbZ_I.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-B-ooj0Oj.js → chunk-5PVQY5BW-Bu5B3Hyf.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-pfgSmAaU.js → chunk-EDXVE4YY-B96Fw4FF.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-Czo3wSBG.js → chunk-ENJZ2VHE-CcGrGQim.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-B0Kq8LNp.js → chunk-ICPOFSXX-ZRvcI4Ai.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-BM97IkL3.js → chunk-OYMX7WX6-B6RI9Fbf.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-Qu1CuohC.js → chunk-U2HBQHQK-BYGHVYyo.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-uDlh8MVE.js → chunk-X2U36JSP-rwNs-gTO.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-DUlG-OZ5.js → chunk-YZCP3GAM-jPttJRap.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-BABivBFM.js → chunk-ZZ45TVLE-DLykWOT5.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BaV5nDmT.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DOKlCKjY.js +1 -0
- package/payload/server/public/assets/clone-sQSwlSln.js +1 -0
- package/payload/server/public/assets/{dagre-KV5264BT-CVL1mRVD.js → dagre-KV5264BT-C6wSzHX2.js} +1 -1
- package/payload/server/public/assets/{dagre-BLaP4HDY.js → dagre-jnQDnF-5.js} +1 -1
- package/payload/server/public/assets/data-DbkuXcPb.js +1 -0
- package/payload/server/public/assets/{device-url-actions-Dmhh-Azv.js → device-url-actions-y1tXNDZx.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-Db75sppc.js → diagram-5BDNPKRD-N3X-n90h.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-Cj8Nvgev.js → diagram-G4DWMVQ6-vfmbzdPd.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-BGXJmtU0.js → diagram-MMDJMWI5-BETmPx_w.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-FALU804i.js → diagram-TYMM5635-BSUGM4wG.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-Dny5IMgt.js → erDiagram-SMLLAGMA-CWZ9OwMb.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CvKuRNSd.js → flowDiagram-DWJPFMVM-BpQOQS1a.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-CMMNRVGJ.js → ganttDiagram-T4ZO3ILL-Dc59igCS.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-GNp7o9CH.js → gitGraphDiagram-UUTBAWPF-D6lXg3zl.js} +1 -1
- package/payload/server/public/assets/graph-CC5_6-dg.js +1 -0
- package/payload/server/public/assets/{graph-labels-DnFPoPy9.js → graph-labels-DFyNH0jb.js} +1 -1
- package/payload/server/public/assets/{graphlib-Bbf4iSQ9.js → graphlib-yG7kH8Fr.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-CKnsQ4zf.js → infoDiagram-42DDH7IO-TS9Pv8Os.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-7iiLy5h7.js → ishikawaDiagram-UXIWVN3A-BJiJJTq6.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-BqbrYu64.js → journeyDiagram-VCZTEJTY-C7PW4fmw.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-B4xrW1HU.js → kanban-definition-6JOO6SKY-BEk21ciD.js} +1 -1
- package/payload/server/public/assets/{line-VuY4jgLe.js → line-DusyVWDE.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-BaqOkGpC.js → mermaid-parser.core-DeeojQSb.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-CCQHCJiH.js → mermaid.core-p65Lo7Sj.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CD7_gX12.js → mindmap-definition-QFDTVHPH-B0jxFxdS.js} +1 -1
- package/payload/server/public/assets/{page-BbunxlG3.js → page-BeYGnDzI.js} +1 -1
- package/payload/server/public/assets/{page-CDFsJW62.js → page-x5khmfRx.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-DYv6IDvS.js → pieDiagram-DEJITSTG-DJ5GKYt6.js} +1 -1
- package/payload/server/public/assets/{public-vZ5OE_BJ.js → public-cnoUs7vq.js} +3 -3
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-Djjgb1kX.js → quadrantDiagram-34T5L4WZ-BV7R-kwV.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-D1jpw_fu.js → requirementDiagram-MS252O5E-DRiLzlGN.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-CiWmspyf.js → sankeyDiagram-XADWPNL6-C5-6_cCI.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-B1GXIeQe.js → sequenceDiagram-FGHM5R23-5FXm_VYM.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DX7QZrhc.js → stateDiagram-FHFEXIEX-FCQTaGqV.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BdpPhdqg.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-BxiwnKFu.js → timeline-definition-GMOUNBTQ-tvtq62ef.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-RxZA_K0W.js → vennDiagram-DHZGUBPP-Dk-k7CE4.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-b2tVWjtB.js → wardleyDiagram-NUSXRM2D-CZSrqniY.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-D55tkJH1.js → xychartDiagram-5P7HB3ND-CpGLpk7Q.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/dist/__tests__/onboarding-state-readback.test.js +0 -61
- package/dist/onboarding-readback.js +0 -27
- package/payload/platform/lib/anthropic-key/dist/index.d.ts +0 -22
- package/payload/platform/lib/anthropic-key/dist/index.d.ts.map +0 -1
- package/payload/platform/lib/anthropic-key/dist/index.js +0 -232
- package/payload/platform/lib/anthropic-key/dist/index.js.map +0 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.d.ts +0 -39
- package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.d.ts.map +0 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.js +0 -249
- package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/.claude-plugin/marketplace.json +0 -13
- package/payload/platform/plugins/real-agency/plugins/loop/.claude-plugin/plugin.json +0 -17
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/index.d.ts +0 -2
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/index.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/index.js +0 -293
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/index.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/crypto.d.ts +0 -10
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/crypto.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/crypto.js +0 -88
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/crypto.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.d.ts +0 -82
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.js +0 -427
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.d.ts +0 -5
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.js +0 -40
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/customer-preferences.d.ts +0 -10
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/customer-preferences.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/customer-preferences.js +0 -24
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/customer-preferences.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/feedback.d.ts +0 -16
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/feedback.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/feedback.js +0 -35
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/feedback.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-deregister.d.ts +0 -5
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-deregister.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-deregister.js +0 -19
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-deregister.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-list.d.ts +0 -4
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-list.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-list.js +0 -14
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-list.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-register.d.ts +0 -9
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-register.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-register.js +0 -60
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/key-register.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-enquiry.d.ts +0 -13
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-enquiry.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-enquiry.js +0 -41
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-enquiry.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts +0 -9
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-batch.js +0 -16
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-batch.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-request.d.ts +0 -15
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-request.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-request.js +0 -11
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-request.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match.d.ts +0 -10
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match.js +0 -39
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/people-detail.d.ts +0 -9
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/people-detail.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/people-detail.js +0 -125
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/people-detail.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/people-search.d.ts +0 -18
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/people-search.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/people-search.js +0 -87
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/people-search.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-detail.d.ts +0 -10
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-detail.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-detail.js +0 -82
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-detail.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-listed.d.ts +0 -12
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-listed.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-listed.js +0 -32
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-listed.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-request.d.ts +0 -15
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-request.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-request.js +0 -11
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-request.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-search.d.ts +0 -16
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-search.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-search.js +0 -41
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/property-search.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/supplier.d.ts +0 -13
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/supplier.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/supplier.js +0 -49
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/supplier.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/team-availability.d.ts +0 -7
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/team-availability.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/team-availability.js +0 -19
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/team-availability.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/team-info.d.ts +0 -5
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/team-info.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/team-info.js +0 -32
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/team-info.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-create.d.ts +0 -14
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-create.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-create.js +0 -11
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-create.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-detail.d.ts +0 -9
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-detail.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-detail.js +0 -85
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-detail.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-search.d.ts +0 -13
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-search.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-search.js +0 -44
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-search.js.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-update.d.ts +0 -14
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-update.d.ts.map +0 -1
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-update.js +0 -18
- package/payload/platform/plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-update.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/.claude-plugin/marketplace.json +0 -13
- package/payload/premium-plugins/real-agency/plugins/loop/.claude-plugin/plugin.json +0 -17
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/index.d.ts +0 -2
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/index.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/index.js +0 -293
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/index.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/crypto.d.ts +0 -10
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/crypto.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/crypto.js +0 -88
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/crypto.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.d.ts +0 -82
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.js +0 -427
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/loop-api.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.d.ts +0 -5
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.js +0 -40
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/lib/neo4j.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/customer-preferences.d.ts +0 -10
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/customer-preferences.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/customer-preferences.js +0 -24
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/customer-preferences.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/feedback.d.ts +0 -16
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/feedback.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/feedback.js +0 -35
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/feedback.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-deregister.d.ts +0 -5
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-deregister.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-deregister.js +0 -19
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-deregister.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-list.d.ts +0 -4
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-list.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-list.js +0 -14
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-list.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-register.d.ts +0 -9
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-register.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-register.js +0 -60
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/key-register.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-enquiry.d.ts +0 -13
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-enquiry.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-enquiry.js +0 -41
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-enquiry.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts +0 -9
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-batch.js +0 -16
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-batch.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-request.d.ts +0 -15
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-request.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-request.js +0 -11
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match-request.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match.d.ts +0 -10
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match.js +0 -39
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/marketing-match.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/people-detail.d.ts +0 -9
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/people-detail.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/people-detail.js +0 -125
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/people-detail.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/people-search.d.ts +0 -18
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/people-search.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/people-search.js +0 -87
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/people-search.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-detail.d.ts +0 -10
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-detail.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-detail.js +0 -82
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-detail.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-listed.d.ts +0 -12
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-listed.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-listed.js +0 -32
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-listed.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-request.d.ts +0 -15
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-request.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-request.js +0 -11
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-request.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-search.d.ts +0 -16
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-search.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-search.js +0 -41
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/property-search.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/supplier.d.ts +0 -13
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/supplier.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/supplier.js +0 -49
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/supplier.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/team-availability.d.ts +0 -7
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/team-availability.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/team-availability.js +0 -19
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/team-availability.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/team-info.d.ts +0 -5
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/team-info.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/team-info.js +0 -32
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/team-info.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-create.d.ts +0 -14
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-create.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-create.js +0 -11
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-create.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-detail.d.ts +0 -9
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-detail.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-detail.js +0 -85
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-detail.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-search.d.ts +0 -13
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-search.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-search.js +0 -44
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-search.js.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-update.d.ts +0 -14
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-update.d.ts.map +0 -1
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-update.js +0 -18
- package/payload/premium-plugins/real-agency/plugins/loop/mcp/dist/tools/viewing-update.js.map +0 -1
- package/payload/server/public/assets/channel-ad6bhEyF.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-D9Gycby2.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-sUgm3wmz.js +0 -1
- package/payload/server/public/assets/clone-CZxh5VW0.js +0 -1
- package/payload/server/public/assets/data-DarDs6k1.js +0 -1
- package/payload/server/public/assets/graph-CG9KcTMy.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CekuC-ks.js +0 -1
- /package/payload/server/public/assets/{brand-B62OQoRC.js → brand-lj7EhWRg.js} +0 -0
|
@@ -53,6 +53,17 @@ hidden:
|
|
|
53
53
|
- wifi
|
|
54
54
|
always: true
|
|
55
55
|
embed: false
|
|
56
|
+
mcp:
|
|
57
|
+
command: node
|
|
58
|
+
args:
|
|
59
|
+
- ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
|
|
60
|
+
- ${PLATFORM_ROOT}/plugins/admin/mcp/dist/index.js
|
|
61
|
+
env:
|
|
62
|
+
MCP_SPAWN_TEE_NAME: admin
|
|
63
|
+
LOG_DIR: ${LOG_DIR}
|
|
64
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
65
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
66
|
+
SESSION_ID: ${SESSION_ID}
|
|
56
67
|
---
|
|
57
68
|
|
|
58
69
|
# Admin
|
|
@@ -94,6 +105,7 @@ Tools are available via the `admin` MCP server.
|
|
|
94
105
|
- `hooks/pre-tool-use.sh` — enforces admin agent write boundaries
|
|
95
106
|
- `hooks/playwright-file-guard.sh` — rewrites file:// URLs to a backgrounded loopback http.server before Playwright sees them
|
|
96
107
|
- `hooks/webfetch-preflight.mjs` — short-circuits WebFetch on JS-SPA shells with a structured `WEBFETCH_CANNOT_READ_JS_SPA` error so the agent surfaces a loud failure to the owner instead of paying the 60s extraction timeout. Fail-open on any internal error.
|
|
108
|
+
- `hooks/turn-completed-graph-write.sh` — Stop hook fired once per completed admin-agent turn. Gates on `MAXY_SESSION_ROLE=admin` + `MAXY_HIDDEN_SPAWN=0` so it never recurses into the hidden recorder PTY or fires on public sessions. POSTs a hidden `/spawn` against the `database-operator` specialist with the transcript tail as `stdinPayload`; the manager records the row with `hidden: true` so `/list` does not surface it.
|
|
97
109
|
|
|
98
110
|
## Failure-report breadcrumbs
|
|
99
111
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Regression test for the Stop-hook gate that fires the database-operator
|
|
3
|
+
# per completed admin-agent turn.
|
|
4
|
+
#
|
|
5
|
+
# Behaviour verified:
|
|
6
|
+
# 1. MAXY_SESSION_ROLE!=admin → exit 0, no POST attempt, no log line.
|
|
7
|
+
# 2. MAXY_HIDDEN_SPAWN=1 → exit 0, no POST attempt, no log line.
|
|
8
|
+
# 3. Empty stdin → exit 0 silently.
|
|
9
|
+
# 4. Missing transcript_path → exit 0 silently.
|
|
10
|
+
# 5. Happy path → POST attempt + `turn-completed-graph-write
|
|
11
|
+
# fired conversationId=<8> tail-bytes=<n> ms=<n>` log line.
|
|
12
|
+
#
|
|
13
|
+
# POST is observed by binding the hook's MANAGER_PORT to a tiny netcat
|
|
14
|
+
# listener that records the request body. Each case uses a separate port
|
|
15
|
+
# so concurrent execution does not interfere.
|
|
16
|
+
|
|
17
|
+
set -u
|
|
18
|
+
|
|
19
|
+
HOOK="$(cd "$(dirname "$0")/.." && pwd)/turn-completed-graph-write.sh"
|
|
20
|
+
if [[ ! -x "$HOOK" ]]; then
|
|
21
|
+
echo "FAIL: $HOOK not executable" >&2
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
TMPFILES=()
|
|
26
|
+
cleanup_test_state() {
|
|
27
|
+
for f in "${TMPFILES[@]:-}"; do
|
|
28
|
+
[[ -n "$f" ]] && rm -f "$f" 2>/dev/null || true
|
|
29
|
+
done
|
|
30
|
+
}
|
|
31
|
+
trap cleanup_test_state EXIT
|
|
32
|
+
|
|
33
|
+
PASS=0
|
|
34
|
+
FAIL=0
|
|
35
|
+
pass() { echo "PASS: $1"; PASS=$((PASS + 1)); }
|
|
36
|
+
fail() { echo "FAIL: $1" >&2; FAIL=$((FAIL + 1)); }
|
|
37
|
+
|
|
38
|
+
# Helper: run hook with a stdin envelope + env, capture stderr + exit code.
|
|
39
|
+
run_hook() {
|
|
40
|
+
local role="$1"; local hidden="$2"; local stdin_json="$3"
|
|
41
|
+
local stderr_file; stderr_file=$(mktemp); TMPFILES+=("$stderr_file")
|
|
42
|
+
local stdout_file; stdout_file=$(mktemp); TMPFILES+=("$stdout_file")
|
|
43
|
+
printf '%s' "$stdin_json" | \
|
|
44
|
+
MAXY_SESSION_ROLE="$role" \
|
|
45
|
+
MAXY_HIDDEN_SPAWN="$hidden" \
|
|
46
|
+
CLAUDE_SESSION_MANAGER_PORT="${MANAGER_PORT:-19400}" \
|
|
47
|
+
bash "$HOOK" >"$stdout_file" 2>"$stderr_file"
|
|
48
|
+
local rc=$?
|
|
49
|
+
HOOK_RC="$rc"
|
|
50
|
+
HOOK_STDERR=$(cat "$stderr_file")
|
|
51
|
+
HOOK_STDOUT=$(cat "$stdout_file")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# --- Case 1: role != admin → no fire --------------------------------------
|
|
55
|
+
TRANSCRIPT=$(mktemp); TMPFILES+=("$TRANSCRIPT")
|
|
56
|
+
printf '{"type":"user","message":{"content":"hi"}}\n' > "$TRANSCRIPT"
|
|
57
|
+
ENVELOPE=$(python3 -c '
|
|
58
|
+
import json, sys
|
|
59
|
+
print(json.dumps({"session_id": "abcd1234-deadbeef", "transcript_path": sys.argv[1]}))
|
|
60
|
+
' "$TRANSCRIPT")
|
|
61
|
+
|
|
62
|
+
run_hook "public" "0" "$ENVELOPE"
|
|
63
|
+
if [[ "$HOOK_RC" -ne 0 ]]; then fail "case-1 expected rc=0 got=$HOOK_RC"
|
|
64
|
+
elif [[ -n "$HOOK_STDERR" ]]; then fail "case-1 expected empty stderr, got: $HOOK_STDERR"
|
|
65
|
+
else pass "case-1 role=public → no fire (rc=0, stderr empty)"
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# --- Case 2: hidden=1 → no fire ------------------------------------------
|
|
69
|
+
run_hook "admin" "1" "$ENVELOPE"
|
|
70
|
+
if [[ "$HOOK_RC" -ne 0 ]]; then fail "case-2 expected rc=0 got=$HOOK_RC"
|
|
71
|
+
elif [[ -n "$HOOK_STDERR" ]]; then fail "case-2 expected empty stderr, got: $HOOK_STDERR"
|
|
72
|
+
else pass "case-2 hidden=1 → no fire (rc=0, stderr empty)"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# --- Case 3: empty stdin → silent --------------------------------------
|
|
76
|
+
run_hook "admin" "0" ""
|
|
77
|
+
if [[ "$HOOK_RC" -ne 0 ]]; then fail "case-3 expected rc=0 got=$HOOK_RC"
|
|
78
|
+
elif [[ -n "$HOOK_STDERR" ]]; then fail "case-3 expected empty stderr, got: $HOOK_STDERR"
|
|
79
|
+
else pass "case-3 empty stdin → silent (rc=0)"
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# --- Case 4: missing transcript_path → silent -------------------------
|
|
83
|
+
BAD_ENVELOPE='{"session_id":"x"}'
|
|
84
|
+
run_hook "admin" "0" "$BAD_ENVELOPE"
|
|
85
|
+
if [[ "$HOOK_RC" -ne 0 ]]; then fail "case-4 expected rc=0 got=$HOOK_RC"
|
|
86
|
+
elif [[ -n "$HOOK_STDERR" ]]; then fail "case-4 expected empty stderr, got: $HOOK_STDERR"
|
|
87
|
+
else pass "case-4 missing transcript_path → silent (rc=0)"
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# --- Case 5: happy path → POST attempt + log line ---------------------
|
|
91
|
+
# Use a deliberately closed port; curl returns non-zero, which is fine —
|
|
92
|
+
# the hook fires fire-and-forget and ignores curl's exit. We assert on
|
|
93
|
+
# the log line and exit code only.
|
|
94
|
+
MANAGER_PORT=1
|
|
95
|
+
run_hook "admin" "0" "$ENVELOPE"
|
|
96
|
+
unset MANAGER_PORT
|
|
97
|
+
if [[ "$HOOK_RC" -ne 0 ]]; then
|
|
98
|
+
fail "case-5 expected rc=0 got=$HOOK_RC stderr=$HOOK_STDERR"
|
|
99
|
+
elif ! echo "$HOOK_STDERR" | grep -q "^turn-completed-graph-write fired conversationId=abcd1234 tail-bytes="; then
|
|
100
|
+
fail "case-5 expected fired log line, got: $HOOK_STDERR"
|
|
101
|
+
else
|
|
102
|
+
pass "case-5 admin foreground → fired log line emitted"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# --- Summary ------------------------------------------------------------
|
|
106
|
+
echo "---"
|
|
107
|
+
echo "PASSED: $PASS FAILED: $FAIL"
|
|
108
|
+
[[ "$FAIL" -eq 0 ]] || exit 1
|
|
109
|
+
exit 0
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Stop hook — fires on every completed admin-agent turn and dispatches one
|
|
3
|
+
# background PTY against `specialists:database-operator` with the just-
|
|
4
|
+
# completed turn payload as stdin. The hidden PTY is the only writer to the
|
|
5
|
+
# Neo4j graph; the admin agent stays focused on the operator's request.
|
|
6
|
+
#
|
|
7
|
+
# Gating:
|
|
8
|
+
# - MAXY_SESSION_ROLE must equal "admin" (skip public PTYs)
|
|
9
|
+
# - MAXY_HIDDEN_SPAWN must equal "0" (skip recursive fires from the
|
|
10
|
+
# hidden database-operator PTY itself; without this gate every
|
|
11
|
+
# recorder turn would spawn another recorder forever)
|
|
12
|
+
#
|
|
13
|
+
# Input: Claude Code's Stop hook stdin shape
|
|
14
|
+
# { "session_id": "<intrinsic>", "transcript_path": "<jsonl path>", ... }
|
|
15
|
+
#
|
|
16
|
+
# Output: one log line per fire on the user-facing session's stderr
|
|
17
|
+
# `turn-completed-graph-write fired conversationId=<8> tail-bytes=<n> ms=<n>`
|
|
18
|
+
#
|
|
19
|
+
# Failure modes are silent (exit 0) — this hook is observability + write
|
|
20
|
+
# orchestration; a failure here must never break the operator's session.
|
|
21
|
+
|
|
22
|
+
set -uo pipefail
|
|
23
|
+
|
|
24
|
+
START_MS=$(python3 -c 'import time; print(int(time.time()*1000))')
|
|
25
|
+
|
|
26
|
+
# Gate 1: only fire on admin foreground PTYs.
|
|
27
|
+
if [ "${MAXY_SESSION_ROLE:-}" != "admin" ]; then
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
if [ "${MAXY_HIDDEN_SPAWN:-0}" = "1" ]; then
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Gate 2: stdin must be a JSON envelope. Fail-open on parse failure.
|
|
35
|
+
if [ -t 0 ]; then
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
INPUT=$(cat)
|
|
39
|
+
if [ -z "$INPUT" ]; then
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Extract session_id and transcript_path via python3 (grep on JSON is
|
|
44
|
+
# fragile when values carry escaped quotes).
|
|
45
|
+
PARSED=$(printf '%s' "$INPUT" | python3 -c '
|
|
46
|
+
import sys, json
|
|
47
|
+
try:
|
|
48
|
+
d = json.load(sys.stdin)
|
|
49
|
+
sid = d.get("session_id", "") or ""
|
|
50
|
+
tpath = d.get("transcript_path", "") or ""
|
|
51
|
+
print(f"{sid}\t{tpath}")
|
|
52
|
+
except Exception:
|
|
53
|
+
print("\t")
|
|
54
|
+
' 2>/dev/null)
|
|
55
|
+
SESSION_ID="${PARSED%% *}"
|
|
56
|
+
TRANSCRIPT_PATH="${PARSED#* }"
|
|
57
|
+
|
|
58
|
+
if [ -z "$SESSION_ID" ] || [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; then
|
|
59
|
+
exit 0
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Read last 64 KiB of the transcript — enough for one completed turn
|
|
63
|
+
# including a moderate tool transcript, bounded so the POST body never
|
|
64
|
+
# balloons. tail -c is portable across BSD and GNU.
|
|
65
|
+
TAIL_BYTES=$(wc -c < "$TRANSCRIPT_PATH" 2>/dev/null | tr -d ' ')
|
|
66
|
+
TAIL_BYTES="${TAIL_BYTES:-0}"
|
|
67
|
+
TURN_TAIL=$(tail -c 65536 "$TRANSCRIPT_PATH" 2>/dev/null)
|
|
68
|
+
|
|
69
|
+
# Manager port — environment override or compile-time default. The
|
|
70
|
+
# installer's systemd unit stamps CLAUDE_SESSION_MANAGER_PORT so this
|
|
71
|
+
# resolves to the brand's loopback port at runtime.
|
|
72
|
+
MANAGER_PORT="${CLAUDE_SESSION_MANAGER_PORT:-19400}"
|
|
73
|
+
|
|
74
|
+
# Build the /spawn body. The recorder gets the raw transcript tail in
|
|
75
|
+
# stdinPayload; the recorder agent parses the JSONL records itself
|
|
76
|
+
# (admin-agent JSONL is more authoritative than any post-hoc summary the
|
|
77
|
+
# hook could synthesise).
|
|
78
|
+
SPAWN_BODY=$(python3 -c '
|
|
79
|
+
import sys, json
|
|
80
|
+
sid = sys.argv[1]
|
|
81
|
+
tail = sys.argv[2]
|
|
82
|
+
body = {
|
|
83
|
+
"senderId": "turn-recorder",
|
|
84
|
+
"role": "admin",
|
|
85
|
+
"channel": "browser",
|
|
86
|
+
"hidden": True,
|
|
87
|
+
"specialist": "database-operator",
|
|
88
|
+
"stdinPayload": json.dumps({
|
|
89
|
+
"conversationId": sid,
|
|
90
|
+
"occurredAt": __import__("datetime").datetime.utcnow().isoformat() + "Z",
|
|
91
|
+
"transcriptTail": tail,
|
|
92
|
+
}),
|
|
93
|
+
}
|
|
94
|
+
print(json.dumps(body))
|
|
95
|
+
' "$SESSION_ID" "$TURN_TAIL" 2>/dev/null)
|
|
96
|
+
|
|
97
|
+
if [ -z "$SPAWN_BODY" ]; then
|
|
98
|
+
exit 0
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Fire-and-forget POST. The manager returns 200 on URL capture (~2 s);
|
|
102
|
+
# we do not wait for it. curl is preferred (universally present on
|
|
103
|
+
# Linux/macOS) — failure is silent.
|
|
104
|
+
curl -sS -X POST \
|
|
105
|
+
-H 'Content-Type: application/json' \
|
|
106
|
+
--max-time 5 \
|
|
107
|
+
--data "$SPAWN_BODY" \
|
|
108
|
+
"http://127.0.0.1:${MANAGER_PORT}/spawn" >/dev/null 2>&1 &
|
|
109
|
+
|
|
110
|
+
END_MS=$(python3 -c 'import time; print(int(time.time()*1000))')
|
|
111
|
+
ELAPSED=$((END_MS - START_MS))
|
|
112
|
+
echo "turn-completed-graph-write fired conversationId=${SESSION_ID:0:8} tail-bytes=${TAIL_BYTES} ms=${ELAPSED}" >&2
|
|
113
|
+
|
|
114
|
+
exit 0
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Safely extract a zip archive the admin has uploaded, inventory its contents, and propose one concrete follow-up per entry class — refusing archives that attempt path traversal, symlink escape, or decompression-bomb pathologies.
|
|
4
4
|
|
|
5
|
-
**Invoked
|
|
5
|
+
**Invoked by the admin agent directly.** Admin owns all unzipping: the operator drops a zip, admin runs this skill against the attachment, then forwards the extracted tree to the appropriate downstream specialist — `specialists:content-producer` for static-site zips carrying a host-website / publish-site / put-online intent (it chains into `publish-site` on the extracted tree), and `specialists:librarian` for graph-bound archives (LinkedIn exports, conversation transcripts, loose PDFs, etc.). The skill itself does not dispatch; it extracts safely, inventories the result, and surfaces the post-unzip contents so admin can route.
|
|
6
6
|
|
|
7
7
|
## When to Use
|
|
8
8
|
|
|
@@ -23,6 +23,17 @@ tools:
|
|
|
23
23
|
always: false
|
|
24
24
|
embed: false
|
|
25
25
|
metadata: {"platform":{}}
|
|
26
|
+
mcp:
|
|
27
|
+
command: node
|
|
28
|
+
args:
|
|
29
|
+
- ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
|
|
30
|
+
- ${PLATFORM_ROOT}/plugins/contacts/mcp/dist/index.js
|
|
31
|
+
env:
|
|
32
|
+
MCP_SPAWN_TEE_NAME: contacts
|
|
33
|
+
LOG_DIR: ${LOG_DIR}
|
|
34
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
35
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
36
|
+
SESSION_ID: ${SESSION_ID}
|
|
26
37
|
---
|
|
27
38
|
|
|
28
39
|
# Contacts
|
|
@@ -458,6 +458,16 @@ The SDK's per-tool override is `_meta["anthropic/alwaysLoad"]: true` on each MCP
|
|
|
458
458
|
|
|
459
459
|
**Observability.** Spawn-time emit: `[tool-surface] session=<convId> permission_allowed=N eager_intent=E eager_set_size=T`. Turn-end emit: `[admin-agent] turn-end ... toolsearch=N toolsearch_unique=U`. A non-zero `toolsearch` on a fresh turn for an eager-intended tool means a plugin reverted to `server.tool()` — fix at the plugin's MCP registration site, not the allow-list.
|
|
460
460
|
|
|
461
|
+
## Spawn-time MCP and subagent registration
|
|
462
|
+
|
|
463
|
+
Each `claude` PTY spawn (admin or public) registers every callable MCP server and every dispatchable subagent before the operator's first turn. The session manager writes a per-spawn `mcp-config.json` to a scratch directory and passes it as `--mcp-config <path>` on the PTY argv. The file contains every plugin's `mcp:` block from its `PLUGIN.md` — `{command, args, env}` — with `${PLATFORM_ROOT}`, `${ACCOUNT_ID}`, `${SESSION_ID}`, and `${LOG_DIR}` expanded at write time. Admin sessions get every plugin; public sessions get only the plugins that expose at least one `publicAllowlist: true` tool. The descriptor's `command` routes through `lib/mcp-spawn-tee/dist/index.js` so each child server's stderr lands in `${LOG_DIR}/mcp-<name>-stderr-<date>.log` even on synchronous module-load throws (Task 743 wrapper).
|
|
464
|
+
|
|
465
|
+
For subagents, the same spawn pushes `--add-dir` for every bundled plugin agents directory (`platform/plugins/*/agents/`, `premium-plugins/*/agents/`) — both roles — plus the per-account specialists directory `<accountDir>/specialists/agents/` (admin only). Claude Code's `subagent_type` dispatch reads the agent file off disk via the added directories; without `--add-dir` the dispatcher returns "no matching agent."
|
|
466
|
+
|
|
467
|
+
A boot gate refuses to start the manager when any admin-allowlisted tool `mcp__<plugin>__*` lacks a registered server. The signal is `boot-failed reason=mcp-allowlist-without-server plugin=<p> tool=<t>` followed by `process.exit(1)`. The remediation is a one-line edit to the named `PLUGIN.md`: add the `mcp:` block. The complementary observability emit `mcp-config-allowlist-coverage admin-tools=A admin-registered=R` (where `A === R`) confirms the invariant per boot.
|
|
468
|
+
|
|
469
|
+
**Per-spawn signals (server.log).** Every spawn emits `pty-spawn-mcp-config servers=<N> tools=<M> bytes=<B> path=<…>` once, plus one `pty-spawn-agents-dir role=<admin|public> path=<…>` per added directory. The diagnostic one-liner is `grep -E 'pty-spawn-mcp-config|pty-spawn-agents-dir|mcp-config-allowlist-coverage|boot-failed reason=mcp-allowlist' ~/.<brand>/logs/server.log | tail -50`.
|
|
470
|
+
|
|
461
471
|
## Tool Call Audit Trail
|
|
462
472
|
|
|
463
473
|
Every tool invocation by the admin agent produces a durable `ToolCall` node in the knowledge graph, linked to the `Conversation` that triggered it. This covers all admin agent tool calls — the full history of what the agent did, when, and in what context.
|
|
@@ -29,19 +29,22 @@ Everything {{productName}} can do is provided by a plugin. Each plugin is a self
|
|
|
29
29
|
- Tools (specific actions the agent can take, exposed via MCP servers)
|
|
30
30
|
- Reference documents (detailed knowledge loaded on demand)
|
|
31
31
|
|
|
32
|
+
**How tools and roles reach the session.** Each `claude` PTY spawn registers every plugin's MCP server and every bundled subagent directory before the operator's first turn — a per-spawn `mcp-config.json` written by the session manager and passed as `--mcp-config` on the PTY argv, plus one `--add-dir` per agents directory. Admin sessions see every plugin and every role; public sessions see only plugins with at least one public-allowlisted tool. The manager refuses to start when a plugin's `PLUGIN.md` declares tools without a matching `mcp:` block (forensic signal: `boot-failed reason=mcp-allowlist-without-server …`). See `internals.md` "Spawn-time MCP and subagent registration" for the full mechanism and `internals.md` "Tool Eagerness" for the separate ToolSearch-vs-eager registration concern.
|
|
33
|
+
|
|
32
34
|
Plugins are installed and managed through conversation. You can add marketplace plugins (like Stripe) or use {{productName}}'s built-in ones (contacts, memory, Telegram).
|
|
33
35
|
|
|
34
36
|
## Roles
|
|
35
37
|
|
|
36
|
-
{{productName}} has
|
|
38
|
+
{{productName}} has six roles it can dispatch for specific tasks — like members of your team. You don't need to configure or manage them — {{productName}} decides when to use each role and handles everything automatically. You may see activity like "Dispatching personal-assistant..." in the chat timeline when this happens.
|
|
37
39
|
|
|
38
40
|
| Role | What it does |
|
|
39
41
|
|------|-------------|
|
|
40
42
|
| Personal Assistant | Scheduling, platform administration, messaging channels, and browser automation |
|
|
41
43
|
| Project Manager | Task and project management — creating, tracking, and completing work items |
|
|
42
44
|
| Research Assistant | Web research, knowledge management, and visual production |
|
|
43
|
-
| Content Producer |
|
|
44
|
-
|
|
|
45
|
+
| Content Producer | Image generation, PDF output, and static-site hosting from prepared archives |
|
|
46
|
+
| Librarian | Foreground ingester for the memory graph — owns document ingestion (PDF / text / web), conversation-transcript ingestion (WhatsApp, Telegram, Signal, iMessage, Slack, Zoom, meeting minutes, LinkedIn DMs), LinkedIn Basic Data Exports, and post-unzip trees the admin agent forwards. Returns a structured outcome to admin per ingest. |
|
|
47
|
+
| Database Operator | Background recorder for the memory graph — a Stop hook fires this specialist as a hidden PTY after every completed admin turn, and it writes whatever the turn implied into the graph. The admin agent itself never writes; it asks, listens, and acts on what the recorder has already captured. |
|
|
45
48
|
|
|
46
49
|
Roles are installed during setup and listed when {{productName}} introduces itself. Some premium plugins add their own specialists (e.g. the writer-craft plugin adds a manuscript reviewer). Roles installed mid-session become active from the next session.
|
|
47
50
|
|
|
@@ -49,6 +52,8 @@ Roles are installed during setup and listed when {{productName}} introduces itse
|
|
|
49
52
|
|
|
50
53
|
{{productName}} maintains a graph database (Neo4j) of everything you've told it. People, conversations, preferences, and context are stored as connected nodes. When you ask {{productName}} something, it searches this graph to retrieve relevant context before responding.
|
|
51
54
|
|
|
55
|
+
**The recording loop.** A background recorder watches every completed admin-agent turn. Once your turn finishes and the reply is on screen, a Stop hook fires the `database-operator` specialist as a hidden Claude Code session with the just-completed turn as input. The recorder decides what's worth keeping and writes through the wrapped graph writers; the admin agent itself does not write to the graph. The recorder runs on a cheap fast model so the recording adds nothing to your perceived latency, and its session never appears in the sidebar or anywhere on the operator UI. To disable it for an account, remove the `Stop` hook entry from that account's `~/.<brand>/.claude/settings.json`; there is no toggle.
|
|
56
|
+
|
|
52
57
|
The memory graph is stored on your Pi. It never leaves your network.
|
|
53
58
|
|
|
54
59
|
The graph view (at `/graph`) lets you explore the memory directly. Pick a category from the filter, then type to search inside it — typing makes the canvas narrower, not wider. Drag the slider to control how many matches you see (1 to 2000). If the search shows a yellow banner saying "Vector ranking unavailable," it means the local AI ranking model is offline; results are still returned using keyword match, but ordering is less semantic until the ranker recovers.
|
|
@@ -65,7 +70,7 @@ There is no dashboard, no settings panel, no menus. Everything is done through c
|
|
|
65
70
|
|
|
66
71
|
The chat input auto-grows as you type — it expands to fit your message and shrinks back when you delete text. You can also drag the resize handle above the input to set a custom height.
|
|
67
72
|
|
|
68
|
-
The admin interface is a three-pane layout: a sidebar on the left with navigation (Sessions, People, Agents, Projects, Tasks, Artefacts) and your recent conversations; the chat in the middle; and an artefact pane on the right that opens when you select a document, click a project, or open Browser, Data, or Graph from the menu, holding the surface side-by-side with the conversation so the chat stays live while you work in it.
|
|
73
|
+
The admin interface is a three-pane layout: a sidebar on the left with navigation (Sessions, People, Agents, Projects, Tasks, Artefacts) and your recent conversations; the chat in the middle; and an artefact pane on the right that opens when you select a document, click a project, or open Browser, Data, or Graph from the menu, holding the surface side-by-side with the conversation so the chat stays live while you work in it. Above the SESSIONS group head — outside the scrolling sessions list — a borderless row holds two controls: a "+ New session" button on the left that spawns a fresh Claude Code session, and a Mode trigger on the right showing the current permission mode (Ask, Accept edits, Plan, or Auto). Both controls render as plain text-plus-icon affordances with no surrounding rectangle; hover only tints the background. Clicking the Mode trigger opens a popover downward from the row whose header reads "Mode" and lists the four permission modes with the current selection check-marked. The sidebar's nav rows swap the list view in place: Sessions shows recent conversations, Projects shows your active work projects, and Artefacts lists every KnowledgeDocument plus this account's agent templates (your admin agent's IDENTITY, SOUL, and KNOWLEDGE files plus one entry per enabled specialist). Each recent session row carries a small status dot (filled sage for alive, hollow circle for ended) so you can read the live state at a glance without parsing the subtitle. The People, Agents, and Tasks rows are graph shortcuts: clicking each opens the artefact-pane Graph filtered to every Person, every public Agent, or every Task in your account respectively, with no side-list, because the graph itself is the result. Public agents become first-class graph entities the moment you create them, with edges to their IDENTITY/SOUL/KNOWLEDGE files, edges to every knowledge document they have access to, and edges from every conversation they have handled, so a single Agents click reveals the whole shape of who knows what and who has been talking to whom. Click an artefact row to open the document. KnowledgeDocuments and your admin agent's templates are editable: type in the document and changes save automatically; specialist agent templates are read-only because they ship with Maxy and your edits would be overwritten on the next install. PDF artefacts render inline so you can read them without leaving the pane. If your browser doesn't have a built-in PDF viewer, a Download button appears instead. Artefacts that have no readable file backing them (orphan rows, files removed from disk, unsupported content types) show a one-line banner explaining the skip instead of opening to a blank pane. Click a project row to open the Graph view focused on that project's neighbourhood; clicking a second project swaps the focus rather than stacking on top. The chat and artefact divider is drag-resizable: drag the line between the columns to make either side wider; double-click it to reset to half of the available width (viewport minus sidebar), clamped to the chat and artefact min-width floors. Your chosen width is remembered across reloads. On wider screens (>1280px) all three panes are visible. The sidebar narrows at 1280px, the artefact pane hides at 1080px (Browser, Data, and Graph then open as full-window pages instead), and the sidebar collapses to a 56px icon rail at 820px. On every viewport the chat header reads left to right as a triptych: a dedicated sidebar toggle (the panel-right icon, which swaps to panel-right-open when the sidebar is showing), the brand mark next to the title in the centre, and the menu burger on the right. This header toggle is the sole sidebar-toggle button; the sidebar itself no longer carries a duplicate. Tap the sidebar toggle to show or hide the sidebar: on phones (<720px) it slides the drawer in or out, on wider screens it collapses or expands the sidebar column. The brand mark in the centre is decorative; clicks go through the dedicated toggle so the affordance is unambiguous. The drawer animation only fires on tap (220ms slide in or out); resizing your window across the 720px boundary snaps the layout without animation, so you never see a half-open flash. At ≤640px the session metadata pane stacks each label above its value instead of the desktop two-column grid, and the row of action buttons (Open in new tab / Open JSONL / Rename / Pin / Archive / End or Purge) collapses behind a single Actions trigger that opens a popover upward from the foot of the pane. Breakpoint summary: >1280px = full sidebar + chat + artefact pane (drag-resizable divider); 1280px→1080px = sidebar narrows; 1080px→820px = artefact pane hides (Browser/Data/Graph open as full-window pages instead); 820px→720px = sidebar collapses to 56px icon rail; ≤720px = sidebar becomes off-canvas drawer (vertical stack of nav, recents list, foot, the same shape as the desktop sidebar, just on top of the chat instead of beside it).
|
|
69
74
|
|
|
70
75
|
Page titles are brand-aware: the browser tab shows your product name (e.g. `Real Agent` instead of `Maxy`) on every shell — chat, graph, and data — so a non-default brand never leaks the default name in tab strips or browser history.
|
|
71
76
|
|
|
@@ -23,6 +23,17 @@ tools:
|
|
|
23
23
|
always: false
|
|
24
24
|
embed: ["admin"]
|
|
25
25
|
metadata: {"platform":{}}
|
|
26
|
+
mcp:
|
|
27
|
+
command: node
|
|
28
|
+
args:
|
|
29
|
+
- ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
|
|
30
|
+
- ${PLATFORM_ROOT}/plugins/email/mcp/dist/index.js
|
|
31
|
+
env:
|
|
32
|
+
MCP_SPAWN_TEE_NAME: email
|
|
33
|
+
LOG_DIR: ${LOG_DIR}
|
|
34
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
35
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
36
|
+
SESSION_ID: ${SESSION_ID}
|
|
26
37
|
---
|
|
27
38
|
|
|
28
39
|
# Email
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linkedin-import",
|
|
3
|
-
"description": "Import a LinkedIn Basic Data Export into the Maxy Neo4j graph. Skill-only plugin owned by the
|
|
3
|
+
"description": "Import a LinkedIn Basic Data Export into the Maxy Neo4j graph. Skill-only plugin owned by the librarian specialist. Opt-in per brand — not enabled by default.",
|
|
4
4
|
"version": "0.1.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Rubytech LLC"
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linkedin-import
|
|
3
|
-
description: "Import a LinkedIn Basic Data Export into the Maxy Neo4j graph. Skill-only plugin owned by the
|
|
3
|
+
description: "Import a LinkedIn Basic Data Export into the Maxy Neo4j graph. Skill-only plugin owned by the librarian specialist. Opt-in per brand — not enabled by default."
|
|
4
4
|
tools: []
|
|
5
5
|
always: false
|
|
6
6
|
embed: false
|
|
7
|
-
specialist:
|
|
7
|
+
specialist: librarian
|
|
8
8
|
metadata: {"platform":{"optional":true,"pluginKey":"linkedin-import"}}
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# LinkedIn Import
|
|
12
12
|
|
|
13
|
-
Ingests a LinkedIn Basic Data Export (unzipped directory of CSVs + subdirectories) into the Maxy Neo4j graph. Skill-only plugin — no MCP server, no admin tools added. The skill runs under the `specialists:
|
|
13
|
+
Ingests a LinkedIn Basic Data Export (unzipped directory of CSVs + subdirectories) into the Maxy Neo4j graph. Skill-only plugin — no MCP server, no admin tools added. The skill runs under the `specialists:librarian` specialist, which owns foreground archive and document ingestion.
|
|
14
14
|
|
|
15
15
|
## When this applies
|
|
16
16
|
|
|
17
|
-
The admin agent delegates to `specialists:
|
|
17
|
+
The admin agent delegates to `specialists:librarian` when the operator drops a `Basic_LinkedInDataExport_*` directory (or references one by path) into chat. The specialist runs the skill's archive-owner confirmation flow before any CSV is read, then ingests the CSVs the skill has references for.
|
|
18
18
|
|
|
19
19
|
## Intra-plugin growth
|
|
20
20
|
|
|
@@ -24,4 +24,4 @@ A LinkedIn export contains ~20 CSVs. The skill ships references for `Profile.csv
|
|
|
24
24
|
|
|
25
25
|
- **contacts** — waitlist-shaped CRM surface. LinkedIn-imported `:Person` nodes are visible via `contact-list`, but ingestion does not go through contact tools.
|
|
26
26
|
- **memory** — the underlying Cypher-write surface used by the skill (`memory-write`, `memory-update`). The skill is parameterised so all writes carry `source='linkedin'` + `createdByAgent='linkedin-import'` for provenance.
|
|
27
|
-
- **
|
|
27
|
+
- **librarian specialist** — owns execution. See [admin/IDENTITY.md](../../../platform/templates/agents/admin/IDENTITY.md) delegation clause.
|
|
@@ -5,6 +5,8 @@ description: Import a LinkedIn Basic Data Export into a {{productName}} Neo4j gr
|
|
|
5
5
|
|
|
6
6
|
# LinkedIn Import
|
|
7
7
|
|
|
8
|
+
**Invoked from `specialists:librarian`** when the operator drops a LinkedIn Basic Data Export (`Basic_LinkedInDataExport_*`) directory or references one by path. The admin agent dispatches the librarian; the librarian loads this skill.
|
|
9
|
+
|
|
8
10
|
**Default parent.** Every `:Person`, `:Organization`, `:Position`, `:Skill`, and `:Message` node this skill writes is anchored to the archive-owner `:Person` (the user whose LinkedIn account produced the export). That Person is itself anchored to the account's `:LocalBusiness`. The archive owner's elementId is the first thing this skill confirms — without it, every row would land as an orphan and the importer refuses to start. Cross-hierarchy edges (`CONNECTED_ON_LINKEDIN`, `WORKS_FOR`, `HAS_SKILL`) describe the relationships; the containment edge from the archive owner is what makes the rows reachable.
|
|
9
11
|
|
|
10
12
|
Ingests a LinkedIn Basic Data Export (unzipped directory of CSVs + subdirs) into a {{productName}} Neo4j graph. Every edge written corresponds to a real relationship expressed by the data — not a convenience anchor.
|
|
@@ -68,7 +70,7 @@ When the owner is an external Person (non-operator archive), the anchor is the c
|
|
|
68
70
|
4. Invoke the deterministic write tool the reference names. For all archive references this is `mcp__memory__memory-archive-write` with `{archiveType, ownerNodeId, rows}` — the Cypher body is fixed server-side per `archiveType`, so the agent supplies parsed rows, never Cypher. The tool batches rows at 500 per transaction internally.
|
|
69
71
|
5. After each file emit `[linkedin-import] file=<name> rows=<n> created=<n> matched=<n> ms=<elapsed>` using the counters returned by the write tool.
|
|
70
72
|
|
|
71
|
-
**Doctrine:** raw Cypher and `cypher-shell` invocations are forbidden in this skill and its references. Writes route through `mcp__memory__memory-archive-write` (bulk archives) or `mcp__memory__memory-write` / `mcp__memory__memory-update` (single-node enrichments like `profile.md`). If a CSV needs a write shape no current MCP tool supports, file a task to extend `memory-archive-write` with a new `archiveType` handler — never improvise via Bash. See [
|
|
73
|
+
**Doctrine:** raw Cypher and `cypher-shell` invocations are forbidden in this skill and its references. Writes route through `mcp__memory__memory-archive-write` (bulk archives) or `mcp__memory__memory-write` / `mcp__memory__memory-update` (single-node enrichments like `profile.md`). If a CSV needs a write shape no current MCP tool supports, file a task to extend `memory-archive-write` with a new `archiveType` handler — never improvise via Bash. See [librarian's LOUD-FAIL prerogative](../../../../templates/specialists/agents/librarian.md#prerogatives).
|
|
72
74
|
|
|
73
75
|
**LOUD-FAIL on parse errors (structurally enforced).** When LinkedIn parser tools land that follow the `mcp__*__*-import-parse` naming convention, the harness-level `platform/plugins/admin/hooks/archive-ingest-gate.sh` will record an `isError: true` response and block every subsequent tool call this turn until the operator submits the next prompt. The hook also denies edits to `platform/plugins/*/lib/*` and JavaScript test runners (`vitest`, `bun test`, `npm test`, `npx jest`) unconditionally. The skill's "no Bash improvisation" doctrine above is the contract; the hook is the enforcement. See [.docs/hooks.md](../../../../../.docs/hooks.md) for the full gate surface.
|
|
74
76
|
|
package/payload/platform/plugins/linkedin-import/skills/linkedin-import/references/connections.md
CHANGED
|
@@ -110,7 +110,7 @@ Rows missing a position but present with a company produce a `WORKS_FOR` edge wi
|
|
|
110
110
|
|
|
111
111
|
## Post-import verification (operator-side, not agent-side)
|
|
112
112
|
|
|
113
|
-
After ingest, the operator can verify counts via the `specialists:
|
|
113
|
+
After ingest, the operator can verify counts via the `specialists:librarian` specialist's read tools — `mcp__memory__memory-search` with `labels: ["Person"]` plus a filter, or a direct read query through `mcp__graph__maxy-graph-read_neo4j_cypher`:
|
|
114
114
|
|
|
115
115
|
```cypher
|
|
116
116
|
// Owner → connections count
|
|
@@ -132,4 +132,4 @@ These are **read queries**, not writes. Cypher writes from the agent are forbidd
|
|
|
132
132
|
| Tool error "row connectedOn is not ISO 8601" | Parser left `Connected On` in `"23 Apr 2026"` form | Convert to `YYYY-MM-DD` before passing to the tool |
|
|
133
133
|
| Tool error "ownerNodeId not found" | Owner-confirmation flow not run, or operator typed the wrong id | Re-run owner confirmation; pass the resulting `elementId` as `ownerNodeId` |
|
|
134
134
|
| `WORKS_FOR` count « connection count | Many rows have blank company | Expected — LinkedIn doesn't force connections to list a current employer |
|
|
135
|
-
| Tool not present in `init` frame | `specialists:
|
|
135
|
+
| Tool not present in `init` frame | `specialists:librarian` spawned without the `mcp__memory__memory-archive-write` token | Loud-fail per librarian's prerogatives. Do not improvise via Bash. Operator must remediate (re-seed specialist templates) |
|
|
@@ -71,6 +71,17 @@ profileKeys:
|
|
|
71
71
|
- realagent.voice_samples
|
|
72
72
|
always: false
|
|
73
73
|
metadata: {"platform":{"optional":true,"embed":["admin"]}}
|
|
74
|
+
mcp:
|
|
75
|
+
command: node
|
|
76
|
+
args:
|
|
77
|
+
- ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
|
|
78
|
+
- ${PREMIUM_PLUGINS_ROOT}/real-agent/plugins/loop/mcp/dist/index.js
|
|
79
|
+
env:
|
|
80
|
+
MCP_SPAWN_TEE_NAME: loop
|
|
81
|
+
LOG_DIR: ${LOG_DIR}
|
|
82
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
83
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
84
|
+
SESSION_ID: ${SESSION_ID}
|
|
74
85
|
---
|
|
75
86
|
|
|
76
87
|
# Real Agent — Loop CRM
|
|
@@ -72,6 +72,17 @@ skills:
|
|
|
72
72
|
- skills/archive-crawler/SKILL.md
|
|
73
73
|
always: true
|
|
74
74
|
embed: false
|
|
75
|
+
mcp:
|
|
76
|
+
command: node
|
|
77
|
+
args:
|
|
78
|
+
- ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
|
|
79
|
+
- ${PLATFORM_ROOT}/plugins/memory/mcp/dist/index.js
|
|
80
|
+
env:
|
|
81
|
+
MCP_SPAWN_TEE_NAME: memory
|
|
82
|
+
LOG_DIR: ${LOG_DIR}
|
|
83
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
84
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
85
|
+
SESSION_ID: ${SESSION_ID}
|
|
75
86
|
---
|
|
76
87
|
|
|
77
88
|
# Memory
|
|
@@ -5,6 +5,8 @@ description: Source-agnostic ingest for conversation transcripts. One skill for
|
|
|
5
5
|
|
|
6
6
|
# Conversation Archive — source-agnostic transcript ingestion
|
|
7
7
|
|
|
8
|
+
**Invoked from `specialists:librarian`** — the admin agent dispatches the librarian when the operator drops a conversation transcript; the librarian loads this skill.
|
|
9
|
+
|
|
8
10
|
**Default parent.** Every `:ConversationArchive` is anchored to the operator-confirmed owner (`:AdminUser` for the account owner, `:Person` for a third-party archive). The owner's elementId is supplied to the bash entry as `--owner-element-id` and becomes the containment parent for the archive node. Per-session `:Section:Conversation` chunks attach to the archive via `:PART_OF`. Participant cross-edges from the archive to each distinct sender (`:Person` / `:AdminUser`) are added alongside the containment edge — they describe the conversation, they do not substitute for the parent.
|
|
9
11
|
|
|
10
12
|
One skill, one bash entry, one writer. The pipeline is identical for every conversation source. The only source-specific code is the per-source normaliser (a pluggable function under [`platform/plugins/memory/mcp/src/lib/conversation-normalisers/`](../../mcp/src/lib/conversation-normalisers/)). New sources = a new normaliser file + an enum entry, never a new skill.
|
|
@@ -5,6 +5,8 @@ description: Source-agnostic Phase 2 for any `:ConversationArchive` — walks th
|
|
|
5
5
|
|
|
6
6
|
# Conversation Archive — chunk-anchored insight derivation
|
|
7
7
|
|
|
8
|
+
**Invoked from `specialists:librarian`** — the admin agent dispatches the librarian when the operator names an existing `:ConversationArchive` and asks for enrichment / derived insights; the librarian loads this skill.
|
|
9
|
+
|
|
8
10
|
One skill. Walks one `:ConversationArchive`'s chunks in pages. Per chunk, Haiku surfaces high-confidence claims via `mcp__memory__conversation-archive-derive-insights`; per claim, the operator decides `wire / skip / reject`. The tool is read-only; the only writes happen through this skill's per-row dispatch.
|
|
9
11
|
|
|
10
12
|
## When to invoke
|
|
@@ -5,6 +5,8 @@ description: Universal document ingestion — maps any unstructured document (PD
|
|
|
5
5
|
|
|
6
6
|
# Document Ingest
|
|
7
7
|
|
|
8
|
+
**Invoked from `specialists:librarian`** — the admin agent dispatches the librarian when the operator hands over a document or chat archive, and the librarian loads this skill. The admin agent never calls this skill directly.
|
|
9
|
+
|
|
8
10
|
**Default parent.** Every `:KnowledgeDocument` (document mode) and `:ConversationArchive` (chat mode) is anchored to a `:Project` when the dispatch brief names one, or to the account's `:LocalBusiness` when the document is account-scoped rather than project-scoped. The admin agent's brief carries the parent elementId; `memory-ingest` refuses the write if the parent is missing or does not exist. Brief-named entity wiring (Persons, Organizations, Tasks) creates cross-hierarchy edges from the document — never substitutes for the containment parent.
|
|
9
11
|
|
|
10
12
|
Ingests any unstructured input — documents (PDF, text, transcript, web page) and chat archives (WhatsApp `_chat.txt`) — into the graph. Every classified section becomes one `:Section` node. **Two parent shapes, one pipeline:**
|
|
@@ -203,10 +205,10 @@ Each ingest produces up to four chat messages, each at the moment it happens. Fa
|
|
|
203
205
|
|
|
204
206
|
| Step | Emitted by | Trigger | Content |
|
|
205
207
|
|---|---|---|---|
|
|
206
|
-
| 1 | Admin agent | On dispatch to
|
|
207
|
-
| 2 |
|
|
208
|
-
| 3 |
|
|
209
|
-
| 4 |
|
|
208
|
+
| 1 | Admin agent | On dispatch to librarian | "Sending `<filename>` to librarian for ingest." |
|
|
209
|
+
| 2 | Librarian (this skill) | After `memory-classify` returns ok | "Classified `<filename>` into `<N>` sections, covering: `<topicKeyword1>, <topicKeyword2>, …`." |
|
|
210
|
+
| 3 | Librarian (this skill) | After `memory-ingest` returns | "Created/connected: `<kind: count via edgeType to anchor>` for each kind; `<orphan-candidates: label and reason>` for any orphans; `<related entities created or merged: kind: count>`." |
|
|
211
|
+
| 4 | Librarian (this skill) | After `wire-brief-entities` step completes AND the brief named at least one entity | "Wired `<N>` brief entities: `<K>` Persons via `<edge>`, `<M>` Organizations via `<edge>`, `<T>` Tasks via `REFERENCES`. `<P>` entities not found in graph: `<comma-separated names>`." |
|
|
210
212
|
|
|
211
213
|
**Step 2 failure form:** "Classifier unavailable — `<reason>`. `<filename>` not ingested. `<remediation>`." Do not call step 3.
|
|
212
214
|
|
|
@@ -19,6 +19,17 @@ tools:
|
|
|
19
19
|
always: false
|
|
20
20
|
embed: ["admin"]
|
|
21
21
|
metadata: {"platform":{"optional":true}}
|
|
22
|
+
mcp:
|
|
23
|
+
command: node
|
|
24
|
+
args:
|
|
25
|
+
- ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
|
|
26
|
+
- ${PLATFORM_ROOT}/plugins/outlook/mcp/dist/index.js
|
|
27
|
+
env:
|
|
28
|
+
MCP_SPAWN_TEE_NAME: outlook
|
|
29
|
+
LOG_DIR: ${LOG_DIR}
|
|
30
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
31
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
32
|
+
SESSION_ID: ${SESSION_ID}
|
|
22
33
|
---
|
|
23
34
|
|
|
24
35
|
# Outlook
|
|
@@ -9,6 +9,17 @@ tools:
|
|
|
9
9
|
- name: replicate-key-verify
|
|
10
10
|
publicAllowlist: false
|
|
11
11
|
metadata: {"platform":{"optional":true,"recommended":true,"pluginKey":"replicate"}}
|
|
12
|
+
mcp:
|
|
13
|
+
command: node
|
|
14
|
+
args:
|
|
15
|
+
- ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
|
|
16
|
+
- ${PLATFORM_ROOT}/plugins/replicate/mcp/dist/index.js
|
|
17
|
+
env:
|
|
18
|
+
MCP_SPAWN_TEE_NAME: replicate
|
|
19
|
+
LOG_DIR: ${LOG_DIR}
|
|
20
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
21
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
22
|
+
SESSION_ID: ${SESSION_ID}
|
|
12
23
|
---
|
|
13
24
|
|
|
14
25
|
# Replicate — Image Generation
|
|
@@ -24,6 +24,17 @@ skills:
|
|
|
24
24
|
always: false
|
|
25
25
|
embed: false
|
|
26
26
|
metadata: {"platform":{}}
|
|
27
|
+
mcp:
|
|
28
|
+
command: node
|
|
29
|
+
args:
|
|
30
|
+
- ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
|
|
31
|
+
- ${PLATFORM_ROOT}/plugins/scheduling/mcp/dist/index.js
|
|
32
|
+
env:
|
|
33
|
+
MCP_SPAWN_TEE_NAME: scheduling
|
|
34
|
+
LOG_DIR: ${LOG_DIR}
|
|
35
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
36
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
37
|
+
SESSION_ID: ${SESSION_ID}
|
|
27
38
|
---
|
|
28
39
|
|
|
29
40
|
# Scheduling
|
|
@@ -31,6 +31,17 @@ tools:
|
|
|
31
31
|
- name: project-complete
|
|
32
32
|
publicAllowlist: false
|
|
33
33
|
metadata: {"platform":{"always":false,"embed":[],"pluginKey":"tasks"}}
|
|
34
|
+
mcp:
|
|
35
|
+
command: node
|
|
36
|
+
args:
|
|
37
|
+
- ${PLATFORM_ROOT}/lib/mcp-spawn-tee/dist/index.js
|
|
38
|
+
- ${PLATFORM_ROOT}/plugins/tasks/mcp/dist/index.js
|
|
39
|
+
env:
|
|
40
|
+
MCP_SPAWN_TEE_NAME: tasks
|
|
41
|
+
LOG_DIR: ${LOG_DIR}
|
|
42
|
+
PLATFORM_ROOT: ${PLATFORM_ROOT}
|
|
43
|
+
ACCOUNT_ID: ${ACCOUNT_ID}
|
|
44
|
+
SESSION_ID: ${SESSION_ID}
|
|
34
45
|
---
|
|
35
46
|
|
|
36
47
|
# Tasks
|