@rubytech/create-maxy-code 0.1.140 → 0.1.142

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 (83) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/config/brand.json +1 -1
  3. package/payload/platform/neo4j/schema.cypher +42 -67
  4. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  5. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.d.ts.map +1 -1
  6. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.js +14 -8
  7. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.js.map +1 -1
  8. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.d.ts +1 -1
  9. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.d.ts.map +1 -1
  10. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.js +10 -7
  11. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-export.js.map +1 -1
  12. package/payload/platform/plugins/docs/references/internals.md +1 -1
  13. package/payload/platform/plugins/docs/references/neo4j.md +3 -3
  14. package/payload/platform/plugins/docs/references/plugins-guide.md +1 -0
  15. package/payload/platform/plugins/email/.claude-plugin/plugin.json +1 -1
  16. package/payload/platform/plugins/email/PLUGIN.md +3 -7
  17. package/payload/platform/plugins/email/mcp/dist/index.js +7 -46
  18. package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
  19. package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts.map +1 -1
  20. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js +4 -15
  21. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js.map +1 -1
  22. package/payload/platform/plugins/email/mcp/dist/lib/graph.d.ts +51 -43
  23. package/payload/platform/plugins/email/mcp/dist/lib/graph.d.ts.map +1 -1
  24. package/payload/platform/plugins/email/mcp/dist/lib/graph.js +223 -229
  25. package/payload/platform/plugins/email/mcp/dist/lib/graph.js.map +1 -1
  26. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js +7 -4
  27. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js.map +1 -1
  28. package/payload/platform/plugins/email/mcp/dist/tools/email-graph-query.d.ts +14 -4
  29. package/payload/platform/plugins/email/mcp/dist/tools/email-graph-query.d.ts.map +1 -1
  30. package/payload/platform/plugins/email/mcp/dist/tools/email-graph-query.js +69 -84
  31. package/payload/platform/plugins/email/mcp/dist/tools/email-graph-query.js.map +1 -1
  32. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts.map +1 -1
  33. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js +49 -64
  34. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js.map +1 -1
  35. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.d.ts.map +1 -1
  36. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js +1 -2
  37. package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js.map +1 -1
  38. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.d.ts +1 -0
  39. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.d.ts.map +1 -1
  40. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.js +3 -0
  41. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/index.js.map +1 -1
  42. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.d.ts +1 -1
  43. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.d.ts.map +1 -1
  44. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js +1 -0
  45. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js.map +1 -1
  46. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.d.ts +3 -0
  47. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.d.ts.map +1 -0
  48. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.js +101 -0
  49. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/x-dm.js.map +1 -0
  50. package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-schema.d.ts.map +1 -1
  51. package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-schema.js +7 -4
  52. package/payload/platform/plugins/memory/mcp/dist/lib/typed-edge-schema.js.map +1 -1
  53. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts +59 -1
  54. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
  55. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +322 -0
  56. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
  57. package/payload/platform/plugins/memory/references/schema-base.md +4 -4
  58. package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +2 -1
  59. package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +1 -0
  60. package/payload/platform/plugins/notion-import/skills/notion-import/SKILL.md +13 -9
  61. package/payload/platform/plugins/notion-import/skills/notion-import/references/databases.md +11 -9
  62. package/payload/platform/plugins/notion-import/skills/notion-import/references/page-tree.md +12 -12
  63. package/payload/platform/plugins/scheduling/PLUGIN.md +18 -0
  64. package/payload/platform/plugins/scheduling/mcp/dist/index.js +93 -0
  65. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  66. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.d.ts +80 -0
  67. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.d.ts.map +1 -0
  68. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.js +395 -0
  69. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.js.map +1 -0
  70. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics.d.ts +16 -0
  71. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics.d.ts.map +1 -1
  72. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics.js +111 -2
  73. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics.js.map +1 -1
  74. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-archive-ics.d.ts +20 -0
  75. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-archive-ics.d.ts.map +1 -0
  76. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-archive-ics.js +63 -0
  77. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-archive-ics.js.map +1 -0
  78. package/payload/platform/plugins/x-import/.claude-plugin/plugin.json +8 -0
  79. package/payload/platform/plugins/x-import/PLUGIN.md +33 -0
  80. package/payload/platform/plugins/x-import/references/archive-shape.md +124 -0
  81. package/payload/platform/plugins/x-import/references/transcript-shape.md +121 -0
  82. package/payload/platform/plugins/x-import/skills/x-import/SKILL.md +123 -0
  83. package/payload/platform/templates/specialists/agents/database-operator.md +6 -2
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/types.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,oBAAoB,sIAUvB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,kBAAkB,CAExE;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B;qDACiD;IACjD,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,KAAK,EAAE,eAAe,KACnB,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/types.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,oBAAoB,8IAWvB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,kBAAkB,CAExE;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B;qDACiD;IACjD,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,KAAK,EAAE,eAAe,KACnB,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC"}
@@ -23,6 +23,7 @@ export const CONVERSATION_SOURCES = [
23
23
  "meeting-minutes",
24
24
  "imessage",
25
25
  "slack",
26
+ "x-dm",
26
27
  "other",
27
28
  ];
28
29
  export function isConversationSource(s) {
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/types.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,uEAAuE;AACvE,2EAA2E;AAC3E,EAAE;AACF,yDAAyD;AACzD,uEAAuE;AACvE,wEAAwE;AACxE,0EAA0E;AAC1E,qEAAqE;AACrE,8EAA8E;AAC9E,4CAA4C;AAC5C,EAAE;AACF,gFAAgF;AAChF,uEAAuE;AACvE,0EAA0E;AAE1E,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,UAAU;IACV,UAAU;IACV,QAAQ;IACR,mBAAmB;IACnB,iBAAiB;IACjB,iBAAiB;IACjB,UAAU;IACV,OAAO;IACP,OAAO;CACC,CAAC;AAIX,MAAM,UAAU,oBAAoB,CAAC,CAAU;IAC7C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAK,oBAA0C,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/types.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,uEAAuE;AACvE,2EAA2E;AAC3E,EAAE;AACF,yDAAyD;AACzD,uEAAuE;AACvE,wEAAwE;AACxE,0EAA0E;AAC1E,qEAAqE;AACrE,8EAA8E;AAC9E,4CAA4C;AAC5C,EAAE;AACF,gFAAgF;AAChF,uEAAuE;AACvE,0EAA0E;AAE1E,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,UAAU;IACV,UAAU;IACV,QAAQ;IACR,mBAAmB;IACnB,iBAAiB;IACjB,iBAAiB;IACjB,UAAU;IACV,OAAO;IACP,MAAM;IACN,OAAO;CACC,CAAC;AAIX,MAAM,UAAU,oBAAoB,CAAC,CAAU;IAC7C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAK,oBAA0C,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { NormaliserInput, NormaliserResult } from "./types.js";
2
+ export declare function xDmNormaliser(input: NormaliserInput): NormaliserResult;
3
+ //# sourceMappingURL=x-dm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-dm.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/x-dm.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAc,MAAM,YAAY,CAAC;AAqDhF,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CA0EtE"}
@@ -0,0 +1,101 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
3
+ import { basename } from "node:path";
4
+ // ---------------------------------------------------------------------------
5
+ // x-dm — X (Twitter) Direct Message normaliser.
6
+ //
7
+ // Reads a single-conversation slice of an X archive's direct-messages export.
8
+ // The X archive ships DMs as a `.js` file with a JSONP-style assignment
9
+ // wrapper:
10
+ //
11
+ // window.YTD.direct_messages.part0 = [
12
+ // { dmConversation: { conversationId, messages: [ { messageCreate: …} ] } },
13
+ // ...
14
+ // ]
15
+ //
16
+ // Multi-conversation files are split by the x-import skill before invocation,
17
+ // one slice per conversationId — each slice is a per-conversation archive in
18
+ // the conversation-archive sense (one `:ConversationArchive` per participant
19
+ // set). The skill writes each slice as either a wrapper-preserving `.js` shim
20
+ // containing a single-element array, or a wrapper-stripped JSON array; this
21
+ // normaliser accepts both shapes.
22
+ //
23
+ // Output bodies are `<senderId>: <text>` — senderId is the X numeric user id,
24
+ // which the x-import skill maps to a confirmed `:Person` / `:AdminUser`
25
+ // elementId before invoking the bash. The bash's `parser-miss` validation
26
+ // reads the senderId prefix and checks membership in the confirmed set.
27
+ // ---------------------------------------------------------------------------
28
+ const WRAPPER_PREFIX_RE = /^\s*window\.YTD\.direct_messages(?:_group)?\.part\d+\s*=\s*/;
29
+ export function xDmNormaliser(input) {
30
+ const { filePath, accountId } = input;
31
+ if (!accountId || !accountId.trim()) {
32
+ throw new Error("x-dm: accountId is required.");
33
+ }
34
+ const rawBytes = readFileSync(filePath);
35
+ const archiveSha256 = createHash("sha256").update(rawBytes).digest("hex");
36
+ const text = decodeText(rawBytes, filePath);
37
+ const stripped = text.replace(WRAPPER_PREFIX_RE, "");
38
+ let parsed;
39
+ try {
40
+ parsed = JSON.parse(stripped);
41
+ }
42
+ catch (err) {
43
+ throw new Error(`x-dm: JSON parse failed after wrapper strip — ${err instanceof Error ? err.message : String(err)}. The file must be either a wrapper-stripped JSON array or a window.YTD.direct_messages.part0 = […] shim. file=${filePath}`);
44
+ }
45
+ if (!Array.isArray(parsed)) {
46
+ throw new Error(`x-dm: expected top-level array (post-wrapper-strip), got ${typeof parsed}. file=${filePath}`);
47
+ }
48
+ if (parsed.length !== 1) {
49
+ throw new Error(`x-dm: expected exactly one dmConversation entry in slice, got ${parsed.length}. Multi-conversation archives must be split by the x-import skill before ingest. file=${filePath}`);
50
+ }
51
+ const entry = parsed[0];
52
+ const convo = entry?.dmConversation;
53
+ if (!convo || !Array.isArray(convo.messages)) {
54
+ throw new Error(`x-dm: slice entry missing dmConversation.messages array. file=${filePath}`);
55
+ }
56
+ const messageCreates = [];
57
+ for (const env of convo.messages) {
58
+ const mc = env?.messageCreate;
59
+ if (!mc)
60
+ continue; // skip non-messageCreate envelopes (reactions, system joins)
61
+ const senderId = mc.senderId;
62
+ const createdAt = mc.createdAt;
63
+ if (!senderId || !createdAt)
64
+ continue;
65
+ const body = typeof mc.text === "string" ? mc.text : "";
66
+ messageCreates.push({ senderId, text: body, createdAt });
67
+ }
68
+ // X serialises createdAt as ISO-8601 (e.g. "2024-09-12T14:32:01.000Z").
69
+ // Sort chronologically — X archives are usually in order, but the contract
70
+ // doesn't guarantee it, so re-sorting is the deterministic primitive.
71
+ messageCreates.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
72
+ const parsedLines = messageCreates.map((m, idx) => ({
73
+ dateSent: m.createdAt,
74
+ body: `${m.senderId}: ${m.text}`,
75
+ sequenceIndex: idx,
76
+ }));
77
+ return {
78
+ parsedLines,
79
+ archiveSha256,
80
+ archiveSourceFile: basename(filePath),
81
+ counters: {
82
+ parsed: parsedLines.length,
83
+ systemSkipped: convo.messages.length - parsedLines.length,
84
+ mediaSkipped: 0,
85
+ parseErrors: 0,
86
+ },
87
+ };
88
+ }
89
+ function decodeText(bytes, filePath) {
90
+ let decoded;
91
+ try {
92
+ decoded = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
93
+ }
94
+ catch (err) {
95
+ throw new Error(`x-dm: UTF-8 decode failed — ${err instanceof Error ? err.message : String(err)}. file=${filePath}`);
96
+ }
97
+ if (decoded.charCodeAt(0) === 0xfeff)
98
+ decoded = decoded.slice(1);
99
+ return decoded;
100
+ }
101
+ //# sourceMappingURL=x-dm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-dm.js","sourceRoot":"","sources":["../../../src/lib/conversation-normalisers/x-dm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,8EAA8E;AAC9E,gDAAgD;AAChD,EAAE;AACF,8EAA8E;AAC9E,wEAAwE;AACxE,WAAW;AACX,EAAE;AACF,yCAAyC;AACzC,iFAAiF;AACjF,UAAU;AACV,MAAM;AACN,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,4EAA4E;AAC5E,kCAAkC;AAClC,EAAE;AACF,8EAA8E;AAC9E,wEAAwE;AACxE,0EAA0E;AAC1E,wEAAwE;AACxE,8EAA8E;AAE9E,MAAM,iBAAiB,GAAG,6DAA6D,CAAC;AA0BxF,MAAM,UAAU,aAAa,CAAC,KAAsB;IAClD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IACtC,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE1E,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IAErD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,iDAAiD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,kHAAkH,QAAQ,EAAE,CAC9N,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,4DAA4D,OAAO,MAAM,UAAU,QAAQ,EAAE,CAC9F,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,iEAAiE,MAAM,CAAC,MAAM,yFAAyF,QAAQ,EAAE,CAClL,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAgB,CAAC;IACvC,MAAM,KAAK,GAAG,KAAK,EAAE,cAAc,CAAC;IACpC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,iEAAiE,QAAQ,EAAE,CAC5E,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAA4D,EAAE,CAAC;IACnF,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,GAAG,EAAE,aAAa,CAAC;QAC9B,IAAI,CAAC,EAAE;YAAE,SAAS,CAAC,6DAA6D;QAChF,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC;QAC7B,MAAM,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC;QAC/B,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS;YAAE,SAAS;QACtC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,cAAc,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,wEAAwE;IACxE,2EAA2E;IAC3E,sEAAsE;IACtE,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAEtE,MAAM,WAAW,GAAiB,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QAChE,QAAQ,EAAE,CAAC,CAAC,SAAS;QACrB,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,EAAE;QAChC,aAAa,EAAE,GAAG;KACnB,CAAC,CAAC,CAAC;IAEJ,OAAO;QACL,WAAW;QACX,aAAa;QACb,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC;QACrC,QAAQ,EAAE;YACR,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM;YACzD,YAAY,EAAE,CAAC;YACf,WAAW,EAAE,CAAC;SACf;KACF,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,QAAgB;IACjD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,+BAA+B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,QAAQ,EAAE,CACpG,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM;QAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjE,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"typed-edge-schema.d.ts","sourceRoot":"","sources":["../../src/lib/typed-edge-schema.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,aAAa,CA6D7D,CAAC;AAUF,uEAAuE;AACvE,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAET;AAED,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,MAAM,CAE3C,CAAC;AAET,mGAAmG;AACnG,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,MAAM,CAStD,CAAC"}
1
+ {"version":3,"file":"typed-edge-schema.d.ts","sourceRoot":"","sources":["../../src/lib/typed-edge-schema.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,aAAa,CAgE7D,CAAC;AAUF,uEAAuE;AACvE,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAET;AAED,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,MAAM,CAE3C,CAAC;AAET,mGAAmG;AACnG,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,MAAM,CAStD,CAAC"}
@@ -56,8 +56,11 @@ export const TYPED_EDGE_ALLOWLIST = [
56
56
  { sourceLabel: "Page", edgeType: "MENTIONS", targetLabel: "Event" },
57
57
  { sourceLabel: "Meeting", edgeType: "MENTIONS", targetLabel: "Person" },
58
58
  { sourceLabel: "Meeting", edgeType: "MENTIONS", targetLabel: "Organization" },
59
- { sourceLabel: "Email", edgeType: "MENTIONS", targetLabel: "Person" },
60
- { sourceLabel: "Email", edgeType: "MENTIONS", targetLabel: "Organization" },
59
+ // Task 321 retired :Email; email threads land as :KnowledgeDocument
60
+ // {source:'email'} and the typed-edge pass picks them up via the
61
+ // KnowledgeDocument tuples below.
62
+ { sourceLabel: "KnowledgeDocument", edgeType: "MENTIONS", targetLabel: "Person" },
63
+ { sourceLabel: "KnowledgeDocument", edgeType: "MENTIONS", targetLabel: "Organization" },
61
64
  { sourceLabel: "Note", edgeType: "MENTIONS", targetLabel: "Person" },
62
65
  { sourceLabel: "Note", edgeType: "MENTIONS", targetLabel: "Organization" },
63
66
  { sourceLabel: "Idea", edgeType: "MENTIONS", targetLabel: "Person" },
@@ -72,7 +75,7 @@ export const TYPED_EDGE_ALLOWLIST = [
72
75
  { sourceLabel: "Person", edgeType: "AUTHORED", targetLabel: "Page" },
73
76
  { sourceLabel: "Person", edgeType: "AUTHORED", targetLabel: "Note" },
74
77
  // ATTACHED_TO — document or media attached to a higher-level entity.
75
- { sourceLabel: "Email", edgeType: "ATTACHED_TO", targetLabel: "Meeting" },
78
+ { sourceLabel: "KnowledgeDocument", edgeType: "ATTACHED_TO", targetLabel: "Meeting" },
76
79
  { sourceLabel: "Page", edgeType: "ATTACHED_TO", targetLabel: "Project" },
77
80
  { sourceLabel: "Note", edgeType: "ATTACHED_TO", targetLabel: "Project" },
78
81
  // REFERENCES — one prose-bearing node references another.
@@ -93,7 +96,7 @@ export const PROSE_BEARING_LABELS = [
93
96
  "Message",
94
97
  "Page",
95
98
  "Meeting",
96
- "Email",
99
+ "KnowledgeDocument",
97
100
  "Idea",
98
101
  "Note",
99
102
  "Post",
@@ -1 +1 @@
1
- {"version":3,"file":"typed-edge-schema.js","sourceRoot":"","sources":["../../src/lib/typed-edge-schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"typed-edge-schema.js","sourceRoot":"","sources":["../../src/lib/typed-edge-schema.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,wEAAwE;AACxE,oEAAoE;AACpE,mDAAmD;AACnD,EAAE;AACF,wBAAwB;AACxB,sEAAsE;AACtE,kDAAkD;AAClD,wEAAwE;AACxE,yEAAyE;AACzE,uCAAuC;AACvC,8DAA8D;AAC9D,qFAAqF;AACrF,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AACpE,iBAAiB;AACjB,EAAE;AACF,uEAAuE;AACvE,mEAAmE;AACnE,sEAAsE;AACtE,sBAAsB;AAQtB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAiC;IAChE,uCAAuC;IACvC,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE;IACrE,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE;IAEvE,wDAAwD;IACxD,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE;IAC5E,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE;IAE7E,oEAAoE;IACpE,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE;IAC/E,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE;IAChF,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE;IACrF,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE;IAEtF,4CAA4C;IAC5C,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE;IAC3E,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE;IAE5E,8DAA8D;IAC9D,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE;IAC3E,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE;IAC5E,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE;IAErE,qDAAqD;IACrD,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE;IACvE,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE;IAC7E,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE;IAC9E,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE;IACtE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE;IACpE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE;IAC1E,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE;IAC3E,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE;IACnE,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE;IACvE,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE;IAC7E,oEAAoE;IACpE,iEAAiE;IACjE,kCAAkC;IAClC,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE;IACjF,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE;IACvF,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE;IACpE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE;IAC1E,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE;IACpE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE;IAC1E,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE;IACpE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE;IAC1E,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE;IACtE,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE;IAE5E,uDAAuD;IACvD,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE;IACpE,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE;IACtE,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE;IACpE,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE;IAEpE,qEAAqE;IACrE,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE;IACrF,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE;IACxE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE;IAExE,0DAA0D;IAC1D,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE;IACpE,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE;IACxE,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE;CACvE,CAAC;AAEF,kDAAkD;AAClD,MAAM,aAAa,GAAwB,IAAI,GAAG,CAChD,oBAAoB,CAAC,GAAG,CACtB,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,CACzC,GAAG,WAAW,IAAI,QAAQ,IAAI,WAAW,EAAE,CAC9C,CACF,CAAC;AAEF,uEAAuE;AACvE,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,QAAgB,EAChB,WAAmB;IAEnB,OAAO,aAAa,CAAC,GAAG,CAAC,GAAG,WAAW,IAAI,QAAQ,IAAI,WAAW,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAA0B,KAAK,CAAC,IAAI,CAC/D,IAAI,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CACrD,CAAC,IAAI,EAAE,CAAC;AAET,mGAAmG;AACnG,MAAM,CAAC,MAAM,oBAAoB,GAA0B;IACzD,SAAS;IACT,MAAM;IACN,SAAS;IACT,mBAAmB;IACnB,MAAM;IACN,MAAM;IACN,MAAM;IACN,QAAQ;CACT,CAAC"}
@@ -65,13 +65,69 @@ export interface ResolvedAttachment {
65
65
  /** Display alt text or null. */
66
66
  alt: string | null;
67
67
  }
68
- export type ArchiveRow = LinkedInConnectionRow | ObsidianPageRow;
68
+ /**
69
+ * One Notion page in a `notion-pages` archive call. The notion-import skill
70
+ * parses page markdown and front-matter, then submits batches of these rows.
71
+ *
72
+ * Parent semantics: `parentNotionId === null` means "top-level page" — the
73
+ * handler writes (:NotionWorkspace)-[:HAS_SECTION]->(:KnowledgeDocument) at
74
+ * insert time. Non-null parents are NOT written here; the skill submits them
75
+ * to `notion-relations-pass-2` with `edgeType: 'HAS_SECTION'` so cross-batch
76
+ * forward references resolve correctly after every page is MERGEd.
77
+ */
78
+ export interface NotionPageRow {
79
+ /** 32-hex Notion UUID. Natural key with accountId. */
80
+ notionId: string;
81
+ /** Human title from the basename. */
82
+ title: string;
83
+ /** Full markdown body, front-matter already stripped. */
84
+ text: string;
85
+ /** Null when this page is a workspace-root page. */
86
+ parentNotionId: string | null;
87
+ /** ISO 8601 datetime from front-matter `Created`, or null. */
88
+ notionCreatedAt: string | null;
89
+ /** ISO 8601 datetime from front-matter `Last edited`, or null. */
90
+ notionLastEditedAt: string | null;
91
+ /** elementId of an in-account :Person resolved by the skill, or null. */
92
+ authorPersonNodeId: string | null;
93
+ }
94
+ /**
95
+ * One row from a Notion database in a `notion-database-rows` archive call.
96
+ * The per-call `label` (one of Person, Organization, Project, Task, Event,
97
+ * KnowledgeDocument) and `databaseNotionId` live on the params, not the row.
98
+ */
99
+ export interface NotionDatabaseRowRow {
100
+ /** 32-hex Notion UUID. Natural key with accountId. */
101
+ notionId: string;
102
+ /** Mapped properties (canonical camelCase where mapped, original col names otherwise). */
103
+ properties: Record<string, string | number | boolean | null>;
104
+ }
105
+ /**
106
+ * One pass-2 relation. Source and target must already exist (MERGEd by a
107
+ * prior `notion-pages` or `notion-database-rows` call); rows whose endpoints
108
+ * are missing are counted as `skippedUnknownTarget`, not errors.
109
+ */
110
+ export interface NotionRelationRow {
111
+ sourceNotionId: string;
112
+ targetNotionId: string;
113
+ /** One of NOTION_RELATION_EDGE_TYPES. Unknown types are counted, not thrown. */
114
+ edgeType: string;
115
+ /** Edge properties (e.g. `mentionContext` for unmapped Notion relations). */
116
+ properties?: Record<string, string | number | boolean | null>;
117
+ }
118
+ export type ArchiveRow = LinkedInConnectionRow | ObsidianPageRow | NotionPageRow | NotionDatabaseRowRow | NotionRelationRow;
69
119
  export interface ArchiveWriteParams {
70
120
  archiveType: string;
71
121
  ownerNodeId: string;
72
122
  accountId: string;
73
123
  rows: ArchiveRow[];
74
124
  sessionId?: string;
125
+ /** notion-pages: UUID per import run, stamped on every created node as `importId`. */
126
+ importId?: string;
127
+ /** notion-database-rows: 32-hex Notion ID of the parent database (the `:KnowledgeDocument {kind:'notion-database'}`). */
128
+ databaseNotionId?: string;
129
+ /** notion-database-rows: one of Person|Organization|Project|Task|Event|KnowledgeDocument. */
130
+ label?: string;
75
131
  }
76
132
  export interface ArchiveWriteResult {
77
133
  archiveType: string;
@@ -114,4 +170,6 @@ export declare const OBSIDIAN_WIKILINK_PAGE_CYPHER = "\nUNWIND $pageLinks AS wl\
114
170
  export declare const OBSIDIAN_WIKILINK_ENTITY_CYPHER = "\nUNWIND $entityLinks AS wl\nMATCH (src:KnowledgeDocument {accountId: $accountId, obsidianPath: wl.fromPath})\nMATCH (dst) WHERE elementId(dst) = wl.toNodeId AND dst.accountId = $accountId\nMERGE (src)-[r:MENTIONS]->(dst)\n ON CREATE SET\n r.linkText = wl.linkText,\n r.alias = wl.alias,\n r.source = 'obsidian',\n r.createdAt = datetime()\nRETURN count(*) AS processed\n";
115
171
  export declare const OBSIDIAN_WIKILINK_STUB_CYPHER = "\nUNWIND $stubLinks AS wl\nMATCH (src:KnowledgeDocument {accountId: $accountId, obsidianPath: wl.fromPath})\nMERGE (c:Concept {accountId: $accountId, name: wl.stubName, source: 'obsidian-stub'})\n ON CREATE SET\n c.createdByAgent = 'obsidian-import',\n c.createdBySource = 'obsidian-import',\n c.createdBySession = $sessionId,\n c.createdAt = datetime(),\n c.scope = 'admin'\nMERGE (src)-[r:MENTIONS]->(c)\n ON CREATE SET\n r.linkText = wl.linkText,\n r.alias = wl.alias,\n r.source = 'obsidian',\n r.createdAt = datetime()\nRETURN count(*) AS processed\n";
116
172
  export declare const OBSIDIAN_ATTACHMENT_CYPHER = "\nUNWIND $rows AS row\nWITH row WHERE size(row.attachments) > 0\nMATCH (k:KnowledgeDocument {accountId: $accountId, obsidianPath: row.obsidianPath})\nUNWIND row.attachments AS att\nMERGE (d:DigitalDocument {accountId: $accountId, attachmentPath: att.archivePath})\n ON CREATE SET\n d.digitalDocumentId = randomUUID(),\n d.source = 'obsidian',\n d.encodingFormat = att.encodingFormat,\n d.alt = att.alt,\n d.createdByAgent = 'obsidian-import',\n d.createdBySource = 'obsidian-import',\n d.createdBySession = $sessionId,\n d.createdAt = datetime(),\n d.scope = 'admin'\nMERGE (d)-[e:EMBEDDED_IN]->(k)\n ON CREATE SET\n e.source = 'obsidian',\n e.createdAt = datetime()\nRETURN count(*) AS processed\n";
173
+ export declare const NOTION_PAGE_CYPHER = "\nMATCH (workspace:NotionWorkspace) WHERE elementId(workspace) = $ownerNodeId\nWITH workspace, $rows AS rows\nUNWIND rows AS row\nMERGE (k:KnowledgeDocument {accountId: $accountId, notionId: row.notionId})\n ON CREATE SET\n k.knowledgeDocId = randomUUID(),\n k.kind = 'notion-page',\n k.source = 'notion',\n k.createdByAgent = 'notion-import',\n k.createdBySource = 'notion-import',\n k.createdBySession = $sessionId,\n k.createdAt = datetime(),\n k.scope = 'admin',\n k.importId = $importId\nSET\n k.title = row.title,\n k.text = row.text,\n k.updatedAt = datetime()\nFOREACH (_ IN CASE WHEN row.notionCreatedAt IS NOT NULL THEN [1] ELSE [] END |\n SET k.notionCreatedAt = datetime(row.notionCreatedAt)\n)\nFOREACH (_ IN CASE WHEN row.notionLastEditedAt IS NOT NULL THEN [1] ELSE [] END |\n SET k.notionLastEditedAt = datetime(row.notionLastEditedAt)\n)\nFOREACH (_ IN CASE WHEN row.parentNotionId IS NULL THEN [1] ELSE [] END |\n MERGE (workspace)-[r:HAS_SECTION]->(k)\n ON CREATE SET r.source = 'notion', r.createdAt = datetime()\n)\nRETURN count(*) AS processed\n";
174
+ export declare const NOTION_PAGE_AUTHOR_CYPHER = "\nUNWIND $rows AS row\nWITH row WHERE row.authorPersonNodeId IS NOT NULL\nMATCH (page:KnowledgeDocument {accountId: $accountId, notionId: row.notionId})\nMATCH (author) WHERE elementId(author) = row.authorPersonNodeId AND author.accountId = $accountId\nMERGE (author)-[r:AUTHORED]->(page)\n ON CREATE SET r.source = 'notion', r.createdAt = datetime()\nRETURN count(*) AS processed\n";
117
175
  //# sourceMappingURL=memory-archive-write.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-archive-write.d.ts","sourceRoot":"","sources":["../../src/tools/memory-archive-write.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory-archive-write.d.ts","sourceRoot":"","sources":["../../src/tools/memory-archive-write.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,9 @@ const BATCH_SIZE = 500;
24
24
  const HANDLERS = {
25
25
  "linkedin-connections": linkedinConnectionsHandler(),
26
26
  "obsidian-vault": obsidianVaultHandler(),
27
+ "notion-pages": notionPagesHandler(),
28
+ "notion-database-rows": notionDatabaseRowsHandler(),
29
+ "notion-relations-pass-2": notionRelationsPass2Handler(),
27
30
  };
28
31
  // ---------------------------------------------------------------------------
29
32
  // Entry point
@@ -473,6 +476,325 @@ function normaliseObsidianRow(row) {
473
476
  attachments: Array.isArray(row.attachments) ? row.attachments : [],
474
477
  };
475
478
  }
479
+ // ---------------------------------------------------------------------------
480
+ // notion-pages / notion-database-rows / notion-relations-pass-2 handlers
481
+ // ---------------------------------------------------------------------------
482
+ //
483
+ // Notion's export shape (page tree + DB schemas + typed relations + mentions)
484
+ // does not fit the linkedin flat-row model, so the import skill splits the
485
+ // write into three archiveType calls:
486
+ //
487
+ // 1. notion-pages — MERGE every :KnowledgeDocument page,
488
+ // stamp provenance, attach workspace-root
489
+ // HAS_SECTION at insert time, optional
490
+ // AUTHORED edge. Page-to-page HAS_SECTION
491
+ // is deferred to pass-2 so cross-batch
492
+ // forward references resolve cleanly.
493
+ // 2. notion-database-rows — MERGE typed-label nodes (Person, Org,
494
+ // Project, Task, Event, KnowledgeDocument
495
+ // fallback) and the
496
+ // (:notion-database)-[:HAS_SECTION]->(row)
497
+ // edge. Per-call `label` decides which
498
+ // Cypher template runs.
499
+ // 3. notion-relations-pass-2 — MERGE all deferred relations
500
+ // (page-to-page HAS_SECTION, MENTIONS,
501
+ // WORKS_FOR, OWNS, ASSIGNED_TO, PART_OF,
502
+ // ATTENDED, AUTHORED) once every node
503
+ // exists. Source/target located by
504
+ // (accountId, notionId); missing endpoints
505
+ // count as skippedUnknownTarget.
506
+ const NOTION_RELATION_EDGE_TYPES = new Set([
507
+ "MENTIONS",
508
+ "WORKS_FOR",
509
+ "OWNS",
510
+ "ASSIGNED_TO",
511
+ "PART_OF",
512
+ "ATTENDED",
513
+ "HAS_SECTION",
514
+ "AUTHORED",
515
+ ]);
516
+ const NOTION_ROW_LABELS = new Set([
517
+ "Person",
518
+ "Organization",
519
+ "Project",
520
+ "Task",
521
+ "Event",
522
+ "KnowledgeDocument",
523
+ ]);
524
+ const NOTION_ID_RE = /^[0-9a-f]{32}$/i;
525
+ async function verifyNotionWorkspaceOwner(session, params) {
526
+ const { ownerNodeId, accountId } = params;
527
+ const result = await session.run(`MATCH (n) WHERE elementId(n) = $ownerNodeId
528
+ RETURN labels(n) AS labels, n.accountId AS accountId LIMIT 1`, { ownerNodeId });
529
+ if (result.records.length === 0) {
530
+ throw new Error(`ownerNodeId ${ownerNodeId} not found. Confirm the :NotionWorkspace node before invoking memory-archive-write.`);
531
+ }
532
+ const labels = result.records[0].get("labels") ?? [];
533
+ if (!labels.includes("NotionWorkspace")) {
534
+ throw new Error(`ownerNodeId ${ownerNodeId} has labels [${labels.join(", ")}]; expected :NotionWorkspace.`);
535
+ }
536
+ const ownerAccountId = result.records[0].get("accountId");
537
+ if (ownerAccountId && ownerAccountId !== accountId) {
538
+ throw new Error(`ownerNodeId ${ownerNodeId} belongs to account ${ownerAccountId}, not ${accountId}. Cross-account Notion ingest refused.`);
539
+ }
540
+ }
541
+ // ---- notion-pages ---------------------------------------------------------
542
+ export const NOTION_PAGE_CYPHER = `
543
+ MATCH (workspace:NotionWorkspace) WHERE elementId(workspace) = $ownerNodeId
544
+ WITH workspace, $rows AS rows
545
+ UNWIND rows AS row
546
+ MERGE (k:KnowledgeDocument {accountId: $accountId, notionId: row.notionId})
547
+ ON CREATE SET
548
+ k.knowledgeDocId = randomUUID(),
549
+ k.kind = 'notion-page',
550
+ k.source = 'notion',
551
+ k.createdByAgent = 'notion-import',
552
+ k.createdBySource = 'notion-import',
553
+ k.createdBySession = $sessionId,
554
+ k.createdAt = datetime(),
555
+ k.scope = 'admin',
556
+ k.importId = $importId
557
+ SET
558
+ k.title = row.title,
559
+ k.text = row.text,
560
+ k.updatedAt = datetime()
561
+ FOREACH (_ IN CASE WHEN row.notionCreatedAt IS NOT NULL THEN [1] ELSE [] END |
562
+ SET k.notionCreatedAt = datetime(row.notionCreatedAt)
563
+ )
564
+ FOREACH (_ IN CASE WHEN row.notionLastEditedAt IS NOT NULL THEN [1] ELSE [] END |
565
+ SET k.notionLastEditedAt = datetime(row.notionLastEditedAt)
566
+ )
567
+ FOREACH (_ IN CASE WHEN row.parentNotionId IS NULL THEN [1] ELSE [] END |
568
+ MERGE (workspace)-[r:HAS_SECTION]->(k)
569
+ ON CREATE SET r.source = 'notion', r.createdAt = datetime()
570
+ )
571
+ RETURN count(*) AS processed
572
+ `;
573
+ export const NOTION_PAGE_AUTHOR_CYPHER = `
574
+ UNWIND $rows AS row
575
+ WITH row WHERE row.authorPersonNodeId IS NOT NULL
576
+ MATCH (page:KnowledgeDocument {accountId: $accountId, notionId: row.notionId})
577
+ MATCH (author) WHERE elementId(author) = row.authorPersonNodeId AND author.accountId = $accountId
578
+ MERGE (author)-[r:AUTHORED]->(page)
579
+ ON CREATE SET r.source = 'notion', r.createdAt = datetime()
580
+ RETURN count(*) AS processed
581
+ `;
582
+ function notionPagesHandler() {
583
+ return {
584
+ async verifyArchive(session, params) {
585
+ if (!params.importId || !params.importId.trim()) {
586
+ throw new Error("notion-pages: params.importId is required (UUID per import run).");
587
+ }
588
+ await verifyNotionWorkspaceOwner(session, params);
589
+ },
590
+ async writeBatch(session, ctx) {
591
+ const { params, batchRows, sessionId } = ctx;
592
+ const rows = batchRows.map(normaliseNotionPageRow);
593
+ const queryParams = {
594
+ ownerNodeId: params.ownerNodeId,
595
+ accountId: params.accountId,
596
+ sessionId,
597
+ importId: params.importId,
598
+ rows,
599
+ };
600
+ return await session.executeWrite(async (tx) => {
601
+ const pageRes = await tx.run(NOTION_PAGE_CYPHER, queryParams);
602
+ const pageCounters = pageRes.summary.counters.updates();
603
+ const authorRes = await tx.run(NOTION_PAGE_AUTHOR_CYPHER, queryParams);
604
+ const authorCounters = authorRes.summary.counters.updates();
605
+ return {
606
+ createdPages: pageCounters.nodesCreated,
607
+ mergedPages: rows.length - pageCounters.nodesCreated,
608
+ workspaceEdgesCreated: pageCounters.relationshipsCreated,
609
+ authoredEdgesCreated: authorCounters.relationshipsCreated,
610
+ };
611
+ });
612
+ },
613
+ };
614
+ }
615
+ function normaliseNotionPageRow(row) {
616
+ if (!row.notionId || !NOTION_ID_RE.test(row.notionId)) {
617
+ throw new Error(`notion-pages row notionId="${row.notionId}" is not a 32-hex Notion UUID.`);
618
+ }
619
+ if (row.parentNotionId !== null && !NOTION_ID_RE.test(row.parentNotionId)) {
620
+ throw new Error(`notion-pages row parentNotionId="${row.parentNotionId}" is not a 32-hex Notion UUID (use null for workspace-root pages).`);
621
+ }
622
+ return {
623
+ notionId: row.notionId.toLowerCase(),
624
+ title: (row.title ?? "").trim(),
625
+ text: row.text ?? "",
626
+ parentNotionId: row.parentNotionId ? row.parentNotionId.toLowerCase() : null,
627
+ notionCreatedAt: row.notionCreatedAt ?? null,
628
+ notionLastEditedAt: row.notionLastEditedAt ?? null,
629
+ authorPersonNodeId: row.authorPersonNodeId && row.authorPersonNodeId.trim()
630
+ ? row.authorPersonNodeId.trim()
631
+ : null,
632
+ };
633
+ }
634
+ // ---- notion-database-rows -------------------------------------------------
635
+ function notionRowCypher(label) {
636
+ // The label is dispatched at handler call time from the closed NOTION_ROW_LABELS
637
+ // allowlist; string interpolation here is safe because the value is validated
638
+ // in verifyArchive before this template is built.
639
+ const docIdStamp = label === "KnowledgeDocument"
640
+ ? "n.knowledgeDocId = randomUUID(),\n n.kind = 'notion-row',"
641
+ : "";
642
+ return `
643
+ MATCH (db:KnowledgeDocument {accountId: $accountId, notionId: $databaseNotionId, kind: 'notion-database'})
644
+ WITH db, $rows AS rows
645
+ UNWIND rows AS row
646
+ MERGE (n:${label} {accountId: $accountId, notionId: row.notionId})
647
+ ON CREATE SET
648
+ ${docIdStamp}
649
+ n.source = 'notion',
650
+ n.createdByAgent = 'notion-import',
651
+ n.createdBySource = 'notion-import',
652
+ n.createdBySession = $sessionId,
653
+ n.createdAt = datetime(),
654
+ n.scope = 'admin',
655
+ n.importId = $importId
656
+ SET n += row.properties, n.updatedAt = datetime()
657
+ MERGE (db)-[r:HAS_SECTION]->(n)
658
+ ON CREATE SET r.source = 'notion', r.createdAt = datetime()
659
+ RETURN count(*) AS processed
660
+ `;
661
+ }
662
+ function notionDatabaseRowsHandler() {
663
+ return {
664
+ async verifyArchive(session, params) {
665
+ if (!params.importId || !params.importId.trim()) {
666
+ throw new Error("notion-database-rows: params.importId is required (UUID per import run).");
667
+ }
668
+ if (!params.databaseNotionId || !NOTION_ID_RE.test(params.databaseNotionId)) {
669
+ throw new Error(`notion-database-rows: params.databaseNotionId="${params.databaseNotionId}" is not a 32-hex Notion UUID.`);
670
+ }
671
+ if (!params.label || !NOTION_ROW_LABELS.has(params.label)) {
672
+ throw new Error(`notion-database-rows: params.label="${params.label}" is not in the allowlist (${Array.from(NOTION_ROW_LABELS).join(", ")}).`);
673
+ }
674
+ await verifyNotionWorkspaceOwner(session, params);
675
+ // The parent database (:KnowledgeDocument {kind:'notion-database'}) must
676
+ // already exist — the skill MERGEs it before calling notion-database-rows.
677
+ const dbRes = await session.run(`MATCH (db:KnowledgeDocument {accountId: $accountId, notionId: $databaseNotionId, kind: 'notion-database'})
678
+ RETURN count(db) AS n LIMIT 1`, { accountId: params.accountId, databaseNotionId: params.databaseNotionId });
679
+ const n = dbRes.records[0]?.get("n");
680
+ const nNum = typeof n === "number" ? n : n?.toNumber?.() ?? 0;
681
+ if (nNum === 0) {
682
+ throw new Error(`notion-database-rows: parent database :KnowledgeDocument {kind:'notion-database', notionId:'${params.databaseNotionId}'} not found for account ${params.accountId}. MERGE the database node before calling notion-database-rows.`);
683
+ }
684
+ },
685
+ async writeBatch(session, ctx) {
686
+ const { params, batchRows, sessionId } = ctx;
687
+ const label = params.label;
688
+ const rows = batchRows.map(normaliseNotionDatabaseRow);
689
+ const queryParams = {
690
+ accountId: params.accountId,
691
+ sessionId,
692
+ importId: params.importId,
693
+ databaseNotionId: params.databaseNotionId,
694
+ rows,
695
+ };
696
+ return await session.executeWrite(async (tx) => {
697
+ const res = await tx.run(notionRowCypher(label), queryParams);
698
+ const counters = res.summary.counters.updates();
699
+ return {
700
+ createdRows: counters.nodesCreated,
701
+ mergedRows: rows.length - counters.nodesCreated,
702
+ createdHasSectionEdges: counters.relationshipsCreated,
703
+ };
704
+ });
705
+ },
706
+ };
707
+ }
708
+ function normaliseNotionDatabaseRow(row) {
709
+ if (!row.notionId || !NOTION_ID_RE.test(row.notionId)) {
710
+ throw new Error(`notion-database-rows row notionId="${row.notionId}" is not a 32-hex Notion UUID.`);
711
+ }
712
+ const properties = {};
713
+ for (const [k, v] of Object.entries(row.properties ?? {})) {
714
+ if (v === undefined)
715
+ continue;
716
+ properties[k] = v;
717
+ }
718
+ return {
719
+ notionId: row.notionId.toLowerCase(),
720
+ properties,
721
+ };
722
+ }
723
+ // ---- notion-relations-pass-2 ----------------------------------------------
724
+ function notionRelationsPass2Handler() {
725
+ return {
726
+ async verifyArchive(session, params) {
727
+ await verifyNotionWorkspaceOwner(session, params);
728
+ },
729
+ async writeBatch(session, ctx) {
730
+ const { params, batchRows } = ctx;
731
+ const relations = batchRows.map(normaliseNotionRelationRow);
732
+ const byType = {};
733
+ let skippedUnknownEdgeType = 0;
734
+ for (const r of relations) {
735
+ if (!NOTION_RELATION_EDGE_TYPES.has(r.edgeType)) {
736
+ skippedUnknownEdgeType += 1;
737
+ continue;
738
+ }
739
+ (byType[r.edgeType] ??= []).push(r);
740
+ }
741
+ return await session.executeWrite(async (tx) => {
742
+ let relationsCreated = 0;
743
+ let relationsMatched = 0;
744
+ let skippedUnknownTarget = 0;
745
+ for (const [edgeType, rels] of Object.entries(byType)) {
746
+ // edgeType is validated against NOTION_RELATION_EDGE_TYPES above, so
747
+ // interpolating it into the MERGE pattern is safe.
748
+ const cypher = `
749
+ UNWIND $relations AS rel
750
+ MATCH (src {accountId: $accountId, notionId: rel.sourceNotionId})
751
+ MATCH (tgt {accountId: $accountId, notionId: rel.targetNotionId})
752
+ MERGE (src)-[r:${edgeType}]->(tgt)
753
+ ON CREATE SET r.source = 'notion', r.createdAt = datetime()
754
+ SET r += coalesce(rel.properties, {})
755
+ RETURN count(*) AS matched
756
+ `;
757
+ const res = await tx.run(cypher, {
758
+ accountId: params.accountId,
759
+ relations: rels,
760
+ });
761
+ const matchedRaw = res.records[0]?.get("matched");
762
+ const matched = typeof matchedRaw === "number"
763
+ ? matchedRaw
764
+ : matchedRaw?.toNumber?.() ?? 0;
765
+ const created = res.summary.counters.updates().relationshipsCreated;
766
+ relationsCreated += created;
767
+ relationsMatched += matched - created;
768
+ skippedUnknownTarget += rels.length - matched;
769
+ }
770
+ return {
771
+ relationsCreated,
772
+ relationsMatched,
773
+ skippedUnknownTarget,
774
+ skippedUnknownEdgeType,
775
+ };
776
+ });
777
+ },
778
+ };
779
+ }
780
+ function normaliseNotionRelationRow(row) {
781
+ if (!row.sourceNotionId || !NOTION_ID_RE.test(row.sourceNotionId)) {
782
+ throw new Error(`notion-relations-pass-2 row sourceNotionId="${row.sourceNotionId}" is not a 32-hex Notion UUID.`);
783
+ }
784
+ if (!row.targetNotionId || !NOTION_ID_RE.test(row.targetNotionId)) {
785
+ throw new Error(`notion-relations-pass-2 row targetNotionId="${row.targetNotionId}" is not a 32-hex Notion UUID.`);
786
+ }
787
+ if (!row.edgeType || !row.edgeType.trim()) {
788
+ throw new Error(`notion-relations-pass-2 row edgeType is required (one of ${Array.from(NOTION_RELATION_EDGE_TYPES).join(", ")} — unknown values are counted, not thrown).`);
789
+ }
790
+ return {
791
+ sourceNotionId: row.sourceNotionId.toLowerCase(),
792
+ targetNotionId: row.targetNotionId.toLowerCase(),
793
+ edgeType: row.edgeType,
794
+ properties: row.properties,
795
+ };
796
+ }
797
+ // ---------------------------------------------------------------------------
476
798
  function normaliseLinkedinRow(row) {
477
799
  if (!row.linkedinUrl || !row.linkedinUrl.trim()) {
478
800
  throw new Error("linkedin-connections row missing linkedinUrl (natural key).");