@rubytech/create-maxy-code 0.1.140 → 0.1.143

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 (139) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/config/brand.json +1 -1
  3. package/payload/platform/lib/graph-style/dist/index.d.ts +6 -4
  4. package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
  5. package/payload/platform/lib/graph-style/dist/index.js +10 -23
  6. package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
  7. package/payload/platform/lib/graph-style/src/index.ts +10 -20
  8. package/payload/platform/lib/graph-trash/dist/index.d.ts.map +1 -1
  9. package/payload/platform/lib/graph-trash/dist/index.js +6 -1
  10. package/payload/platform/lib/graph-trash/dist/index.js.map +1 -1
  11. package/payload/platform/lib/graph-trash/src/index.ts +6 -1
  12. package/payload/platform/neo4j/edge-annotations.json +3 -3
  13. package/payload/platform/neo4j/schema.cypher +81 -119
  14. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  15. package/payload/platform/plugins/admin/hooks/archive-ingest-surface-gate.sh +2 -2
  16. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.d.ts.map +1 -1
  17. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.js +14 -8
  18. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.js.map +1 -1
  19. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.d.ts +1 -1
  20. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.d.ts.map +1 -1
  21. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.js +10 -7
  22. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.js.map +1 -1
  23. package/payload/platform/plugins/docs/references/internals.md +1 -1
  24. package/payload/platform/plugins/docs/references/linkedin-extension.md +1 -1
  25. package/payload/platform/plugins/docs/references/neo4j.md +3 -3
  26. package/payload/platform/plugins/docs/references/plugins-guide.md +3 -2
  27. package/payload/platform/plugins/email/.claude-plugin/plugin.json +1 -1
  28. package/payload/platform/plugins/email/PLUGIN.md +3 -7
  29. package/payload/platform/plugins/email/mcp/dist/index.js +7 -46
  30. package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
  31. package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts.map +1 -1
  32. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js +4 -15
  33. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js.map +1 -1
  34. package/payload/platform/plugins/email/mcp/dist/lib/graph.d.ts +51 -43
  35. package/payload/platform/plugins/email/mcp/dist/lib/graph.d.ts.map +1 -1
  36. package/payload/platform/plugins/email/mcp/dist/lib/graph.js +223 -229
  37. package/payload/platform/plugins/email/mcp/dist/lib/graph.js.map +1 -1
  38. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js +7 -4
  39. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js.map +1 -1
  40. package/payload/platform/plugins/email/mcp/dist/tools/email-graph-query.d.ts +14 -4
  41. package/payload/platform/plugins/email/mcp/dist/tools/email-graph-query.d.ts.map +1 -1
  42. package/payload/platform/plugins/email/mcp/dist/tools/email-graph-query.js +69 -84
  43. package/payload/platform/plugins/email/mcp/dist/tools/email-graph-query.js.map +1 -1
  44. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts.map +1 -1
  45. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js +49 -64
  46. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js.map +1 -1
  47. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.d.ts.map +1 -1
  48. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js +1 -2
  49. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js.map +1 -1
  50. package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
  51. package/payload/platform/plugins/memory/PLUGIN.md +1 -1
  52. package/payload/platform/plugins/memory/bin/conversation-archive-ingest.mjs +12 -13
  53. package/payload/platform/plugins/memory/bin/conversation-archive-ingest.sh +1 -1
  54. package/payload/platform/plugins/memory/mcp/dist/index.js +17 -15
  55. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  56. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.d.ts +1 -0
  57. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.d.ts.map +1 -1
  58. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.js +3 -0
  59. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.js.map +1 -1
  60. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.d.ts +1 -1
  61. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.d.ts.map +1 -1
  62. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js +13 -7
  63. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js.map +1 -1
  64. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.d.ts +3 -0
  65. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.d.ts.map +1 -0
  66. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.js +101 -0
  67. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.js.map +1 -0
  68. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/sender-bind.d.ts.map +1 -1
  69. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/sender-bind.js +2 -1
  70. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/sender-bind.js.map +1 -1
  71. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts +5 -3
  72. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts.map +1 -1
  73. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js +12 -10
  74. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js.map +1 -1
  75. package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-schema.d.ts.map +1 -1
  76. package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-schema.js +7 -4
  77. package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-schema.js.map +1 -1
  78. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights.test.js +3 -3
  79. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights.test.js.map +1 -1
  80. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-emit.test.js +1 -1
  81. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest-emit.test.js.map +1 -1
  82. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js +47 -39
  83. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js.map +1 -1
  84. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts +7 -6
  85. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts.map +1 -1
  86. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +12 -11
  87. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
  88. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts +59 -1
  89. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
  90. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +326 -4
  91. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
  92. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +31 -27
  93. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
  94. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +72 -49
  95. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
  96. package/payload/platform/plugins/memory/references/schema-base.md +5 -6
  97. package/payload/platform/plugins/memory/skills/archive-crawler/SKILL.md +1 -1
  98. package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +16 -15
  99. package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +8 -8
  100. package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +14 -13
  101. package/payload/platform/plugins/notion-import/skills/notion-import/SKILL.md +13 -9
  102. package/payload/platform/plugins/notion-import/skills/notion-import/references/databases.md +11 -9
  103. package/payload/platform/plugins/notion-import/skills/notion-import/references/page-tree.md +12 -12
  104. package/payload/platform/plugins/scheduling/PLUGIN.md +18 -0
  105. package/payload/platform/plugins/scheduling/mcp/dist/index.js +93 -0
  106. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  107. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.d.ts +80 -0
  108. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.d.ts.map +1 -0
  109. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.js +395 -0
  110. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.js.map +1 -0
  111. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics.d.ts +16 -0
  112. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics.d.ts.map +1 -1
  113. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics.js +111 -2
  114. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics.js.map +1 -1
  115. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-archive-ics.d.ts +20 -0
  116. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-archive-ics.d.ts.map +1 -0
  117. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-archive-ics.js +63 -0
  118. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-archive-ics.js.map +1 -0
  119. package/payload/platform/plugins/scheduling/skills/daily-prep/SKILL.md +2 -2
  120. package/payload/platform/plugins/whatsapp/PLUGIN.md +1 -1
  121. package/payload/platform/plugins/x-import/.claude-plugin/plugin.json +8 -0
  122. package/payload/platform/plugins/x-import/PLUGIN.md +33 -0
  123. package/payload/platform/plugins/x-import/references/archive-shape.md +124 -0
  124. package/payload/platform/plugins/x-import/references/transcript-shape.md +121 -0
  125. package/payload/platform/plugins/x-import/skills/x-import/SKILL.md +123 -0
  126. package/payload/platform/scripts/check-no-conversation-id-leaks.mjs +1 -1
  127. package/payload/platform/templates/specialists/agents/database-operator.md +6 -2
  128. package/payload/platform/templates/specialists/agents/librarian.md +4 -4
  129. package/payload/server/public/assets/{admin-BM9aXUUh.js → admin-_pm0RRTE.js} +1 -1
  130. package/payload/server/public/assets/{data-Ds2ECtfP.js → data-b6q64Ot4.js} +1 -1
  131. package/payload/server/public/assets/{graph-BzxObKMM.js → graph-D1SVlBLb.js} +1 -1
  132. package/payload/server/public/assets/graph-labels-BiDGzVs2.js +1 -0
  133. package/payload/server/public/assets/{page-BlkBsjP2.js → page-BV6E4J2q.js} +1 -1
  134. package/payload/server/public/assets/{page-h_SA5SVQ.js → page-DwFigpyR.js} +1 -1
  135. package/payload/server/public/data.html +3 -3
  136. package/payload/server/public/graph.html +3 -3
  137. package/payload/server/public/index.html +4 -4
  138. package/payload/server/server.js +18 -21
  139. package/payload/server/public/assets/graph-labels-Dwgep_nr.js +0 -1
@@ -209,28 +209,56 @@ OPTIONS {
209
209
  };
210
210
 
211
211
  // ----------------------------------------------------------
212
- // KnowledgeDocument / Section — single-Section document ingestion
213
- // (replaces the three-level KnowledgeDocument/Section/Chunk model).
212
+ // KnowledgeDocument / Section — unified document + conversation container.
214
213
  //
215
214
  // KnowledgeDocument -[HAS_SECTION]-> Section
216
215
  // Section -[NEXT]-> Section (reading-order chain)
217
216
  // KnowledgeDocument -[PARTY]-> (Person|Organization) (contracts only)
218
217
  // KnowledgeDocument -[REFERENCES]-> (any entity) (legacy; no new writes)
218
+ // KnowledgeDocument <-[PARTICIPANT_IN]- (Person|AdminUser)
219
+ // (conversation docs only)
219
220
  //
220
- // Every classified section is one Section node. Recognised kinds carry a
221
+ // Two writer paths produce :KnowledgeDocument parents (one writer per
222
+ // algorithm; see platform/plugins/memory/mcp/src/tools/memory-ingest.ts):
223
+ // - Document path — MERGE-keyed on `attachmentId` (URL, file path, obsidian
224
+ // page, contract attachment, etc.). First-ingest re-writes sections per
225
+ // run; anchor edges to subject nodes; orphan-candidate related entities.
226
+ // - Conversation path — MERGE-keyed on `conversationIdentity`
227
+ // (= sha256(accountId + ":" + sortedParticipantElementIds)). Source-agnostic
228
+ // across WhatsApp, Telegram, Signal, LinkedIn DMs, Zoom transcript, meeting
229
+ // minutes, iMessage, Slack, Granola, Otter, Circleback — `source` is a
230
+ // property on the parent, not a separate label. Delta-append after cursor
231
+ // lookup; :PARTICIPANT_IN edges from each operator-confirmed sender; no
232
+ // anchor / orphan-related discovery.
233
+ //
234
+ // Every classified section is one :Section node. Recognised kinds carry a
221
235
  // secondary label (Section:Position, Section:Education, Section:Chapter,
222
236
  // Section:Parties, Section:Other, etc.) — anchor edges from the document
223
237
  // subject (UserProfile/LocalBusiness) point at the multi-labeled node
224
238
  // directly. The :Chunk overflow level is gone; sections store their body
225
- // inline. Identifying property remains attachmentId on KnowledgeDocument.
239
+ // inline. The two identifying properties (`attachmentId`, `conversationIdentity`)
240
+ // are mutually exclusive on any given row — every :KnowledgeDocument is keyed
241
+ // by exactly one of them.
226
242
  // ----------------------------------------------------------
227
243
 
228
244
  CREATE CONSTRAINT knowledge_doc_id_unique IF NOT EXISTS
229
245
  FOR (k:KnowledgeDocument) REQUIRE k.attachmentId IS UNIQUE;
230
246
 
247
+ // conversationIdentity — natural key for the conversation-document path.
248
+ // Per-account by composition (sha256 includes accountId). Allows multiple
249
+ // nulls so document-path rows (attachmentId-keyed) are unaffected.
250
+ CREATE CONSTRAINT knowledge_doc_conversation_identity_unique IF NOT EXISTS
251
+ FOR (k:KnowledgeDocument) REQUIRE k.conversationIdentity IS UNIQUE;
252
+
231
253
  CREATE INDEX knowledge_doc_account IF NOT EXISTS
232
254
  FOR (k:KnowledgeDocument) ON (k.accountId);
233
255
 
256
+ // (accountId, source) — used by the conversation-document writer to look up
257
+ // "every conversation from this source for this account" without scanning the
258
+ // :KnowledgeDocument label population.
259
+ CREATE INDEX knowledge_doc_account_source IF NOT EXISTS
260
+ FOR (k:KnowledgeDocument) ON (k.accountId, k.source);
261
+
234
262
  // sourceUrl — lookup index for duplicate detection when re-ingesting a URL.
235
263
  // Not unique: user may re-ingest the same URL to get updated content.
236
264
  CREATE INDEX knowledge_doc_source_url IF NOT EXISTS
@@ -272,48 +300,6 @@ OPTIONS {
272
300
  }
273
301
  };
274
302
 
275
- // ----------------------------------------------------------
276
- // ConversationArchive — chunked conversation archive.
277
- // Source-agnostic: WhatsApp `_chat.txt`, Telegram, Signal,
278
- // LinkedIn DMs, Zoom transcript, meeting minutes, iMessage, Slack — every
279
- // source flows through the same shape with `source` as the discriminator.
280
- //
281
- // :ConversationArchive parent + :Section:Conversation chunks (HAS_SECTION + NEXT chain).
282
- // MERGE-keyed on conversationIdentity = sha256(accountId + ":" + sortedParticipantElementIds).
283
- // :Section base label is shared with KnowledgeDocument's children — chunks
284
- // reuse the section_embedding vector index above and the universal fulltext
285
- // index below.
286
- //
287
- // :PARTICIPANT_IN edges from :Person/:AdminUser to :ConversationArchive are
288
- // MERGEd on every ingest (idempotent); the operator confirms each participant
289
- // up front via the conversation-archive skill flow.
290
- //
291
- // `source` is a closed enum ('whatsapp' | 'telegram' | 'signal' |
292
- // 'linkedin-messages' | 'zoom-transcript' | 'meeting-minutes' | 'imessage' |
293
- // 'slack' | 'other') — see `conversation-normalisers/types.ts`.
294
- // ----------------------------------------------------------
295
-
296
- CREATE CONSTRAINT conversation_archive_identity_unique IF NOT EXISTS
297
- FOR (a:ConversationArchive) REQUIRE a.conversationIdentity IS UNIQUE;
298
-
299
- CREATE INDEX conversation_archive_account IF NOT EXISTS
300
- FOR (a:ConversationArchive) ON (a.accountId);
301
-
302
- CREATE INDEX conversation_archive_session IF NOT EXISTS
303
- FOR (a:ConversationArchive) ON (a.createdBySession);
304
-
305
- CREATE INDEX conversation_archive_account_source IF NOT EXISTS
306
- FOR (a:ConversationArchive) ON (a.accountId, a.source);
307
-
308
- CREATE VECTOR INDEX conversation_archive_embedding IF NOT EXISTS
309
- FOR (a:ConversationArchive) ON (a.embedding)
310
- OPTIONS {
311
- indexConfig: {
312
- `vector.dimensions`: 768,
313
- `vector.similarity_function`: 'cosine'
314
- }
315
- };
316
-
317
303
  // Universal full-text BM25 index for hybrid keyword search.
318
304
  //
319
305
  // Every operator-meaningful label written by the platform is in the index union;
@@ -332,13 +318,14 @@ OPTIONS {
332
318
  // Label union — every operator-meaningful label:
333
319
  // - Business identity: LocalBusiness, Service, PriceSpecification, OpeningHoursSpecification, Organization
334
320
  // - People: Person, UserProfile, Preference, AdminUser, AccessGrant
335
- // - Knowledge: KnowledgeDocument, ConversationArchive, Section, Chunk (legacy), DigitalDocument, CreativeWork,
321
+ // - Knowledge: KnowledgeDocument, Section, Chunk (legacy), DigitalDocument, CreativeWork,
336
322
  // Question, FAQPage, DefinedTerm, Review, ImageObject
337
323
  // - Conversational: Conversation, AdminConversation, PublicConversation, Message,
338
324
  // UserMessage, AssistantMessage, ToolCall
339
325
  // - Tasks/projects/events: Task, Project, Event
340
326
  // - Workflows: Workflow, WorkflowStep, WorkflowRun, StepResult
341
- // - Email: Email, EmailAccount
327
+ // - Email: EmailAccount (config node only — email threads land on
328
+ // :KnowledgeDocument {source:'email'} since Task 321)
342
329
  // - CV/career sublabels: Position, Credential
343
330
  // - Public agents: Agent (projection of file-based public agents)
344
331
  //
@@ -350,9 +337,9 @@ OPTIONS {
350
337
  // LinkedIn imports, since edge properties are invisible to a
351
338
  // node-only fulltext index. `currentTitle` (not `title`) avoids
352
339
  // shadowing :Position.title semantics in cross-label cypher.)
353
- // - Email: subject, bodyPreview, fromName, fromAddress
354
340
  // - EmailAccount: agentAddress
355
- // - Email: screeningReason
341
+ // - Email-thread KnowledgeDocument: subject, body, messages (JSON) — covered
342
+ // by the generic body/text/description columns below.
356
343
  // - Credential: authority
357
344
  // - AccessGrant: contactValue
358
345
  // - ToolCall: toolName
@@ -364,11 +351,11 @@ OPTIONS {
364
351
  CREATE FULLTEXT INDEX entity_search IF NOT EXISTS
365
352
  FOR (n:LocalBusiness|Service|PriceSpecification|OpeningHoursSpecification|Organization
366
353
  |Person|UserProfile|Preference|AdminUser|AccessGrant
367
- |KnowledgeDocument|ConversationArchive|Section|Chunk|DigitalDocument|CreativeWork|Question|FAQPage|DefinedTerm|Review|ImageObject
354
+ |KnowledgeDocument|Section|Chunk|DigitalDocument|CreativeWork|Question|FAQPage|DefinedTerm|Review|ImageObject
368
355
  |Conversation|AdminConversation|PublicConversation|Message|UserMessage|AssistantMessage|ToolCall
369
356
  |Task|Project|Event
370
357
  |Workflow|WorkflowStep|WorkflowRun|StepResult
371
- |Email|EmailAccount
358
+ |EmailAccount
372
359
  |Position|Credential|Agent|Idea)
373
360
  ON EACH [n.name, n.firstName, n.lastName, n.givenName, n.familyName,
374
361
  n.title, n.currentTitle, n.summary, n.body, n.content, n.text, n.description, n.headline, n.abstract,
@@ -562,6 +549,27 @@ OPTIONS {
562
549
  }
563
550
  };
564
551
 
552
+ // ----------------------------------------------------------
553
+ // Meeting node — past or future calendar meetings ingested
554
+ // from an .ics archive (scheduling/schedule-archive-ics).
555
+ // Distinct from :Event (which models scheduled triggers /
556
+ // recurring action dispatchers). A :Meeting carries the
557
+ // title, start/end, location, description verbatim from the
558
+ // source VEVENT plus the importing AdminUser's account scope.
559
+ // Attendees are :Person nodes linked via (:Person)-[:ATTENDED]->(:Meeting).
560
+ // ----------------------------------------------------------
561
+
562
+ // Composite uniqueness so the same UID under two accounts
563
+ // produces two distinct :Meeting nodes. Requires Neo4j 5.7+.
564
+ CREATE CONSTRAINT meeting_account_uid_unique IF NOT EXISTS
565
+ FOR (m:Meeting) REQUIRE (m.accountId, m.uid) IS UNIQUE;
566
+
567
+ CREATE INDEX meeting_account IF NOT EXISTS
568
+ FOR (m:Meeting) ON (m.accountId);
569
+
570
+ CREATE INDEX meeting_starts_at IF NOT EXISTS
571
+ FOR (m:Meeting) ON (m.startsAt);
572
+
565
573
  // ----------------------------------------------------------
566
574
  // Workflow node — persistent named workflows with structured
567
575
  // executable steps. Each workflow has WorkflowStep children
@@ -704,68 +712,26 @@ OPTIONS {
704
712
  // ----------------------------------------------------------
705
713
 
706
714
  // ----------------------------------------------------------
707
- // Email nodepersisted inbound email messages
708
- // Platform-native. Each Email represents a single received
709
- // message, scoped to a specific recipient address (the agent's
710
- // agentAddress). Linked to EmailAccount via RECEIVED_BY.
715
+ // Email threads:KnowledgeDocument {source:'email'}
711
716
  //
712
- // Properties:
713
- // emailId — deterministic SHA-256 (primary key for dedup)
714
- // messageId — RFC 2822 Message-ID (nullable, used for threading)
715
- // inReplyTo — RFC 2822 In-Reply-To header (nullable, parent message)
716
- // toAddresses — string[] of TO recipients
717
- // ccAddresses — string[] of CC recipients
718
- // recipientAddress partition key (the agent's agentAddress)
719
- // fromAddress, fromName, subject, bodyPreview
720
- // receivedAt, fetchedAt, accountId
721
- // scope: "admin" — always admin
722
- // screening — "clean" | "suspicious" | "discarded" (Haiku classification)
723
- // screeningReason — one-line explanation from classifier
724
- // promptInjectionFlag — true if body targets an AI agent
725
- // embedding — vector (subject + bodyPreview), dims per EMBED_DIMENSIONS — absent for discarded
717
+ // Task 321 retired the legacy :Email label. Every inbound (and outbound)
718
+ // email lands as one :KnowledgeDocument per thread, keyed on
719
+ // attachmentId = sha256("email:<accountId>:<rootMessageId>"). The body
720
+ // is the verbatim chronological transcript; per-message envelopes live
721
+ // in a JSON-serialised `messages` property; address parties hang off
722
+ // the document as :Person edges (FROM/TO/CC). The email-fetch script
723
+ // writes them via storeEmailMessage in plugins/email/mcp/src/lib/graph.ts.
726
724
  //
727
- // Deduplication: emailId derived from RFC 2822 Message-ID
728
- // (primary) or SHA-256(uidValidity:uid:mailbox:recipientAddress)
729
- // when Message-ID is absent. MERGE on emailId is idempotent.
725
+ // No :Email constraints or indexes are declared. The general
726
+ // KnowledgeDocument constraints + indexes (above) already cover
727
+ // uniqueness, accountId lookup, and embedding search. Email-specific
728
+ // filtering (source='email') uses the generic accountId + source path.
730
729
  //
731
730
  // Relationships:
732
- // (Email)-[:RECEIVED_BY]->(EmailAccount)
731
+ // (KnowledgeDocument {source:'email'})-[:RECEIVED_BY]->(EmailAccount)
732
+ // (KnowledgeDocument {source:'email'})-[:FROM|:TO|:CC]->(Person)
733
733
  // ----------------------------------------------------------
734
734
 
735
- CREATE CONSTRAINT email_id_unique IF NOT EXISTS
736
- FOR (e:Email) REQUIRE e.emailId IS UNIQUE;
737
-
738
- // Composite uniqueness: one Email per messageId + accountId.
739
- // Database-level safety net for the application-level messageId pre-check
740
- // in storeEmail. Null messageId values are excluded by Neo4j constraint
741
- // semantics — UID-based fallback emails are not affected.
742
- CREATE CONSTRAINT email_message_id_account_unique IF NOT EXISTS
743
- FOR (e:Email) REQUIRE (e.messageId, e.accountId) IS UNIQUE;
744
-
745
- CREATE INDEX email_message_id IF NOT EXISTS
746
- FOR (e:Email) ON (e.messageId);
747
-
748
- CREATE INDEX email_recipient IF NOT EXISTS
749
- FOR (e:Email) ON (e.recipientAddress);
750
-
751
- CREATE INDEX email_account IF NOT EXISTS
752
- FOR (e:Email) ON (e.accountId);
753
-
754
- CREATE INDEX email_received IF NOT EXISTS
755
- FOR (e:Email) ON (e.receivedAt);
756
-
757
- CREATE INDEX email_screening IF NOT EXISTS
758
- FOR (e:Email) ON (e.screening);
759
-
760
- CREATE VECTOR INDEX email_embedding IF NOT EXISTS
761
- FOR (e:Email) ON (e.embedding)
762
- OPTIONS {
763
- indexConfig: {
764
- `vector.dimensions`: 768,
765
- `vector.similarity_function`: 'cosine'
766
- }
767
- };
768
-
769
735
  // ----------------------------------------------------------
770
736
  // AccessGrant node — per-agent, time-bound access credentials
771
737
  // Platform-native. Each AccessGrant represents a single
@@ -1203,7 +1169,8 @@ FOR (a:PostalAddress) ON (a.postalCode);
1203
1169
  // the next distillation.
1204
1170
  //
1205
1171
  // `authorshipMode` is an enum property on content-bearing labels
1206
- // (`:KnowledgeDocument`, `:Email`, `:Message`, `:SocialPost`) with
1172
+ // (`:KnowledgeDocument` (includes email threads since Task 321),
1173
+ // `:Message`, `:SocialPost`) with
1207
1174
  // values `human-only | human-led-agent-assisted | agent-led-human-reviewed
1208
1175
  // | agent-only | unknown`. Legacy nodes default to `unknown` until
1209
1176
  // reviewed via the voice-mirror backfill flow. The index lets the
@@ -1224,22 +1191,17 @@ FOR (k:KnowledgeDocument) ON (k.authorshipMode);
1224
1191
  CREATE INDEX message_authorship IF NOT EXISTS
1225
1192
  FOR (m:Message) ON (m.authorshipMode);
1226
1193
 
1227
- CREATE INDEX email_authorship IF NOT EXISTS
1228
- FOR (e:Email) ON (e.authorshipMode);
1229
-
1230
1194
  CREATE INDEX social_post_authorship IF NOT EXISTS
1231
1195
  FOR (s:SocialPost) ON (s.authorshipMode);
1232
1196
 
1233
- // :Section authorshipMode — the corpus walk includes :Section:Conversation
1234
- // chat-archive chunks. Index on the base :Section label so the per-label
1235
- // filter on authorshipMode is cheap. The conjunction with the :Conversation
1236
- // sub-label is applied at query time, not at index time.
1197
+ // :Section authorshipMode — the corpus walk includes conversation-document
1198
+ // :Section chunks (parent :KnowledgeDocument with `conversationIdentity` set)
1199
+ // alongside ordinary document sections. Index on the :Section label so the
1200
+ // authorshipMode filter is cheap; the conversation-vs-document split is
1201
+ // applied at query time via the parent's identifying property.
1237
1202
  CREATE INDEX section_authorship IF NOT EXISTS
1238
1203
  FOR (s:Section) ON (s.authorshipMode);
1239
1204
 
1240
- CREATE INDEX email_account IF NOT EXISTS
1241
- FOR (e:Email) ON (e.accountId);
1242
-
1243
1205
  CREATE INDEX social_post_account IF NOT EXISTS
1244
1206
  FOR (s:SocialPost) ON (s.accountId);
1245
1207
 
@@ -123,6 +123,11 @@
123
123
  "name": "workflows",
124
124
  "source": "./workflows",
125
125
  "version": "0.1.0"
126
+ },
127
+ {
128
+ "name": "x-import",
129
+ "source": "./x-import",
130
+ "version": "0.1.0"
126
131
  }
127
132
  ]
128
133
  }
@@ -8,7 +8,7 @@
8
8
  # blocking the legacy MCP deviation tools mechanically. The retired
9
9
  # `whatsapp-export-insight-pass` tool is replaced by Phase 2:
10
10
  # `mcp__memory__conversation-archive-derive-insights` — a read-only tool that
11
- # walks :Section:Conversation chunks of one named :ConversationArchive in
11
+ # walks :Section chunks of one named conversation-document :KnowledgeDocument in
12
12
  # pages and emits per-row proposals. The new tool is NOT in any BLOCK list
13
13
  # (the gate is allow-by-default for unrecognised tools) — its writes go
14
14
  # through the existing graph-cypher-write surface, gated by the operator per
@@ -154,7 +154,7 @@ fi
154
154
  case "$TOOL_NAME" in
155
155
  mcp__memory__whatsapp-export-parse|mcp__memory__whatsapp-export-insight-write|mcp__memory__whatsapp-export-insight-pass|mcp__memory__whatsapp-export-preview)
156
156
  emit_decision "block" "denied-mcp-legacy" \
157
- "Blocked: ${TOOL_NAME} is a retired path. generalised conversation-archive ingest — invoke 'bash platform/plugins/memory/bin/conversation-archive-ingest.sh <archive> --source whatsapp --owner-element-id <id> --participant-person-ids <csv> --scope <admin|public>' once. Normalise, sessionize, classify (mode=chat), and memory-ingest (parentLabel=ConversationArchive, source=<enum>) all run in-process."
157
+ "Blocked: ${TOOL_NAME} is a retired path. generalised conversation-archive ingest — invoke 'bash platform/plugins/memory/bin/conversation-archive-ingest.sh <archive> --source whatsapp --owner-element-id <id> --participant-person-ids <csv> --scope <admin|public>' once. Normalise, sessionize, classify (mode=chat), and memory-ingest (writes :KnowledgeDocument keyed on conversationIdentity, source=<enum>) all run in-process."
158
158
  ;;
159
159
  esac
160
160
 
@@ -1 +1 @@
1
- {"version":3,"file":"contact-erase.d.ts","sourceRoot":"","sources":["../../src/tools/contact-erase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,KAAK,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,YAAY,CAAC;AAE7D,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CA6N7B"}
1
+ {"version":3,"file":"contact-erase.d.ts","sourceRoot":"","sources":["../../src/tools/contact-erase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,KAAK,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,YAAY,CAAC;AAE7D,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAmO7B"}
@@ -81,11 +81,14 @@ export async function contactErase(params) {
81
81
  counts.messages = convCountResult.records[0].get("msgCount").low ?? 0;
82
82
  }
83
83
  }
84
- // Count Emails via personEmail
84
+ // Count email-source :KnowledgeDocument threads via Person FROM/TO/CC
85
+ // edges. Task 321 retired :Email; threads now live as
86
+ // :KnowledgeDocument {source:'email'} linked to :Person via address edges.
85
87
  if (personEmail) {
86
- const emailCountResult = await session.run(`MATCH (e:Email {accountId: $accountId})
87
- WHERE e.fromAddress = $personEmail OR $personEmail IN e.toAddresses
88
- RETURN count(e) AS emailCount`, { personEmail, accountId });
88
+ const emailCountResult = await session.run(`MATCH (kd:KnowledgeDocument {source: 'email', accountId: $accountId})
89
+ MATCH (p:Person {email: $personEmail})
90
+ WHERE (kd)-[:FROM]->(p) OR (kd)-[:TO]->(p) OR (kd)-[:CC]->(p)
91
+ RETURN count(DISTINCT kd) AS emailCount`, { personEmail, accountId });
89
92
  if (emailCountResult.records.length > 0) {
90
93
  counts.emails = emailCountResult.records[0].get("emailCount").low ?? 0;
91
94
  }
@@ -121,11 +124,14 @@ export async function contactErase(params) {
121
124
  WHERE NOT EXISTS { MATCH (m:Message)-[:PART_OF]->(c) }
122
125
  DETACH DELETE c`, { sessionId, accountId });
123
126
  }
124
- // 3c. Delete Emails matching the contact's email
127
+ // 3c. Delete email-source :KnowledgeDocument threads that mention this
128
+ // person via FROM/TO/CC edges. Task 321 retired :Email — every email
129
+ // thread is one :KnowledgeDocument {source:'email'}.
125
130
  if (personEmail) {
126
- await tx.run(`MATCH (e:Email {accountId: $accountId})
127
- WHERE e.fromAddress = $personEmail OR $personEmail IN e.toAddresses
128
- DETACH DELETE e`, { personEmail, accountId });
131
+ await tx.run(`MATCH (kd:KnowledgeDocument {source: 'email', accountId: $accountId})
132
+ MATCH (p:Person {email: $personEmail})
133
+ WHERE (kd)-[:FROM]->(p) OR (kd)-[:TO]->(p) OR (kd)-[:CC]->(p)
134
+ DETACH DELETE kd`, { personEmail, accountId });
129
135
  }
130
136
  // 3d. Delete AccessGrants via relationship
131
137
  await tx.run(`MATCH (p:Person)-[:HAS_ACCESS]->(g:AccessGrant)
@@ -1 +1 @@
1
- {"version":3,"file":"contact-erase.js","sourceRoot":"","sources":["../../src/tools/contact-erase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contact-erase.js","sourceRoot":"","sources":["../../src/tools/contact-erase.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  * Gathers all data held on a specific contact across Neo4j stores:
5
5
  * Person → AccessGrants (via relationship)
6
6
  * Person → Conversations + Messages (via Person.sessionId → Conversation.conversationId)
7
- * Person → Emails (via Person.email Email.fromAddress / toAddresses)
7
+ * Person → email-source KnowledgeDocuments (via Person.email matching the KD's FROM/TO/CC edges)
8
8
  *
9
9
  * Returns a self-contained JSON document suitable for handing to the data subject.
10
10
  */
@@ -1 +1 @@
1
- {"version":3,"file":"contact-export.d.ts","sourceRoot":"","sources":["../../src/tools/contact-export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,UAAU,oBAAoB;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,aAAa,EAAE,oBAAoB,EAAE,CAAC;IACtC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,EAAE;QACP,gBAAgB,EAAE,MAAM,CAAC;QACzB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAkJ9B"}
1
+ {"version":3,"file":"contact-export.d.ts","sourceRoot":"","sources":["../../src/tools/contact-export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,UAAU,oBAAoB;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,aAAa,EAAE,oBAAoB,EAAE,CAAC;IACtC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,EAAE;QACP,gBAAgB,EAAE,MAAM,CAAC;QACzB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAqJ9B"}
@@ -4,7 +4,7 @@
4
4
  * Gathers all data held on a specific contact across Neo4j stores:
5
5
  * Person → AccessGrants (via relationship)
6
6
  * Person → Conversations + Messages (via Person.sessionId → Conversation.conversationId)
7
- * Person → Emails (via Person.email Email.fromAddress / toAddresses)
7
+ * Person → email-source KnowledgeDocuments (via Person.email matching the KD's FROM/TO/CC edges)
8
8
  *
9
9
  * Returns a self-contained JSON document suitable for handing to the data subject.
10
10
  */
@@ -67,18 +67,21 @@ export async function contactExport(params) {
67
67
  });
68
68
  }
69
69
  }
70
- // Step 4: Gather Emails via Person.email
70
+ // Step 4: Gather email-source :KnowledgeDocument threads via Person edges.
71
+ // Task 321 retired :Email; an email thread is one :KD{source:'email'}
72
+ // with FROM/TO/CC edges to :Person.
71
73
  const emails = [];
72
74
  const personEmail = personProps.email;
73
75
  if (personEmail) {
74
- const emailResult = await session.run(`MATCH (e:Email {accountId: $accountId})
75
- WHERE e.fromAddress = $personEmail OR $personEmail IN e.toAddresses
76
- RETURN e, elementId(e) AS eNodeId
77
- ORDER BY e.receivedAt DESC`, { personEmail, accountId });
76
+ const emailResult = await session.run(`MATCH (kd:KnowledgeDocument {source: 'email', accountId: $accountId})
77
+ MATCH (p:Person {email: $personEmail})
78
+ WHERE (kd)-[:FROM]->(p) OR (kd)-[:TO]->(p) OR (kd)-[:CC]->(p)
79
+ RETURN kd, elementId(kd) AS eNodeId
80
+ ORDER BY kd.lastReceivedAt DESC`, { personEmail, accountId });
78
81
  for (const r of emailResult.records) {
79
82
  emails.push({
80
83
  nodeId: r.get("eNodeId"),
81
- properties: r.get("e").properties,
84
+ properties: r.get("kd").properties,
82
85
  });
83
86
  }
84
87
  }
@@ -1 +1 @@
1
- {"version":3,"file":"contact-export.js","sourceRoot":"","sources":["../../src/tools/contact-export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAgD9D,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B;IAE3B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IACvD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE3B,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,kBAAkB,CACrD,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAC5B,SAAS,CACV,CAAC;IAEF,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,8BAA8B;QAC9B,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC,GAAG,WAAW,mCAAmC,EACjD,WAAW,CACZ,CAAC;QAEF,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtC,MAAM,UAAU,GAAG,KAAK,IAAI,SAAS,IAAI,MAAM,IAAI,SAAS,CAAC;YAC7D,OAAO,CAAC,KAAK,CACX,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,gBAAgB;gBACtB,MAAM,EAAE,WAAW;gBACnB,UAAU;gBACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;aAChC,CAAC,CACH,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAW,CAAC;QAC1D,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAqC,CAAC;QAEhF,MAAM,MAAM,GAAmB;YAC7B,MAAM,EAAE,YAAY;YACpB,UAAU,EAAE,WAAW;SACxB,CAAC;QAEF,+CAA+C;QAC/C,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC;;yCAEmC,EACnC,EAAE,YAAY,EAAE,CACjB,CAAC;QAEF,MAAM,YAAY,GAA0B,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3E,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAW;YAClC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAqC;SAC7D,CAAC,CAAC,CAAC;QAEJ,+DAA+D;QAC/D,MAAM,aAAa,GAA2B,EAAE,CAAC;QACjD,MAAM,SAAS,GAAG,WAAW,CAAC,SAA+B,CAAC;QAE9D,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC;2CACmC,EACnC,EAAE,SAAS,EAAE,SAAS,EAAE,CACzB,CAAC;YAEF,KAAK,MAAM,UAAU,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;gBAC5C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAW,CAAC;gBACpD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAqC,CAAC;gBAE5E,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC;;;oCAG0B,EAC1B,EAAE,OAAO,EAAE,CACZ,CAAC;gBAEF,MAAM,QAAQ,GAAsB,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAChE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAW;oBAClC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAqC;iBAC7D,CAAC,CAAC,CAAC;gBAEJ,aAAa,CAAC,IAAI,CAAC;oBACjB,MAAM,EAAE,OAAO;oBACf,UAAU,EAAE,SAAS;oBACrB,QAAQ;iBACT,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,yCAAyC;QACzC,MAAM,MAAM,GAAoB,EAAE,CAAC;QACnC,MAAM,WAAW,GAAG,WAAW,CAAC,KAA2B,CAAC;QAE5D,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC;;;oCAG4B,EAC5B,EAAE,WAAW,EAAE,SAAS,EAAE,CAC3B,CAAC;YAEF,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;gBACpC,MAAM,CAAC,IAAI,CAAC;oBACV,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAW;oBAClC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAqC;iBAC7D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAEnF,OAAO,CAAC,KAAK,CACX,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,SAAS;YACjB,UAAU,EAAE,KAAK,IAAI,SAAS,IAAI,MAAM;YACxC,gBAAgB,EAAE;gBAChB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aAClC;YACD,MAAM,EAAE;gBACN,YAAY,EAAE,YAAY,CAAC,MAAM;gBACjC,aAAa,EAAE,aAAa,CAAC,MAAM;gBACnC,QAAQ,EAAE,aAAa;gBACvB,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB;YACD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;SAChC,CAAC,CACH,CAAC;QAEF,OAAO;YACL,MAAM;YACN,YAAY;YACZ,aAAa;YACb,MAAM;YACN,OAAO,EAAE;gBACP,gBAAgB,EAAE,YAAY,CAAC,MAAM;gBACrC,iBAAiB,EAAE,aAAa,CAAC,MAAM;gBACvC,YAAY,EAAE,aAAa;gBAC3B,UAAU,EAAE,MAAM,CAAC,MAAM;aAC1B;SACF,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"contact-export.js","sourceRoot":"","sources":["../../src/tools/contact-export.ts"],"names":[],"mappings":"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"}
@@ -79,7 +79,7 @@ Vector search excels at semantic meaning — "how do I contact someone" finds no
79
79
 
80
80
  Every searchable node type has its own vector index. The `memory-search` tool discovers indexes at runtime via `SHOW INDEXES` and caches the label-to-index mapping. This means new index definitions in `schema.cypher` become searchable automatically without code changes.
81
81
 
82
- Indexed labels: `Question`, `DefinedTerm`, `Review`, `Service`, `Person`, `LocalBusiness`, `PriceSpecification`, `Task`, `CreativeWork`, `DigitalDocument`, `KnowledgeDocument`, `Section`, `Chunk`, `Conversation`, `Message`, `Event`, `Workflow`, `Preference`, `Email` (19 labels total).
82
+ Indexed labels: `Question`, `DefinedTerm`, `Review`, `Service`, `Person`, `LocalBusiness`, `PriceSpecification`, `Task`, `CreativeWork`, `DigitalDocument`, `KnowledgeDocument` (includes email threads via `source:'email'` since Task 321), `Section`, `Chunk`, `Conversation`, `Message`, `Event`, `Workflow`, `Preference` (18 labels total).
83
83
 
84
84
  ### Full-text index
85
85
 
@@ -32,7 +32,7 @@ Every click produces **one `:KnowledgeDocument`** keyed on the page URL, holding
32
32
 
33
33
  Soft signals ("interested in chatting", "would love to compare notes") stay in the document body. They are never promoted to graph nodes.
34
34
 
35
- The plugin will never create `:Communication`, `:ConversationArchive`, or `:Message` nodes — those labels are reserved for other flows (live chat, archive ingest).
35
+ The plugin will never create `:Communication`, conversation-document `:KnowledgeDocument` rows (i.e. KnowledgeDocument nodes that carry `conversationIdentity`), or `:Message` nodes — those shapes are reserved for other flows (live chat, archive ingest).
36
36
 
37
37
  ## When the pill turns amber
38
38
 
@@ -39,8 +39,8 @@ If a session closes without one of the four typed end-intent tokens (Sidebar Arc
39
39
  | Page | MENTIONS | Event |
40
40
  | Meeting | MENTIONS | Person |
41
41
  | Meeting | MENTIONS | Organization |
42
- | Email | MENTIONS | Person |
43
- | Email | MENTIONS | Organization |
42
+ | KnowledgeDocument | MENTIONS | Person |
43
+ | KnowledgeDocument | MENTIONS | Organization |
44
44
  | Note | MENTIONS | Person |
45
45
  | Note | MENTIONS | Organization |
46
46
  | Idea | MENTIONS | Person |
@@ -53,7 +53,7 @@ If a session closes without one of the four typed end-intent tokens (Sidebar Arc
53
53
  | Person | AUTHORED | Report |
54
54
  | Person | AUTHORED | Page |
55
55
  | Person | AUTHORED | Note |
56
- | Email | ATTACHED_TO | Meeting |
56
+ | KnowledgeDocument | ATTACHED_TO | Meeting |
57
57
  | Page | ATTACHED_TO | Project |
58
58
  | Note | ATTACHED_TO | Project |
59
59
  | Page | REFERENCES | Page |
@@ -40,8 +40,9 @@ These are enabled during onboarding and can be added or removed at any time. Som
40
40
  | `linkedin-import` | Import a LinkedIn Basic Data Export — Profile and Connections today, more CSVs as references land | Database operator |
41
41
  | `notion-import` | Import a Notion workspace export (markdown + CSV) — pages, databases, hierarchy, attachments, schema-bounded relations, `@person` mentions account-filtered | Database operator |
42
42
  | `obsidian-import` | Import an extracted Obsidian vault — pages map to `:KnowledgeDocument`, wikilinks resolve to intra-vault pages or existing entities, tags become `:DefinedTerm`, embedded images become `:DigitalDocument`. Two-phase tool (dry-run → operator disambiguation → commit). | Database operator |
43
- | `memory/skills/conversation-archive` | Source-agnostic conversation transcript ingest. One skill for WhatsApp `_chat.txt`, Telegram, Signal, LinkedIn DMs, Zoom transcript, meeting minutes, iMessage, Slack `--source <enum>` selects the per-source normaliser. Single Bash entry — `bash platform/plugins/memory/bin/conversation-archive-ingest.sh <archive> --source <enum> --owner-element-id <id> --participant-person-ids <csv> --scope <admin\|public>` — runs normalise → operator-confirms owner + every distinct sender → sessionize at gap-hours boundaries (default 12h) → classify each session via Haiku (`memory-classify` with `mode='chat'`) into topic-bounded `:Section:Conversation` chunks → memory-ingest with `parentLabel='ConversationArchive'`, `source=<enum>`. Re-imports are delta-append. Auto-creating participants is forbidden any sender outside the operator-confirmed closed set LOUD-FAILs with `parser-miss`. Phase 0 ships only `whatsapp`; other normalisers land per-source. Distinct from the live `whatsapp` plugin (Baileys). | Database operator |
44
- | `memory/skills/conversation-archive-enrich` | Phase 2 for any named `:ConversationArchive` source-agnostic per-row insight derivation. Operator-triggered (never auto-fires on Phase 1 completion). Walks `:Section:Conversation` chunks in pages via the read-only MCP tool `mcp__memory__conversation-archive-derive-insights`; surfaces high-confidence claims for per-row operator gate (`wire / skip / reject`) over four kinds `mention`, `task`, `preference`, `observed-relationship`. Idempotent on `(elementId(chunk), kind, contentHash)` — re-runs collapse identical claims. Haiku runs on OAuth (admin-side LLM never the API key); confidence floor is a hedging-avoidance instruction in the system prompt, not a numeric post-filter. | Database operator |
43
+ | `x-import` | Import an X (Twitter) Basic Data Export tweet stream renders as one chronological transcript and ingests as a single `:KnowledgeDocument` (`source='x'`); each DM `conversationId` ingests as one conversation-document `:KnowledgeDocument` (`source='x-dm'`, keyed on `conversationIdentity`) via `conversation-archive-ingest.sh`. Mentions, replies, and quote-tweet authors resolve to `:Person` on lowercased `xHandle`; every handle and DM senderId confirms against existing nodes (no auto-create). Per-thread KD granularity and `:Post` / `:DirectMessage` labels are explicitly rejected. | Database operator |
44
+ | `memory/skills/conversation-archive` | Source-agnostic conversation transcript ingest. One skill for WhatsApp `_chat.txt`, Telegram, Signal, LinkedIn DMs, Zoom transcript, meeting minutes, iMessage, Slack, X DMs `--source <enum>` selects the per-source normaliser. Single Bash entry — `bash platform/plugins/memory/bin/conversation-archive-ingest.sh <archive> --source <enum> --owner-element-id <id> --participant-person-ids <csv> --scope <admin\|public>` — runs normalise → operator-confirms owner + every distinct sender → sessionize at gap-hours boundaries (default 12h) classify each session via Haiku (`memory-classify` with `mode='chat'`) into topic-bounded `:Section` chunks → memory-ingest with `conversationIdentity` set (writes `:KnowledgeDocument`), `source=<enum>`. Re-imports are delta-append. Auto-creating participants is forbidden any sender outside the operator-confirmed closed set LOUD-FAILs with `parser-miss`. Distinct from the live `whatsapp` plugin (Baileys). | Database operator |
45
+ | `memory/skills/conversation-archive-enrich` | Phase 2 for any named conversation-document `:KnowledgeDocument` — source-agnostic per-row insight derivation. Operator-triggered (never auto-fires on Phase 1 completion). Walks the parent's `:Section` chunks in pages via the read-only MCP tool `mcp__memory__conversation-archive-derive-insights`; surfaces high-confidence claims for per-row operator gate (`wire / skip / reject`) over four kinds — `mention`, `task`, `preference`, `observed-relationship`. Idempotent on `(elementId(chunk), kind, contentHash)` — re-runs collapse identical claims. Haiku runs on OAuth (admin-side LLM never the API key); confidence floor is a hedging-avoidance instruction in the system prompt, not a numeric post-filter. | Database operator |
45
46
 
46
47
  ### Claude Official (marketplace)
47
48
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "email",
3
- "description": "Email — dedicated email account. Retrieval: email-graph-query for stored email history, recall, and search ('what emails are in memory?', 'emails about X', 'what did Y send?'); email-read / email-search for live IMAP inbox. Sending: email-send (new), email-reply (threaded). Config: email-setup, email-status, email-auto-respond-config, email-otp-extract.",
3
+ "description": "Email — dedicated email account. Retrieval: email-graph-query for stored email-thread history as :KnowledgeDocument {source:'email'} (recall, search, 'threads about X', 'what did Y send?'); email-read / email-search for live IMAP inbox. Sending: email-send (new), email-reply (threaded). Config: email-setup, email-status, email-otp-extract.",
4
4
  "version": "0.1.0",
5
5
  "author": {
6
6
  "name": "Rubytech LLC"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: email
3
- description: "Email — dedicated email account. Retrieval: email-graph-query for stored email history, recall, and search ('what emails are in memory?', 'emails about X', 'what did Y send?'); email-read / email-search for live IMAP inbox. Sending: email-send (new), email-reply (threaded). Config: email-setup, email-status, email-auto-respond-config, email-otp-extract."
3
+ description: "Email — dedicated email account. Retrieval: email-graph-query for stored email-thread history as :KnowledgeDocument {source:'email'} (recall, search, 'threads about X', 'what did Y send?'); email-read / email-search for live IMAP inbox. Sending: email-send (new), email-reply (threaded). Config: email-setup, email-status, email-otp-extract."
4
4
  tools:
5
5
  - name: email-setup
6
6
  publicAllowlist: false
@@ -26,9 +26,6 @@ tools:
26
26
  - name: email-status
27
27
  publicAllowlist: false
28
28
  adminAllowlist: false
29
- - name: email-auto-respond-config
30
- publicAllowlist: false
31
- adminAllowlist: false
32
29
  always: false
33
30
  embed: ["admin"]
34
31
  metadata: {"platform":{}}
@@ -59,15 +56,14 @@ Manages the agent's own dedicated email account — IMAP for reading, SMTP for s
59
56
  - **Search inbox:** `email-search` — live IMAP search by sender, subject, body keyword, date range.
60
57
  - **Send:** `email-send` — new outbound email.
61
58
  - **Reply:** `email-reply` — threaded reply to an existing email by `messageId`. Supports `replyAll`.
62
- - **Recall/history:** `email-graph-query` — search stored emails in Neo4j by natural language, sender, date, direction.
59
+ - **Recall/history:** `email-graph-query` — search stored email threads in Neo4j by natural language, sender, date, direction. Each thread is one `:KnowledgeDocument {source:'email'}` carrying the verbatim chronological transcript with `:Person` `FROM`/`TO`/`CC` edges.
63
60
  - **Status:** `email-status` — connection health and configuration state.
64
- - **Auto-respond:** `email-auto-respond-config` — enable/disable automated public agent replies to inbound email.
65
61
  - **OTP:** `email-otp-extract` — poll for verification codes during service authentication.
66
62
 
67
63
  ## Retrieval paths
68
64
 
69
65
  - **Live inbox** (`email-read`, `email-search`) — real-time IMAP queries. Use for checking the inbox or reading recent messages.
70
- - **Graph history** (`email-graph-query`) — stored Email nodes in Neo4j. Use for recall, semantic search, email history questions.
66
+ - **Graph history** (`email-graph-query`) — stored email-thread `:KnowledgeDocument {source:'email'}` rows in Neo4j. Use for recall, semantic search, email history questions.
71
67
  - **General knowledge** (`memory-search`) — cross-type knowledge graph. Use when the question spans all memory, not just emails.
72
68
 
73
69
  ## Skills