@datasynx/agentic-crm 1.0.0 → 1.1.0

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 (81) hide show
  1. package/README.md +8 -1
  2. package/dist/{ask-D8iYqDAr.js → ask-CDysGnRg.js} +2 -2
  3. package/dist/{ask-D8iYqDAr.js.map → ask-CDysGnRg.js.map} +1 -1
  4. package/dist/attachments-CX2GAtsw.cjs +517 -0
  5. package/dist/attachments-CX2GAtsw.cjs.map +1 -0
  6. package/dist/attachments-D207gXfN.js +514 -0
  7. package/dist/attachments-D207gXfN.js.map +1 -0
  8. package/dist/attachments-rLa96rOK.js +514 -0
  9. package/dist/attachments-rLa96rOK.js.map +1 -0
  10. package/dist/chunk-BfDYWZQ8.cjs +32 -0
  11. package/dist/chunk-BfDYWZQ8.cjs.map +1 -0
  12. package/dist/chunk-BhUZmQg5.js +32 -0
  13. package/dist/chunk-BhUZmQg5.js.map +1 -0
  14. package/dist/chunk-ChC83jai.js +2 -0
  15. package/dist/chunk-e_w8qqtP.js +32 -0
  16. package/dist/chunk-e_w8qqtP.js.map +1 -0
  17. package/dist/cli.js +16 -15
  18. package/dist/cli.js.map +1 -1
  19. package/dist/daemon/worker.js +3 -3
  20. package/dist/email-body-BFSRa0AW.cjs +42 -0
  21. package/dist/email-body-BFSRa0AW.cjs.map +1 -0
  22. package/dist/email-body-BOd7U-D2.js +42 -0
  23. package/dist/email-body-BOd7U-D2.js.map +1 -0
  24. package/dist/{gmail-sync-DueE6tl5.js → gmail-sync-B4Iu3AQb.js} +45 -15
  25. package/dist/gmail-sync-B4Iu3AQb.js.map +1 -0
  26. package/dist/{gmail-sync-GEy3oVvw.cjs → gmail-sync-BpSVESSe.cjs} +45 -15
  27. package/dist/gmail-sync-BpSVESSe.cjs.map +1 -0
  28. package/dist/{gmail-sync-C-NmibzS.js → gmail-sync-DIbrPnTK.js} +45 -15
  29. package/dist/gmail-sync-DIbrPnTK.js.map +1 -0
  30. package/dist/{gmail-webhook-handler-kGKpbY9h.js → gmail-webhook-handler-BzOFbvgh.js} +2 -2
  31. package/dist/{gmail-webhook-handler-kGKpbY9h.js.map → gmail-webhook-handler-BzOFbvgh.js.map} +1 -1
  32. package/dist/{gmail-webhook-handler-B26COilD.js → gmail-webhook-handler-CvSDW_Js.js} +1 -1
  33. package/dist/{google-drive-sync-D1n7WKZn.js → google-drive-sync-B_I1d54Y.js} +2 -2
  34. package/dist/{google-drive-sync-D1n7WKZn.js.map → google-drive-sync-B_I1d54Y.js.map} +1 -1
  35. package/dist/html-BaeOCZKE.js +36 -0
  36. package/dist/html-BaeOCZKE.js.map +1 -0
  37. package/dist/html-CmOku6jS.cjs +47 -0
  38. package/dist/html-CmOku6jS.cjs.map +1 -0
  39. package/dist/{import-hubspot-DB4n89jy.js → import-hubspot-CTId9IGV.js} +2 -2
  40. package/dist/{import-hubspot-DB4n89jy.js.map → import-hubspot-CTId9IGV.js.map} +1 -1
  41. package/dist/{index-pY7tYXwH.d.cts → index-BAutNcAT.d.cts} +13 -9
  42. package/dist/index-BAutNcAT.d.cts.map +1 -0
  43. package/dist/{index-B0IMMrp_.d.ts → index-FzDsNSSb.d.ts} +5 -1
  44. package/dist/index-FzDsNSSb.d.ts.map +1 -0
  45. package/dist/index.d.cts +13 -9
  46. package/dist/index.d.cts.map +1 -1
  47. package/dist/index.d.ts +5 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/{interactions-writer-RJB8SWf2.js → interactions-writer-B2y-73lh.js} +1 -1
  50. package/dist/{interactions-writer-DbSyI2rt.js → interactions-writer-B8XAzdqR.js} +3 -2
  51. package/dist/interactions-writer-B8XAzdqR.js.map +1 -0
  52. package/dist/{interactions-writer-a2yzBd7T.cjs → interactions-writer-BRJNrefF.cjs} +3 -2
  53. package/dist/interactions-writer-BRJNrefF.cjs.map +1 -0
  54. package/dist/{interactions-writer-BZzUIgJd.js → interactions-writer-ZQcpFOh9.js} +3 -2
  55. package/dist/interactions-writer-ZQcpFOh9.js.map +1 -0
  56. package/dist/{knowledge-base-DHNc4hVj.js → knowledge-base--063Kpa3.js} +9 -7
  57. package/dist/{knowledge-base-DHNc4hVj.js.map → knowledge-base--063Kpa3.js.map} +1 -1
  58. package/dist/mcp.cjs +44 -22
  59. package/dist/mcp.cjs.map +1 -1
  60. package/dist/mcp.js +44 -22
  61. package/dist/mcp.js.map +1 -1
  62. package/dist/{microsoft-calendar-jIu9K5zX.js → microsoft-calendar-BgVR8GDv.js} +3 -3
  63. package/dist/{microsoft-calendar-jIu9K5zX.js.map → microsoft-calendar-BgVR8GDv.js.map} +1 -1
  64. package/dist/{microsoft-sync-R_r8HL-B.js → microsoft-sync-D30_XksI.js} +3 -3
  65. package/dist/{microsoft-sync-R_r8HL-B.js.map → microsoft-sync-D30_XksI.js.map} +1 -1
  66. package/dist/{nba-mTJ4yEqD.js → nba-DwdfM93s.js} +2 -2
  67. package/dist/{nba-mTJ4yEqD.js.map → nba-DwdfM93s.js.map} +1 -1
  68. package/dist/{server-DqSMYhSA.js → server-DoRPPOeR.js} +39 -19
  69. package/dist/server-DoRPPOeR.js.map +1 -0
  70. package/dist/{transcript-watcher-0mh2ZhmH.js → transcript-watcher-BoClrJAz.js} +2 -2
  71. package/dist/{transcript-watcher-0mh2ZhmH.js.map → transcript-watcher-BoClrJAz.js.map} +1 -1
  72. package/package.json +12 -1
  73. package/dist/gmail-sync-C-NmibzS.js.map +0 -1
  74. package/dist/gmail-sync-DueE6tl5.js.map +0 -1
  75. package/dist/gmail-sync-GEy3oVvw.cjs.map +0 -1
  76. package/dist/index-B0IMMrp_.d.ts.map +0 -1
  77. package/dist/index-pY7tYXwH.d.cts.map +0 -1
  78. package/dist/interactions-writer-BZzUIgJd.js.map +0 -1
  79. package/dist/interactions-writer-DbSyI2rt.js.map +0 -1
  80. package/dist/interactions-writer-a2yzBd7T.cjs.map +0 -1
  81. package/dist/server-DqSMYhSA.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { r as updateSlugSyncState } from "./sync-state-DMZgzpez.js";
2
- import { n as appendInteraction } from "./interactions-writer-DbSyI2rt.js";
2
+ import { n as appendInteraction } from "./interactions-writer-B8XAzdqR.js";
3
3
  //#region src/sync/microsoft-calendar.ts
4
4
  async function syncMicrosoftCalendar(opts) {
5
5
  const result = {
@@ -12,7 +12,7 @@ async function syncMicrosoftCalendar(opts) {
12
12
  const top = opts.maxResults ?? 50;
13
13
  const startStr = since.toISOString();
14
14
  const endStr = until.toISOString();
15
- const { readInteractions } = await import("./interactions-writer-RJB8SWf2.js");
15
+ const { readInteractions } = await import("./interactions-writer-B2y-73lh.js");
16
16
  const existing = await readInteractions(opts.dataDir, opts.slug).catch(() => "");
17
17
  let url = `https://graph.microsoft.com/v1.0/me/calendarView?startDateTime=${startStr}&endDateTime=${endStr}&$top=${top}&$select=id,subject,bodyPreview,start,end,attendees,organizer`;
18
18
  while (url) {
@@ -64,4 +64,4 @@ async function syncMicrosoftCalendar(opts) {
64
64
  //#endregion
65
65
  export { syncMicrosoftCalendar };
66
66
 
67
- //# sourceMappingURL=microsoft-calendar-jIu9K5zX.js.map
67
+ //# sourceMappingURL=microsoft-calendar-BgVR8GDv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"microsoft-calendar-jIu9K5zX.js","names":[],"sources":["../src/sync/microsoft-calendar.ts"],"sourcesContent":["import { appendInteraction } from \"../fs/interactions-writer.js\";\nimport { updateSlugSyncState } from \"../fs/sync-state.js\";\n\nexport interface CalendarSyncOptions {\n slug: string;\n dataDir: string;\n accessToken: string;\n since?: Date;\n maxResults?: number;\n}\n\nexport interface CalendarSyncResult {\n synced: number;\n skipped: number;\n errors: string[];\n}\n\ninterface GraphEvent {\n id: string;\n subject?: string;\n bodyPreview?: string;\n start?: { dateTime?: string };\n end?: { dateTime?: string };\n attendees?: Array<{ emailAddress?: { name?: string; address?: string } }>;\n organizer?: { emailAddress?: { name?: string; address?: string } };\n}\n\ninterface GraphEventsResponse {\n value: GraphEvent[];\n \"@odata.nextLink\"?: string;\n}\n\nexport async function syncMicrosoftCalendar(\n opts: CalendarSyncOptions\n): Promise<CalendarSyncResult> {\n const result: CalendarSyncResult = { synced: 0, skipped: 0, errors: [] };\n const since = opts.since ?? new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);\n const until = new Date();\n const top = opts.maxResults ?? 50;\n\n const startStr = since.toISOString();\n const endStr = until.toISOString();\n\n const { readInteractions } = await import(\"../fs/interactions-writer.js\");\n const existing = await readInteractions(opts.dataDir, opts.slug).catch(() => \"\");\n\n let url: string | undefined =\n `https://graph.microsoft.com/v1.0/me/calendarView?startDateTime=${startStr}&endDateTime=${endStr}&$top=${top}&$select=id,subject,bodyPreview,start,end,attendees,organizer`;\n\n while (url) {\n let events: GraphEvent[];\n let nextLink: string | undefined;\n try {\n const res = await fetch(url, {\n headers: { Authorization: `Bearer ${opts.accessToken}` },\n });\n if (!res.ok) {\n result.errors.push(`Graph Calendar API error: ${res.status} ${res.statusText}`);\n break;\n }\n const data = (await res.json()) as GraphEventsResponse;\n events = data.value ?? [];\n nextLink = data[\"@odata.nextLink\"];\n } catch (err) {\n result.errors.push(`Network error: ${(err as Error).message}`);\n break;\n }\n\n for (const event of events) {\n const sourceRef = `microsoft://calendar/${event.id}`;\n if (existing.includes(sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = event.start?.dateTime\n ? new Date(event.start.dateTime).toISOString().slice(0, 10)\n : new Date().toISOString().slice(0, 10);\n\n const attendeeNames = (event.attendees ?? [])\n .map((a) => a.emailAddress?.name ?? a.emailAddress?.address ?? \"unknown\")\n .join(\", \");\n\n const organizer =\n event.organizer?.emailAddress?.name ?? event.organizer?.emailAddress?.address ?? \"unknown\";\n\n try {\n await appendInteraction(opts.dataDir, opts.slug, {\n date,\n type: \"Meeting\",\n with: attendeeNames || organizer,\n summary: `${event.subject ?? \"(no subject)\"}: ${event.bodyPreview?.slice(0, 200) ?? \"\"}`,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n direction: \"inbound\",\n });\n result.synced++;\n } catch (err) {\n result.errors.push(`Failed to append ${event.id}: ${(err as Error).message}`);\n }\n }\n\n url = nextLink;\n }\n\n if (result.synced > 0) {\n updateSlugSyncState(opts.dataDir, opts.slug, {\n lastGmailSync: new Date().toISOString(),\n });\n }\n\n return result;\n}\n"],"mappings":";;;AAgCA,eAAsB,sBACpB,MAC6B;CAC7B,MAAM,SAA6B;EAAE,QAAQ;EAAG,SAAS;EAAG,QAAQ,CAAC;CAAE;CACvE,MAAM,QAAQ,KAAK,yBAAS,IAAI,KAAK,KAAK,IAAI,IAAI,MAAU,KAAK,KAAK,GAAI;CAC1E,MAAM,wBAAQ,IAAI,KAAK;CACvB,MAAM,MAAM,KAAK,cAAc;CAE/B,MAAM,WAAW,MAAM,YAAY;CACnC,MAAM,SAAS,MAAM,YAAY;CAEjC,MAAM,EAAE,qBAAqB,MAAM,OAAO;CAC1C,MAAM,WAAW,MAAM,iBAAiB,KAAK,SAAS,KAAK,IAAI,EAAE,YAAY,EAAE;CAE/E,IAAI,MACF,kEAAkE,SAAS,eAAe,OAAO,QAAQ,IAAI;CAE/G,OAAO,KAAK;EACV,IAAI;EACJ,IAAI;EACJ,IAAI;GACF,MAAM,MAAM,MAAM,MAAM,KAAK,EAC3B,SAAS,EAAE,eAAe,UAAU,KAAK,cAAc,EACzD,CAAC;GACD,IAAI,CAAC,IAAI,IAAI;IACX,OAAO,OAAO,KAAK,6BAA6B,IAAI,OAAO,GAAG,IAAI,YAAY;IAC9E;GACF;GACA,MAAM,OAAQ,MAAM,IAAI,KAAK;GAC7B,SAAS,KAAK,SAAS,CAAC;GACxB,WAAW,KAAK;EAClB,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,kBAAmB,IAAc,SAAS;GAC7D;EACF;EAEA,KAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,YAAY,wBAAwB,MAAM;GAChD,IAAI,SAAS,SAAS,SAAS,GAAG;IAChC,OAAO;IACP;GACF;GAEA,MAAM,OAAO,MAAM,OAAO,WACtB,IAAI,KAAK,MAAM,MAAM,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,qBACxD,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;GAExC,MAAM,iBAAiB,MAAM,aAAa,CAAC,GACxC,KAAK,MAAM,EAAE,cAAc,QAAQ,EAAE,cAAc,WAAW,SAAS,EACvE,KAAK,IAAI;GAEZ,MAAM,YACJ,MAAM,WAAW,cAAc,QAAQ,MAAM,WAAW,cAAc,WAAW;GAEnF,IAAI;IACF,MAAM,kBAAkB,KAAK,SAAS,KAAK,MAAM;KAC/C;KACA,MAAM;KACN,MAAM,iBAAiB;KACvB,SAAS,GAAG,MAAM,WAAW,eAAe,IAAI,MAAM,aAAa,MAAM,GAAG,GAAG,KAAK;KACpF,WAAW,CAAC;KACZ;KACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;KAC/B,WAAW;IACb,CAAC;IACD,OAAO;GACT,SAAS,KAAK;IACZ,OAAO,OAAO,KAAK,oBAAoB,MAAM,GAAG,IAAK,IAAc,SAAS;GAC9E;EACF;EAEA,MAAM;CACR;CAEA,IAAI,OAAO,SAAS,GAClB,oBAAoB,KAAK,SAAS,KAAK,MAAM,EAC3C,gCAAe,IAAI,KAAK,GAAE,YAAY,EACxC,CAAC;CAGH,OAAO;AACT"}
1
+ {"version":3,"file":"microsoft-calendar-BgVR8GDv.js","names":[],"sources":["../src/sync/microsoft-calendar.ts"],"sourcesContent":["import { appendInteraction } from \"../fs/interactions-writer.js\";\nimport { updateSlugSyncState } from \"../fs/sync-state.js\";\n\nexport interface CalendarSyncOptions {\n slug: string;\n dataDir: string;\n accessToken: string;\n since?: Date;\n maxResults?: number;\n}\n\nexport interface CalendarSyncResult {\n synced: number;\n skipped: number;\n errors: string[];\n}\n\ninterface GraphEvent {\n id: string;\n subject?: string;\n bodyPreview?: string;\n start?: { dateTime?: string };\n end?: { dateTime?: string };\n attendees?: Array<{ emailAddress?: { name?: string; address?: string } }>;\n organizer?: { emailAddress?: { name?: string; address?: string } };\n}\n\ninterface GraphEventsResponse {\n value: GraphEvent[];\n \"@odata.nextLink\"?: string;\n}\n\nexport async function syncMicrosoftCalendar(\n opts: CalendarSyncOptions\n): Promise<CalendarSyncResult> {\n const result: CalendarSyncResult = { synced: 0, skipped: 0, errors: [] };\n const since = opts.since ?? new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);\n const until = new Date();\n const top = opts.maxResults ?? 50;\n\n const startStr = since.toISOString();\n const endStr = until.toISOString();\n\n const { readInteractions } = await import(\"../fs/interactions-writer.js\");\n const existing = await readInteractions(opts.dataDir, opts.slug).catch(() => \"\");\n\n let url: string | undefined =\n `https://graph.microsoft.com/v1.0/me/calendarView?startDateTime=${startStr}&endDateTime=${endStr}&$top=${top}&$select=id,subject,bodyPreview,start,end,attendees,organizer`;\n\n while (url) {\n let events: GraphEvent[];\n let nextLink: string | undefined;\n try {\n const res = await fetch(url, {\n headers: { Authorization: `Bearer ${opts.accessToken}` },\n });\n if (!res.ok) {\n result.errors.push(`Graph Calendar API error: ${res.status} ${res.statusText}`);\n break;\n }\n const data = (await res.json()) as GraphEventsResponse;\n events = data.value ?? [];\n nextLink = data[\"@odata.nextLink\"];\n } catch (err) {\n result.errors.push(`Network error: ${(err as Error).message}`);\n break;\n }\n\n for (const event of events) {\n const sourceRef = `microsoft://calendar/${event.id}`;\n if (existing.includes(sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = event.start?.dateTime\n ? new Date(event.start.dateTime).toISOString().slice(0, 10)\n : new Date().toISOString().slice(0, 10);\n\n const attendeeNames = (event.attendees ?? [])\n .map((a) => a.emailAddress?.name ?? a.emailAddress?.address ?? \"unknown\")\n .join(\", \");\n\n const organizer =\n event.organizer?.emailAddress?.name ?? event.organizer?.emailAddress?.address ?? \"unknown\";\n\n try {\n await appendInteraction(opts.dataDir, opts.slug, {\n date,\n type: \"Meeting\",\n with: attendeeNames || organizer,\n summary: `${event.subject ?? \"(no subject)\"}: ${event.bodyPreview?.slice(0, 200) ?? \"\"}`,\n nextSteps: [],\n sourceRef,\n synced: new Date().toISOString(),\n direction: \"inbound\",\n });\n result.synced++;\n } catch (err) {\n result.errors.push(`Failed to append ${event.id}: ${(err as Error).message}`);\n }\n }\n\n url = nextLink;\n }\n\n if (result.synced > 0) {\n updateSlugSyncState(opts.dataDir, opts.slug, {\n lastGmailSync: new Date().toISOString(),\n });\n }\n\n return result;\n}\n"],"mappings":";;;AAgCA,eAAsB,sBACpB,MAC6B;CAC7B,MAAM,SAA6B;EAAE,QAAQ;EAAG,SAAS;EAAG,QAAQ,CAAC;CAAE;CACvE,MAAM,QAAQ,KAAK,yBAAS,IAAI,KAAK,KAAK,IAAI,IAAI,MAAU,KAAK,KAAK,GAAI;CAC1E,MAAM,wBAAQ,IAAI,KAAK;CACvB,MAAM,MAAM,KAAK,cAAc;CAE/B,MAAM,WAAW,MAAM,YAAY;CACnC,MAAM,SAAS,MAAM,YAAY;CAEjC,MAAM,EAAE,qBAAqB,MAAM,OAAO;CAC1C,MAAM,WAAW,MAAM,iBAAiB,KAAK,SAAS,KAAK,IAAI,EAAE,YAAY,EAAE;CAE/E,IAAI,MACF,kEAAkE,SAAS,eAAe,OAAO,QAAQ,IAAI;CAE/G,OAAO,KAAK;EACV,IAAI;EACJ,IAAI;EACJ,IAAI;GACF,MAAM,MAAM,MAAM,MAAM,KAAK,EAC3B,SAAS,EAAE,eAAe,UAAU,KAAK,cAAc,EACzD,CAAC;GACD,IAAI,CAAC,IAAI,IAAI;IACX,OAAO,OAAO,KAAK,6BAA6B,IAAI,OAAO,GAAG,IAAI,YAAY;IAC9E;GACF;GACA,MAAM,OAAQ,MAAM,IAAI,KAAK;GAC7B,SAAS,KAAK,SAAS,CAAC;GACxB,WAAW,KAAK;EAClB,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,kBAAmB,IAAc,SAAS;GAC7D;EACF;EAEA,KAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,YAAY,wBAAwB,MAAM;GAChD,IAAI,SAAS,SAAS,SAAS,GAAG;IAChC,OAAO;IACP;GACF;GAEA,MAAM,OAAO,MAAM,OAAO,WACtB,IAAI,KAAK,MAAM,MAAM,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,qBACxD,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;GAExC,MAAM,iBAAiB,MAAM,aAAa,CAAC,GACxC,KAAK,MAAM,EAAE,cAAc,QAAQ,EAAE,cAAc,WAAW,SAAS,EACvE,KAAK,IAAI;GAEZ,MAAM,YACJ,MAAM,WAAW,cAAc,QAAQ,MAAM,WAAW,cAAc,WAAW;GAEnF,IAAI;IACF,MAAM,kBAAkB,KAAK,SAAS,KAAK,MAAM;KAC/C;KACA,MAAM;KACN,MAAM,iBAAiB;KACvB,SAAS,GAAG,MAAM,WAAW,eAAe,IAAI,MAAM,aAAa,MAAM,GAAG,GAAG,KAAK;KACpF,WAAW,CAAC;KACZ;KACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;KAC/B,WAAW;IACb,CAAC;IACD,OAAO;GACT,SAAS,KAAK;IACZ,OAAO,OAAO,KAAK,oBAAoB,MAAM,GAAG,IAAK,IAAc,SAAS;GAC9E;EACF;EAEA,MAAM;CACR;CAEA,IAAI,OAAO,SAAS,GAClB,oBAAoB,KAAK,SAAS,KAAK,MAAM,EAC3C,gCAAe,IAAI,KAAK,GAAE,YAAY,EACxC,CAAC;CAGH,OAAO;AACT"}
@@ -1,5 +1,5 @@
1
1
  import { r as updateSlugSyncState } from "./sync-state-DMZgzpez.js";
2
- import { n as appendInteraction } from "./interactions-writer-DbSyI2rt.js";
2
+ import { n as appendInteraction } from "./interactions-writer-B8XAzdqR.js";
3
3
  //#region src/sync/microsoft-sync.ts
4
4
  async function syncMicrosoft(opts) {
5
5
  const result = {
@@ -24,7 +24,7 @@ async function syncMicrosoft(opts) {
24
24
  result.errors.push(`Network error: ${err.message}`);
25
25
  return result;
26
26
  }
27
- const { readInteractions } = await import("./interactions-writer-RJB8SWf2.js");
27
+ const { readInteractions } = await import("./interactions-writer-B2y-73lh.js");
28
28
  const existing = await readInteractions(opts.dataDir, opts.slug).catch(() => "");
29
29
  for (const msg of messages) {
30
30
  const sourceRef = `microsoft://message/${msg.id}`;
@@ -65,4 +65,4 @@ async function syncMicrosoft(opts) {
65
65
  //#endregion
66
66
  export { syncMicrosoft };
67
67
 
68
- //# sourceMappingURL=microsoft-sync-R_r8HL-B.js.map
68
+ //# sourceMappingURL=microsoft-sync-D30_XksI.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"microsoft-sync-R_r8HL-B.js","names":[],"sources":["../src/sync/microsoft-sync.ts"],"sourcesContent":["import { appendInteraction } from \"../fs/interactions-writer.js\";\nimport { updateSlugSyncState } from \"../fs/sync-state.js\";\n\nexport interface MicrosoftSyncOptions {\n slug: string;\n dataDir: string;\n accessToken: string;\n query?: string;\n since?: Date;\n maxResults?: number;\n}\n\nexport interface MicrosoftSyncResult {\n synced: number;\n skipped: number;\n errors: string[];\n}\n\ninterface GraphMessage {\n id: string;\n subject?: string;\n bodyPreview?: string;\n receivedDateTime?: string;\n from?: { emailAddress?: { address?: string; name?: string } };\n}\n\ninterface GraphResponse {\n value: GraphMessage[];\n}\n\nexport async function syncMicrosoft(opts: MicrosoftSyncOptions): Promise<MicrosoftSyncResult> {\n const result: MicrosoftSyncResult = { synced: 0, skipped: 0, errors: [] };\n const maxResults = opts.maxResults ?? 50;\n\n let filter = \"\";\n if (opts.since) {\n filter = `&$filter=receivedDateTime ge ${opts.since.toISOString()}`;\n }\n if (opts.query) {\n filter += (filter ? \" and \" : \"&$filter=\") + opts.query;\n }\n\n const url = `https://graph.microsoft.com/v1.0/me/messages?$top=${maxResults}${filter}`;\n\n let messages: GraphMessage[];\n try {\n const res = await fetch(url, {\n headers: { Authorization: `Bearer ${opts.accessToken}` },\n });\n if (!res.ok) {\n result.errors.push(`Graph API error: ${res.status} ${res.statusText}`);\n return result;\n }\n const data = (await res.json()) as GraphResponse;\n messages = data.value ?? [];\n } catch (err) {\n result.errors.push(`Network error: ${(err as Error).message}`);\n return result;\n }\n\n const { readInteractions } = await import(\"../fs/interactions-writer.js\");\n const existing = await readInteractions(opts.dataDir, opts.slug).catch(() => \"\");\n\n for (const msg of messages) {\n const sourceRef = `microsoft://message/${msg.id}`;\n if (existing.includes(sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = msg.receivedDateTime\n ? new Date(msg.receivedDateTime).toISOString().slice(0, 10)\n : new Date().toISOString().slice(0, 10);\n\n const from = msg.from?.emailAddress?.name ?? msg.from?.emailAddress?.address ?? \"unknown\";\n const subject = msg.subject ?? \"(no subject)\";\n const preview = msg.bodyPreview ?? \"\";\n\n let summary = preview.slice(0, 300);\n let nextSteps: string[] = [];\n\n try {\n const { summarizeEmail } = await import(\"../core/llm.js\");\n const llmResult = await summarizeEmail(subject, preview, from);\n summary = llmResult.summary;\n nextSteps = llmResult.nextSteps;\n } catch {\n // LLM unavailable — use raw preview\n }\n\n try {\n await appendInteraction(opts.dataDir, opts.slug, {\n date,\n type: \"Email\",\n with: from,\n summary: `${subject}: ${summary}`,\n nextSteps,\n sourceRef,\n synced: new Date().toISOString(),\n });\n result.synced++;\n } catch (err) {\n result.errors.push(`Failed to append ${msg.id}: ${(err as Error).message}`);\n }\n }\n\n if (result.synced > 0) {\n updateSlugSyncState(opts.dataDir, opts.slug, {\n lastGmailSync: new Date().toISOString(),\n });\n }\n\n return result;\n}\n"],"mappings":";;;AA8BA,eAAsB,cAAc,MAA0D;CAC5F,MAAM,SAA8B;EAAE,QAAQ;EAAG,SAAS;EAAG,QAAQ,CAAC;CAAE;CACxE,MAAM,aAAa,KAAK,cAAc;CAEtC,IAAI,SAAS;CACb,IAAI,KAAK,OACP,SAAS,gCAAgC,KAAK,MAAM,YAAY;CAElE,IAAI,KAAK,OACP,WAAW,SAAS,UAAU,eAAe,KAAK;CAGpD,MAAM,MAAM,qDAAqD,aAAa;CAE9E,IAAI;CACJ,IAAI;EACF,MAAM,MAAM,MAAM,MAAM,KAAK,EAC3B,SAAS,EAAE,eAAe,UAAU,KAAK,cAAc,EACzD,CAAC;EACD,IAAI,CAAC,IAAI,IAAI;GACX,OAAO,OAAO,KAAK,oBAAoB,IAAI,OAAO,GAAG,IAAI,YAAY;GACrE,OAAO;EACT;EAEA,YAAW,MADS,IAAI,KAAK,GACb,SAAS,CAAC;CAC5B,SAAS,KAAK;EACZ,OAAO,OAAO,KAAK,kBAAmB,IAAc,SAAS;EAC7D,OAAO;CACT;CAEA,MAAM,EAAE,qBAAqB,MAAM,OAAO;CAC1C,MAAM,WAAW,MAAM,iBAAiB,KAAK,SAAS,KAAK,IAAI,EAAE,YAAY,EAAE;CAE/E,KAAK,MAAM,OAAO,UAAU;EAC1B,MAAM,YAAY,uBAAuB,IAAI;EAC7C,IAAI,SAAS,SAAS,SAAS,GAAG;GAChC,OAAO;GACP;EACF;EAEA,MAAM,OAAO,IAAI,mBACb,IAAI,KAAK,IAAI,gBAAgB,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,qBACxD,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;EAExC,MAAM,OAAO,IAAI,MAAM,cAAc,QAAQ,IAAI,MAAM,cAAc,WAAW;EAChF,MAAM,UAAU,IAAI,WAAW;EAC/B,MAAM,UAAU,IAAI,eAAe;EAEnC,IAAI,UAAU,QAAQ,MAAM,GAAG,GAAG;EAClC,IAAI,YAAsB,CAAC;EAE3B,IAAI;GACF,MAAM,EAAE,mBAAmB,MAAM,OAAO;GACxC,MAAM,YAAY,MAAM,eAAe,SAAS,SAAS,IAAI;GAC7D,UAAU,UAAU;GACpB,YAAY,UAAU;EACxB,QAAQ,CAER;EAEA,IAAI;GACF,MAAM,kBAAkB,KAAK,SAAS,KAAK,MAAM;IAC/C;IACA,MAAM;IACN,MAAM;IACN,SAAS,GAAG,QAAQ,IAAI;IACxB;IACA;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,OAAO;EACT,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,oBAAoB,IAAI,GAAG,IAAK,IAAc,SAAS;EAC5E;CACF;CAEA,IAAI,OAAO,SAAS,GAClB,oBAAoB,KAAK,SAAS,KAAK,MAAM,EAC3C,gCAAe,IAAI,KAAK,GAAE,YAAY,EACxC,CAAC;CAGH,OAAO;AACT"}
1
+ {"version":3,"file":"microsoft-sync-D30_XksI.js","names":[],"sources":["../src/sync/microsoft-sync.ts"],"sourcesContent":["import { appendInteraction } from \"../fs/interactions-writer.js\";\nimport { updateSlugSyncState } from \"../fs/sync-state.js\";\n\nexport interface MicrosoftSyncOptions {\n slug: string;\n dataDir: string;\n accessToken: string;\n query?: string;\n since?: Date;\n maxResults?: number;\n}\n\nexport interface MicrosoftSyncResult {\n synced: number;\n skipped: number;\n errors: string[];\n}\n\ninterface GraphMessage {\n id: string;\n subject?: string;\n bodyPreview?: string;\n receivedDateTime?: string;\n from?: { emailAddress?: { address?: string; name?: string } };\n}\n\ninterface GraphResponse {\n value: GraphMessage[];\n}\n\nexport async function syncMicrosoft(opts: MicrosoftSyncOptions): Promise<MicrosoftSyncResult> {\n const result: MicrosoftSyncResult = { synced: 0, skipped: 0, errors: [] };\n const maxResults = opts.maxResults ?? 50;\n\n let filter = \"\";\n if (opts.since) {\n filter = `&$filter=receivedDateTime ge ${opts.since.toISOString()}`;\n }\n if (opts.query) {\n filter += (filter ? \" and \" : \"&$filter=\") + opts.query;\n }\n\n const url = `https://graph.microsoft.com/v1.0/me/messages?$top=${maxResults}${filter}`;\n\n let messages: GraphMessage[];\n try {\n const res = await fetch(url, {\n headers: { Authorization: `Bearer ${opts.accessToken}` },\n });\n if (!res.ok) {\n result.errors.push(`Graph API error: ${res.status} ${res.statusText}`);\n return result;\n }\n const data = (await res.json()) as GraphResponse;\n messages = data.value ?? [];\n } catch (err) {\n result.errors.push(`Network error: ${(err as Error).message}`);\n return result;\n }\n\n const { readInteractions } = await import(\"../fs/interactions-writer.js\");\n const existing = await readInteractions(opts.dataDir, opts.slug).catch(() => \"\");\n\n for (const msg of messages) {\n const sourceRef = `microsoft://message/${msg.id}`;\n if (existing.includes(sourceRef)) {\n result.skipped++;\n continue;\n }\n\n const date = msg.receivedDateTime\n ? new Date(msg.receivedDateTime).toISOString().slice(0, 10)\n : new Date().toISOString().slice(0, 10);\n\n const from = msg.from?.emailAddress?.name ?? msg.from?.emailAddress?.address ?? \"unknown\";\n const subject = msg.subject ?? \"(no subject)\";\n const preview = msg.bodyPreview ?? \"\";\n\n let summary = preview.slice(0, 300);\n let nextSteps: string[] = [];\n\n try {\n const { summarizeEmail } = await import(\"../core/llm.js\");\n const llmResult = await summarizeEmail(subject, preview, from);\n summary = llmResult.summary;\n nextSteps = llmResult.nextSteps;\n } catch {\n // LLM unavailable — use raw preview\n }\n\n try {\n await appendInteraction(opts.dataDir, opts.slug, {\n date,\n type: \"Email\",\n with: from,\n summary: `${subject}: ${summary}`,\n nextSteps,\n sourceRef,\n synced: new Date().toISOString(),\n });\n result.synced++;\n } catch (err) {\n result.errors.push(`Failed to append ${msg.id}: ${(err as Error).message}`);\n }\n }\n\n if (result.synced > 0) {\n updateSlugSyncState(opts.dataDir, opts.slug, {\n lastGmailSync: new Date().toISOString(),\n });\n }\n\n return result;\n}\n"],"mappings":";;;AA8BA,eAAsB,cAAc,MAA0D;CAC5F,MAAM,SAA8B;EAAE,QAAQ;EAAG,SAAS;EAAG,QAAQ,CAAC;CAAE;CACxE,MAAM,aAAa,KAAK,cAAc;CAEtC,IAAI,SAAS;CACb,IAAI,KAAK,OACP,SAAS,gCAAgC,KAAK,MAAM,YAAY;CAElE,IAAI,KAAK,OACP,WAAW,SAAS,UAAU,eAAe,KAAK;CAGpD,MAAM,MAAM,qDAAqD,aAAa;CAE9E,IAAI;CACJ,IAAI;EACF,MAAM,MAAM,MAAM,MAAM,KAAK,EAC3B,SAAS,EAAE,eAAe,UAAU,KAAK,cAAc,EACzD,CAAC;EACD,IAAI,CAAC,IAAI,IAAI;GACX,OAAO,OAAO,KAAK,oBAAoB,IAAI,OAAO,GAAG,IAAI,YAAY;GACrE,OAAO;EACT;EAEA,YAAW,MADS,IAAI,KAAK,GACb,SAAS,CAAC;CAC5B,SAAS,KAAK;EACZ,OAAO,OAAO,KAAK,kBAAmB,IAAc,SAAS;EAC7D,OAAO;CACT;CAEA,MAAM,EAAE,qBAAqB,MAAM,OAAO;CAC1C,MAAM,WAAW,MAAM,iBAAiB,KAAK,SAAS,KAAK,IAAI,EAAE,YAAY,EAAE;CAE/E,KAAK,MAAM,OAAO,UAAU;EAC1B,MAAM,YAAY,uBAAuB,IAAI;EAC7C,IAAI,SAAS,SAAS,SAAS,GAAG;GAChC,OAAO;GACP;EACF;EAEA,MAAM,OAAO,IAAI,mBACb,IAAI,KAAK,IAAI,gBAAgB,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,qBACxD,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;EAExC,MAAM,OAAO,IAAI,MAAM,cAAc,QAAQ,IAAI,MAAM,cAAc,WAAW;EAChF,MAAM,UAAU,IAAI,WAAW;EAC/B,MAAM,UAAU,IAAI,eAAe;EAEnC,IAAI,UAAU,QAAQ,MAAM,GAAG,GAAG;EAClC,IAAI,YAAsB,CAAC;EAE3B,IAAI;GACF,MAAM,EAAE,mBAAmB,MAAM,OAAO;GACxC,MAAM,YAAY,MAAM,eAAe,SAAS,SAAS,IAAI;GAC7D,UAAU,UAAU;GACpB,YAAY,UAAU;EACxB,QAAQ,CAER;EAEA,IAAI;GACF,MAAM,kBAAkB,KAAK,SAAS,KAAK,MAAM;IAC/C;IACA,MAAM;IACN,MAAM;IACN,SAAS,GAAG,QAAQ,IAAI;IACxB;IACA;IACA,yBAAQ,IAAI,KAAK,GAAE,YAAY;GACjC,CAAC;GACD,OAAO;EACT,SAAS,KAAK;GACZ,OAAO,OAAO,KAAK,oBAAoB,IAAI,GAAG,IAAK,IAAc,SAAS;EAC5E;CACF;CAEA,IAAI,OAAO,SAAS,GAClB,oBAAoB,KAAK,SAAS,KAAK,MAAM,EAC3C,gCAAe,IAAI,KAAK,GAAE,YAAY,EACxC,CAAC;CAGH,OAAO;AACT"}
@@ -1,4 +1,4 @@
1
- import { i as readInteractions } from "./interactions-writer-DbSyI2rt.js";
1
+ import { i as readInteractions } from "./interactions-writer-B8XAzdqR.js";
2
2
  import { t as readPipeline } from "./pipeline-writer-CIllfnZl.js";
3
3
  import { t as scoreOpportunity } from "./opportunity-score-BTMOQSTV.js";
4
4
  //#region src/core/nba.ts
@@ -45,4 +45,4 @@ async function nextBestAction(dataDir, slug) {
45
45
  //#endregion
46
46
  export { nextBestAction };
47
47
 
48
- //# sourceMappingURL=nba-mTJ4yEqD.js.map
48
+ //# sourceMappingURL=nba-DwdfM93s.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nba-mTJ4yEqD.js","names":[],"sources":["../src/core/nba.ts"],"sourcesContent":["import { readPipeline } from \"../fs/pipeline-writer.js\";\nimport { readInteractions } from \"../fs/interactions-writer.js\";\nimport { scoreOpportunity } from \"./opportunity-score.js\";\nimport type { PipelineDeal } from \"../schemas/pipeline.js\";\n\n/**\n * Next-Best-Action engine (domino D11 / C3): from a customer's open pipeline +\n * engagement recency, recommend prioritized next steps with rationale. Builds\n * on opportunity scoring; actions are meant to run through the D4 approval gate.\n */\nexport type Priority = \"high\" | \"medium\" | \"low\";\n\nexport interface NbaAction {\n action: string;\n reason: string;\n priority: Priority;\n deal?: string;\n}\n\nconst STAGE_ACTION: Record<PipelineDeal[\"stage\"], string> = {\n lead: \"Qualify the lead and book a discovery call\",\n qualified: \"Send a tailored proposal\",\n proposal: \"Follow up on the open proposal\",\n negotiation: \"Address objections and push to close\",\n won: \"Kick off onboarding\",\n lost: \"Run a loss post-mortem\",\n};\n\nconst RANK: Record<Priority, number> = { high: 0, medium: 1, low: 2 };\n\nexport async function nextBestAction(dataDir: string, slug: string): Promise<NbaAction[]> {\n const actions: NbaAction[] = [];\n\n const deals = await readPipeline(dataDir, slug).catch(() => [] as PipelineDeal[]);\n const open = deals.filter((d) => d.stage !== \"won\" && d.stage !== \"lost\");\n for (const d of open) {\n const { score } = scoreOpportunity(d);\n const priority: Priority = score >= 70 ? \"high\" : score >= 40 ? \"medium\" : \"low\";\n actions.push({\n action: STAGE_ACTION[d.stage],\n reason: `Deal '${d.name}' is in ${d.stage} (win-likelihood ${score})`,\n priority,\n deal: d.name,\n });\n }\n\n const interactions = await readInteractions(dataDir, slug).catch(() => \"\");\n if (!/## \\d{4}-\\d{2}-\\d{2}/.test(interactions)) {\n actions.push({\n action: \"Re-engage — no logged interactions yet\",\n reason: \"No interaction history for this customer\",\n priority: \"medium\",\n });\n }\n\n if (open.length === 0 && deals.length === 0) {\n actions.push({\n action: \"Create an opportunity\",\n reason: \"No pipeline deals exist for this customer\",\n priority: \"low\",\n });\n }\n\n return actions.sort((a, b) => RANK[a.priority] - RANK[b.priority]);\n}\n"],"mappings":";;;;AAmBA,MAAM,eAAsD;CAC1D,MAAM;CACN,WAAW;CACX,UAAU;CACV,aAAa;CACb,KAAK;CACL,MAAM;AACR;AAEA,MAAM,OAAiC;CAAE,MAAM;CAAG,QAAQ;CAAG,KAAK;AAAE;AAEpE,eAAsB,eAAe,SAAiB,MAAoC;CACxF,MAAM,UAAuB,CAAC;CAE9B,MAAM,QAAQ,MAAM,aAAa,SAAS,IAAI,EAAE,YAAY,CAAC,CAAmB;CAChF,MAAM,OAAO,MAAM,QAAQ,MAAM,EAAE,UAAU,SAAS,EAAE,UAAU,MAAM;CACxE,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,EAAE,UAAU,iBAAiB,CAAC;EACpC,MAAM,WAAqB,SAAS,KAAK,SAAS,SAAS,KAAK,WAAW;EAC3E,QAAQ,KAAK;GACX,QAAQ,aAAa,EAAE;GACvB,QAAQ,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,MAAM;GACnE;GACA,MAAM,EAAE;EACV,CAAC;CACH;CAEA,MAAM,eAAe,MAAM,iBAAiB,SAAS,IAAI,EAAE,YAAY,EAAE;CACzE,IAAI,CAAC,uBAAuB,KAAK,YAAY,GAC3C,QAAQ,KAAK;EACX,QAAQ;EACR,QAAQ;EACR,UAAU;CACZ,CAAC;CAGH,IAAI,KAAK,WAAW,KAAK,MAAM,WAAW,GACxC,QAAQ,KAAK;EACX,QAAQ;EACR,QAAQ;EACR,UAAU;CACZ,CAAC;CAGH,OAAO,QAAQ,MAAM,GAAG,MAAM,KAAK,EAAE,YAAY,KAAK,EAAE,SAAS;AACnE"}
1
+ {"version":3,"file":"nba-DwdfM93s.js","names":[],"sources":["../src/core/nba.ts"],"sourcesContent":["import { readPipeline } from \"../fs/pipeline-writer.js\";\nimport { readInteractions } from \"../fs/interactions-writer.js\";\nimport { scoreOpportunity } from \"./opportunity-score.js\";\nimport type { PipelineDeal } from \"../schemas/pipeline.js\";\n\n/**\n * Next-Best-Action engine (domino D11 / C3): from a customer's open pipeline +\n * engagement recency, recommend prioritized next steps with rationale. Builds\n * on opportunity scoring; actions are meant to run through the D4 approval gate.\n */\nexport type Priority = \"high\" | \"medium\" | \"low\";\n\nexport interface NbaAction {\n action: string;\n reason: string;\n priority: Priority;\n deal?: string;\n}\n\nconst STAGE_ACTION: Record<PipelineDeal[\"stage\"], string> = {\n lead: \"Qualify the lead and book a discovery call\",\n qualified: \"Send a tailored proposal\",\n proposal: \"Follow up on the open proposal\",\n negotiation: \"Address objections and push to close\",\n won: \"Kick off onboarding\",\n lost: \"Run a loss post-mortem\",\n};\n\nconst RANK: Record<Priority, number> = { high: 0, medium: 1, low: 2 };\n\nexport async function nextBestAction(dataDir: string, slug: string): Promise<NbaAction[]> {\n const actions: NbaAction[] = [];\n\n const deals = await readPipeline(dataDir, slug).catch(() => [] as PipelineDeal[]);\n const open = deals.filter((d) => d.stage !== \"won\" && d.stage !== \"lost\");\n for (const d of open) {\n const { score } = scoreOpportunity(d);\n const priority: Priority = score >= 70 ? \"high\" : score >= 40 ? \"medium\" : \"low\";\n actions.push({\n action: STAGE_ACTION[d.stage],\n reason: `Deal '${d.name}' is in ${d.stage} (win-likelihood ${score})`,\n priority,\n deal: d.name,\n });\n }\n\n const interactions = await readInteractions(dataDir, slug).catch(() => \"\");\n if (!/## \\d{4}-\\d{2}-\\d{2}/.test(interactions)) {\n actions.push({\n action: \"Re-engage — no logged interactions yet\",\n reason: \"No interaction history for this customer\",\n priority: \"medium\",\n });\n }\n\n if (open.length === 0 && deals.length === 0) {\n actions.push({\n action: \"Create an opportunity\",\n reason: \"No pipeline deals exist for this customer\",\n priority: \"low\",\n });\n }\n\n return actions.sort((a, b) => RANK[a.priority] - RANK[b.priority]);\n}\n"],"mappings":";;;;AAmBA,MAAM,eAAsD;CAC1D,MAAM;CACN,WAAW;CACX,UAAU;CACV,aAAa;CACb,KAAK;CACL,MAAM;AACR;AAEA,MAAM,OAAiC;CAAE,MAAM;CAAG,QAAQ;CAAG,KAAK;AAAE;AAEpE,eAAsB,eAAe,SAAiB,MAAoC;CACxF,MAAM,UAAuB,CAAC;CAE9B,MAAM,QAAQ,MAAM,aAAa,SAAS,IAAI,EAAE,YAAY,CAAC,CAAmB;CAChF,MAAM,OAAO,MAAM,QAAQ,MAAM,EAAE,UAAU,SAAS,EAAE,UAAU,MAAM;CACxE,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,EAAE,UAAU,iBAAiB,CAAC;EACpC,MAAM,WAAqB,SAAS,KAAK,SAAS,SAAS,KAAK,WAAW;EAC3E,QAAQ,KAAK;GACX,QAAQ,aAAa,EAAE;GACvB,QAAQ,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,MAAM;GACnE;GACA,MAAM,EAAE;EACV,CAAC;CACH;CAEA,MAAM,eAAe,MAAM,iBAAiB,SAAS,IAAI,EAAE,YAAY,EAAE;CACzE,IAAI,CAAC,uBAAuB,KAAK,YAAY,GAC3C,QAAQ,KAAK;EACX,QAAQ;EACR,QAAQ;EACR,UAAU;CACZ,CAAC;CAGH,IAAI,KAAK,WAAW,KAAK,MAAM,WAAW,GACxC,QAAQ,KAAK;EACX,QAAQ;EACR,QAAQ;EACR,UAAU;CACZ,CAAC;CAGH,OAAO,QAAQ,MAAM,GAAG,MAAM,KAAK,EAAE,YAAY,KAAK,EAAE,SAAS;AACnE"}
@@ -2,11 +2,11 @@ import { a as readMainFacts, i as listCustomerSlugs, n as customerExists, o as w
2
2
  import { t as writeFileAtomic } from "./atomic-write-8yjqqLtS.js";
3
3
  import { i as writeJsonFile } from "./json-store-WWsFzXub.js";
4
4
  import { n as getSession } from "./session-store-CEa39Dxs.js";
5
- import { a as searchKbSimple, n as getKbArticle, o as writeKbArticle, r as getKbMetaForExport, s as CAPABILITIES_TEXT } from "./knowledge-base-DHNc4hVj.js";
5
+ import { a as searchKbSimple, n as getKbArticle, o as writeKbArticle, r as getKbMetaForExport, s as CAPABILITIES_TEXT } from "./knowledge-base--063Kpa3.js";
6
6
  import { i as readBackupLog, n as listBackupsInDir, o as runBackup } from "./backup-CTlIxUdO.js";
7
7
  import { r as updateSlugSyncState, t as getLastGmailSync } from "./sync-state-DMZgzpez.js";
8
8
  import { t as withFileQueue } from "./write-queue-IbsAjUnh.js";
9
- import { n as appendInteraction, r as formatInteractionEntry } from "./interactions-writer-DbSyI2rt.js";
9
+ import { n as appendInteraction, r as formatInteractionEntry } from "./interactions-writer-B8XAzdqR.js";
10
10
  import { i as writeAuditEntry, n as getActor, r as readAuditLog, t as filterAuditLog } from "./audit-log-DNMY9mUZ.js";
11
11
  import { a as customerVisibility, n as canSeeCustomer, o as enforceRbac } from "./rbac-msmBc_tK.js";
12
12
  import { f as getPipelineStages, i as buildSimulationInput, l as runSimulation, n as buildConfidenceMessage } from "./revenue-simulation-D8f_YkUY.js";
@@ -26,7 +26,7 @@ import { a as loadCustomObjects, i as listRecords, n as defineCustomObject, t as
26
26
  import { r as searchKnowledge } from "./lancedb-CuHKNsNZ.js";
27
27
  import { t as buildDailyBriefing } from "./proactive-agent-B7u3Bj_l.js";
28
28
  import { a as protectedResourceMetadata, o as verifyBearer, r as isAuthRequired, s as wwwAuthenticateHeader } from "./auth-DDXZTwS0.js";
29
- import { i as verifyGmailPubSubSignature, n as decodeGmailPubSubPayload, r as handleGmailPushEvent } from "./gmail-webhook-handler-kGKpbY9h.js";
29
+ import { i as verifyGmailPubSubSignature, n as decodeGmailPubSubPayload, r as handleGmailPushEvent } from "./gmail-webhook-handler-BzOFbvgh.js";
30
30
  import { n as registerUpdateDeal } from "./update-deal-DSzr_Aau.js";
31
31
  import path from "path";
32
32
  import fs from "fs";
@@ -267,7 +267,7 @@ function triggerOnQuerySync(dataDir, slug) {
267
267
  const sources = JSON.parse(fs.readFileSync(sourcesPath, "utf-8"));
268
268
  if (!sources.gmail?.enabled || !sources.gmail.query) return;
269
269
  const query = sources.gmail.query;
270
- import("./gmail-sync-DueE6tl5.js").then(({ syncGmail }) => syncGmail({
270
+ import("./gmail-sync-B4Iu3AQb.js").then(({ syncGmail }) => syncGmail({
271
271
  slug,
272
272
  dataDir,
273
273
  auth,
@@ -582,14 +582,27 @@ async function handleExportCustomer(input, dataDir = DATA_DIR$47) {
582
582
  interactionsCount = countInteractions(interactionsContent);
583
583
  }
584
584
  const pipeline = await readPipeline(dataDir, input.slug);
585
+ const includeAttachmentContent = input.includeAttachmentContent ?? false;
585
586
  const attachmentsDir = path.join(customerDir, "attachments");
586
587
  const attachments = [];
588
+ const attachmentContents = {};
587
589
  if (fs.existsSync(attachmentsDir)) try {
588
590
  const files = fs.readdirSync(attachmentsDir);
589
591
  for (const f of files) try {
590
- if (fs.statSync(path.join(attachmentsDir, f)).isFile()) attachments.push(f);
592
+ if (!fs.statSync(path.join(attachmentsDir, f)).isFile()) continue;
593
+ attachments.push(f);
594
+ if (includeAttachmentContent && f.endsWith(".md")) attachmentContents[f] = fs.readFileSync(path.join(attachmentsDir, f), "utf-8");
591
595
  } catch {}
592
596
  } catch {}
597
+ const attachmentContentSection = () => {
598
+ const entries = Object.entries(attachmentContents);
599
+ if (!includeAttachmentContent || entries.length === 0) return [];
600
+ return [
601
+ "",
602
+ `## Attachment Contents (${entries.length})`,
603
+ ...entries.map(([name, content]) => `\n### ${name}\n\n${content.trim()}`)
604
+ ];
605
+ };
593
606
  if (format === "markdown") return { content: [{
594
607
  type: "text",
595
608
  text: [
@@ -608,7 +621,8 @@ async function handleExportCustomer(input, dataDir = DATA_DIR$47) {
608
621
  pipeline.length > 0 ? pipeline.map((d) => `- **${d.name}** · ${d.stage}${d.value !== void 0 ? ` · €${d.value}` : ""}${d.close_date ? ` · close: ${d.close_date}` : ""}`).join("\n") : "(no deals)",
609
622
  "",
610
623
  `## Attachments (${attachments.length})`,
611
- attachments.length > 0 ? attachments.map((f) => `- ${f}`).join("\n") : "(none)"
624
+ attachments.length > 0 ? attachments.map((f) => `- ${f}`).join("\n") : "(none)",
625
+ ...attachmentContentSection()
612
626
  ].join("\n")
613
627
  }] };
614
628
  const exported = {
@@ -617,7 +631,8 @@ async function handleExportCustomer(input, dataDir = DATA_DIR$47) {
617
631
  mainFacts,
618
632
  interactionsCount,
619
633
  pipeline,
620
- attachments
634
+ attachments,
635
+ ...includeAttachmentContent ? { attachmentContents } : {}
621
636
  };
622
637
  return { content: [{
623
638
  type: "text",
@@ -627,23 +642,28 @@ async function handleExportCustomer(input, dataDir = DATA_DIR$47) {
627
642
  function registerExportCustomer(server) {
628
643
  server.registerTool("export_customer", {
629
644
  title: "Export Customer",
630
- description: `Export all customer data (main_facts + interactions count + pipeline deals).
631
- Useful for reporting, audits, or creating backups.
645
+ description: `Export all customer data (main_facts + interactions + pipeline deals + attachments).
646
+ Useful for reporting, audits, handoffs, or creating a complete sendable bundle
647
+ of every conversation and document for a customer.
632
648
 
633
649
  Args:
634
650
  slug: Customer ID (e.g. "acme-corp")
635
651
  format: Output format — "json" (default) or "markdown"
652
+ includeAttachmentContent: Inline the converted Markdown of every attachment
653
+ (default false). Use this to produce a single self-contained bundle.
636
654
 
637
655
  Returns:
638
- JSON: { slug, exportedAt, mainFacts, interactionsCount, pipeline }
639
- Markdown: Formatted document with all sections`,
656
+ JSON: { slug, exportedAt, mainFacts, interactionsCount, pipeline, attachments[, attachmentContents] }
657
+ Markdown: Formatted document with all sections (and attachment contents when requested)`,
640
658
  inputSchema: z.object({
641
659
  slug: z.string().describe("Customer slug (e.g. 'acme-corp')"),
642
- format: z.enum(["json", "markdown"]).optional().describe("Output format: 'json' (default) or 'markdown'")
660
+ format: z.enum(["json", "markdown"]).optional().describe("Output format: 'json' (default) or 'markdown'"),
661
+ includeAttachmentContent: z.boolean().optional().describe("Inline converted attachment Markdown into the export (default false)")
643
662
  })
644
- }, async ({ slug, format }) => handleExportCustomer({
663
+ }, async ({ slug, format, includeAttachmentContent }) => handleExportCustomer({
645
664
  slug,
646
- ...format !== void 0 ? { format } : {}
665
+ ...format !== void 0 ? { format } : {},
666
+ ...includeAttachmentContent !== void 0 ? { includeAttachmentContent } : {}
647
667
  }));
648
668
  }
649
669
  //#endregion
@@ -1704,7 +1724,7 @@ async function executeAction(action, dataDir) {
1704
1724
  if (!slug) return "skipped";
1705
1725
  switch (action.type) {
1706
1726
  case "log_interaction": {
1707
- const { appendInteraction } = await import("./interactions-writer-RJB8SWf2.js");
1727
+ const { appendInteraction } = await import("./interactions-writer-B2y-73lh.js");
1708
1728
  await appendInteraction(dataDir, slug, {
1709
1729
  date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
1710
1730
  type: action.payload["type"] ?? "Note",
@@ -1717,7 +1737,7 @@ async function executeAction(action, dataDir) {
1717
1737
  return "executed";
1718
1738
  }
1719
1739
  case "schedule_meeting": {
1720
- const { appendInteraction } = await import("./interactions-writer-RJB8SWf2.js");
1740
+ const { appendInteraction } = await import("./interactions-writer-B2y-73lh.js");
1721
1741
  await appendInteraction(dataDir, slug, {
1722
1742
  date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
1723
1743
  type: "Note",
@@ -3724,7 +3744,7 @@ async function handleTriggerSync(input, dataDir = DATA_DIR$4) {
3724
3744
  try {
3725
3745
  const sources = JSON.parse(fs.readFileSync(sourcesPath, "utf-8"));
3726
3746
  if (!sources.gmail?.enabled || !sources.gmail.query) continue;
3727
- const { syncGmail } = await import("./gmail-sync-DueE6tl5.js");
3747
+ const { syncGmail } = await import("./gmail-sync-B4Iu3AQb.js");
3728
3748
  const result = await syncGmail({
3729
3749
  slug,
3730
3750
  dataDir,
@@ -3982,7 +4002,7 @@ function registerResources(server, dataDir = DATA_DIR$1) {
3982
4002
  description: "Newest-first interaction history for a customer",
3983
4003
  mimeType: "text/markdown"
3984
4004
  }, async (uri, variables) => {
3985
- const { readInteractions } = await import("./interactions-writer-RJB8SWf2.js");
4005
+ const { readInteractions } = await import("./interactions-writer-B2y-73lh.js");
3986
4006
  const text = await readInteractions(dataDir, String(variables["slug"]));
3987
4007
  return { contents: [{
3988
4008
  uri: uri.href,
@@ -4342,4 +4362,4 @@ else startStdio().catch((err) => {
4342
4362
  //#endregion
4343
4363
  export { startHttp, startStdio };
4344
4364
 
4345
- //# sourceMappingURL=server-DqSMYhSA.js.map
4365
+ //# sourceMappingURL=server-DoRPPOeR.js.map