@rubytech/create-realagent 1.0.658 → 1.0.660

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 (86) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.ts +115 -61
  3. package/payload/platform/plugins/contacts/mcp/dist/lib/resolve-person.d.ts +13 -1
  4. package/payload/platform/plugins/contacts/mcp/dist/lib/resolve-person.d.ts.map +1 -1
  5. package/payload/platform/plugins/contacts/mcp/dist/lib/resolve-person.js +20 -5
  6. package/payload/platform/plugins/contacts/mcp/dist/lib/resolve-person.js.map +1 -1
  7. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.d.ts.map +1 -1
  8. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js +6 -1
  9. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js.map +1 -1
  10. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-delete.d.ts.map +1 -1
  11. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-delete.js +1 -1
  12. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-delete.js.map +1 -1
  13. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.d.ts.map +1 -1
  14. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.js +1 -1
  15. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-erase.js.map +1 -1
  16. package/payload/platform/plugins/contacts/mcp/dist/tools/group-create.d.ts.map +1 -1
  17. package/payload/platform/plugins/contacts/mcp/dist/tools/group-create.js +8 -3
  18. package/payload/platform/plugins/contacts/mcp/dist/tools/group-create.js.map +1 -1
  19. package/payload/platform/plugins/contacts/mcp/dist/tools/group-manage.d.ts.map +1 -1
  20. package/payload/platform/plugins/contacts/mcp/dist/tools/group-manage.js +14 -6
  21. package/payload/platform/plugins/contacts/mcp/dist/tools/group-manage.js.map +1 -1
  22. package/payload/platform/plugins/docs/references/memory-guide.md +2 -0
  23. package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts +7 -0
  24. package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts.map +1 -1
  25. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js +7 -0
  26. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js.map +1 -1
  27. package/payload/platform/plugins/memory/mcp/dist/index.js +1 -1
  28. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  29. package/payload/platform/plugins/memory/mcp/dist/lib/document-hierarchy.d.ts +0 -16
  30. package/payload/platform/plugins/memory/mcp/dist/lib/document-hierarchy.d.ts.map +1 -1
  31. package/payload/platform/plugins/memory/mcp/dist/lib/document-hierarchy.js +0 -39
  32. package/payload/platform/plugins/memory/mcp/dist/lib/document-hierarchy.js.map +1 -1
  33. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.d.ts +10 -0
  34. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.d.ts.map +1 -1
  35. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js +20 -7
  36. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js.map +1 -1
  37. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts.map +1 -1
  38. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js +4 -1
  39. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js.map +1 -1
  40. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
  41. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +24 -5
  42. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  43. package/payload/platform/plugins/workflows/mcp/dist/index.js +6 -3
  44. package/payload/platform/plugins/workflows/mcp/dist/index.js.map +1 -1
  45. package/payload/platform/plugins/workflows/mcp/dist/lib/active-runs.d.ts.map +1 -1
  46. package/payload/platform/plugins/workflows/mcp/dist/lib/active-runs.js +2 -1
  47. package/payload/platform/plugins/workflows/mcp/dist/lib/active-runs.js.map +1 -1
  48. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-delete.d.ts +25 -3
  49. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-delete.d.ts.map +1 -1
  50. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-delete.js +44 -12
  51. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-delete.js.map +1 -1
  52. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts.map +1 -1
  53. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +19 -3
  54. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
  55. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.d.ts.map +1 -1
  56. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.js +3 -1
  57. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.js.map +1 -1
  58. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-list.d.ts.map +1 -1
  59. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-list.js +3 -2
  60. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-list.js.map +1 -1
  61. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-runs.d.ts.map +1 -1
  62. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-runs.js +7 -2
  63. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-runs.js.map +1 -1
  64. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.d.ts.map +1 -1
  65. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js +5 -1
  66. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js.map +1 -1
  67. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.d.ts.map +1 -1
  68. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.js +3 -1
  69. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.js.map +1 -1
  70. package/payload/server/public/assets/{admin-Czc-XCGo.js → admin-BFIYSS4u.js} +1 -1
  71. package/payload/server/public/assets/{data-CrSbmVOi.js → data-BmeeI1Ix.js} +1 -1
  72. package/payload/server/public/assets/{file-DJN8iDYd.js → file-D4Qulqz_.js} +1 -1
  73. package/payload/server/public/assets/graph-MoIys9Ub.js +49 -0
  74. package/payload/server/public/assets/{house-0e8rAfIV.js → house-B0Hukxjp.js} +1 -1
  75. package/payload/server/public/assets/{jsx-runtime-c8K7DPME.css → jsx-runtime-C6owBiFB.css} +1 -1
  76. package/payload/server/public/assets/{public-CWJExYI2.js → public-LvjJTLGn.js} +1 -1
  77. package/payload/server/public/assets/{share-2-DZ7p8QqC.js → share-2-BafZBLp9.js} +1 -1
  78. package/payload/server/public/assets/{useVoiceRecorder-BgiIIuSz.js → useVoiceRecorder-dLOpmcYJ.js} +1 -1
  79. package/payload/server/public/assets/{x-CknuyFAk.js → x-BOZIeV0f.js} +1 -1
  80. package/payload/server/public/data.html +6 -6
  81. package/payload/server/public/graph.html +6 -6
  82. package/payload/server/public/index.html +7 -7
  83. package/payload/server/public/public.html +4 -4
  84. package/payload/server/server.js +262 -160
  85. package/payload/server/public/assets/graph-BtnUfXRD.js +0 -49
  86. /package/payload/server/public/assets/{jsx-runtime-DHkQ2la3.js → jsx-runtime-CmCvZzVE.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-realagent",
3
- "version": "1.0.658",
3
+ "version": "1.0.660",
4
4
  "description": "Install Real Agent — Built for agents. By agents.",
5
5
  "bin": {
6
6
  "create-realagent": "./dist/index.js"
@@ -363,14 +363,24 @@ export const SCRAPE_EXPRESSION = `(${scrapeCurrentPage.toString()})(document, lo
363
363
  // constructing a full CdpClient + WebSocket.
364
364
  export type CdpEvaluator = (expression: string) => Promise<unknown>;
365
365
 
366
- // Number of consecutive polls returning an identical non-empty count that
367
- // proves the SPA zone-list has finished hydrating. Two iterations at 500 ms
368
- // each = 1 s of observed stability, which is the empirical ceiling on the
369
- // CF dashboard's lazy zone-list fetch post-document-ready. Shorter thresholds
370
- // risk returning a partial list; longer thresholds add user-visible latency
371
- // without proportional robustness.
366
+ // Trailing-run length (consecutive polls at `max_count`) the complete-line
367
+ // asserts before it declares `unstable=false`. Two iterations at 500 ms each
368
+ // = 1 s of continuous observation at the high-water mark. Task 615 removed
369
+ // the early-exit on this threshold (it shortcuts multi-zone accounts where
370
+ // the first zone hydrates one poll ahead of the second — the plateau at the
371
+ // intermediate count trips the threshold before the final zone arrives);
372
+ // the threshold now only labels the exit, it does not gate it.
372
373
  const STABLE_POLL_THRESHOLD = 2;
373
374
 
375
+ // Cap on `document.documentElement.outerHTML` captured into the dump file.
376
+ // The observed Cloudflare dashboard outerHTML is ~1 MB; 5 MB is 5× headroom
377
+ // and still fits comfortably in one `writeFile` syscall on the Pi. Pre-Task
378
+ // 615 this was 100 KB — the dump ended mid-`<head>` CSS on every scrape,
379
+ // rendering the forensic artifact premise of Task 608 silently broken: the
380
+ // zone table lived past the cutoff and `grep <zone-host> <dump>` always
381
+ // returned nothing, forcing re-scrapes to answer post-hoc questions.
382
+ const OUTER_HTML_CAPTURE_MAX_CHARS = 5_000_000;
383
+
374
384
  // Cap the `domains=[…]` payload on per-poll and complete phase lines. The
375
385
  // extractor already implicitly bounds the list via the FQDN regex + Set
376
386
  // dedupe, but a pathological CF redesign could emit thousands of href
@@ -386,7 +396,7 @@ function formatDomains(domains: string[]): string {
386
396
  }
387
397
 
388
398
  type DumpMode = "stable" | "unstable" | "empty-or-drift";
389
- type DumpResult = { path: string } | { err: string };
399
+ type DumpResult = { path: string; truncated: boolean } | { err: string };
390
400
 
391
401
  // Snapshot the operator's current dashboard HTML so post-hoc diagnosis of a
392
402
  // partial, unstable, or empty scrape has the exact DOM the scrape observed
@@ -404,7 +414,7 @@ async function dumpHtml(
404
414
  ): Promise<DumpResult> {
405
415
  try {
406
416
  const html = (await evaluator(
407
- "document.documentElement.outerHTML.slice(0, 100000)",
417
+ `document.documentElement.outerHTML.slice(0, ${OUTER_HTML_CAPTURE_MAX_CHARS})`,
408
418
  )) as string;
409
419
  // CONFIG_DIR is set by list-cf-domains.sh before the spawn. A silent
410
420
  // fallback would dump logs into the wrong brand's directory on a Real
@@ -423,8 +433,19 @@ async function dumpHtml(
423
433
  logDir,
424
434
  `list-cf-domains-${ts}-count${count}-${mode}-pid${process.pid}.html`,
425
435
  );
426
- await writeFile(dumpPath, typeof html === "string" ? html : String(html), "utf-8");
427
- return { path: dumpPath };
436
+ const htmlStr = typeof html === "string" ? html : String(html);
437
+ await writeFile(dumpPath, htmlStr, "utf-8");
438
+ // Heuristic: if the slice returned exactly OUTER_HTML_CAPTURE_MAX_CHARS,
439
+ // the source outerHTML almost certainly exceeded the cap and we
440
+ // truncated mid-document. The false positive (outerHTML exactly at the
441
+ // ceiling) is a rounding coincidence on the order of 1-in-5M and is
442
+ // acceptable — a loud truncation signal with a ~10^-7 false-positive
443
+ // rate is strictly better than silent truncation (the pre-Task-615
444
+ // failure mode at the 100 KB ceiling, which silently broke every scrape
445
+ // for five months). A downstream investigator seeing `truncated=true`
446
+ // can re-scrape with a larger cap or `outerHTML` unsliced.
447
+ const truncated = htmlStr.length >= OUTER_HTML_CAPTURE_MAX_CHARS;
448
+ return { path: dumpPath, truncated };
428
449
  } catch (err) {
429
450
  return {
430
451
  err: (err instanceof Error ? err.message : String(err)).slice(0, 120),
@@ -437,7 +458,17 @@ async function dumpHtml(
437
458
  // complete line terse and routes every failure through the same observation
438
459
  // primitive so investigators have one grep pattern for all dump write errors.
439
460
  function dumpField(result: DumpResult, mode: DumpMode): string {
440
- if ("path" in result) return `dump=${result.path}`;
461
+ if ("path" in result) {
462
+ if (result.truncated) {
463
+ // Loud separate phase line — an investigator grepping for truncation
464
+ // incidents across the stream log has one exact pattern to match.
465
+ logPhase(
466
+ `phase=dump-truncated mode=${mode} path=${result.path} captured_bytes=${OUTER_HTML_CAPTURE_MAX_CHARS}`,
467
+ );
468
+ return `dump=${result.path} dump_truncated=true`;
469
+ }
470
+ return `dump=${result.path}`;
471
+ }
441
472
  logPhase(
442
473
  `phase=dump-write-failed mode=${mode} detail="${result.err.replace(/"/g, "'")}"`,
443
474
  );
@@ -446,13 +477,30 @@ function dumpField(result: DumpResult, mode: DumpMode): string {
446
477
 
447
478
  export async function scrapeDomains(evaluator: CdpEvaluator): Promise<string[]> {
448
479
  const deadline = Date.now() + SCRAPE_POLL_MS;
480
+ // Task 615: pure poll-to-deadline. The earlier "first N stable polls wins"
481
+ // heuristic short-circuited on the first plateau a multi-zone dashboard
482
+ // rendered — a 2-zone account whose second zone hydrates one poll later
483
+ // than the first would lock `count=1` before the second zone arrived.
484
+ // Removing early-exit entirely is the only formulation that eliminates the
485
+ // class: any "N-consec-at-max wins" variant still fires on the intermediate
486
+ // plateau (`[] [] [a] [a] [a,b] …` → threshold met at poll 4 before zone B
487
+ // observed). The cost is ~9 s of happy-path latency under the 10 s budget
488
+ // (still within onboarding tolerance). `max_count` tracks the high-water
489
+ // count; `consecutiveAtMax` tracks the trailing run at that water-mark;
490
+ // `seenDecrease` tracks any mid-trajectory count drop. `unstable=false`
491
+ // requires reaching max, ending at max, at least STABLE_POLL_THRESHOLD
492
+ // consecutive trailing polls at max, and no mid-trajectory decrease — so a
493
+ // trajectory like `[a][a][a][a,b]{never reaches 2 consecutive}` correctly
494
+ // reports `unstable=true` even though `final_count === max_count`.
449
495
  let lastOutcome: ScrapeOutcome | null = null;
450
- // Track the most recent non-empty observation so deadline-reached without
451
- // stability returns the caller's best evidence rather than falling through
452
- // to the drift-dump (which is reserved for the always-empty case).
453
- let lastNonEmptyDomains: string[] = [];
454
- let stableCount = -1;
455
- let stableIterations = 0;
496
+ let maxCount = 0;
497
+ // Snapshot of the domains array at the most-recent observation of
498
+ // `maxCount`. Updated on every `>=` poll so it always reflects the latest
499
+ // capture at the high-water mark; returned at deadline when `maxCount > 0`.
500
+ let maxDomains: string[] = [];
501
+ let finalCount = 0;
502
+ let consecutiveAtMax = 0;
503
+ let seenDecrease = false;
456
504
  let polls = 0;
457
505
 
458
506
  while (Date.now() < deadline) {
@@ -460,40 +508,44 @@ export async function scrapeDomains(evaluator: CdpEvaluator): Promise<string[]>
460
508
  try {
461
509
  const outcome = (await evaluator(SCRAPE_EXPRESSION)) as ScrapeOutcome;
462
510
  lastOutcome = outcome;
511
+ const count = outcome.domains.length;
463
512
 
464
- // Per-poll trajectory line (Task 608). Names the exact list captured at
465
- // this iteration so a partial-capture scenario (e.g. 2-zone account
466
- // rendering count=1 on poll K because zone B has not hydrated yet) is
467
- // legible from the stream log alone. Emitted only on successful
468
- // evaluator returns — the catch branch emits `phase=scrape-retry`
469
- // instead, because "zero observed" and "failed to observe" are
470
- // semantically distinct signals for a downstream reader.
471
513
  logPhase(
472
- `phase=dom-scrape-poll n=${polls} count=${outcome.domains.length} domains=[${formatDomains(outcome.domains)}]`,
514
+ `phase=dom-scrape-poll n=${polls} count=${count} domains=[${formatDomains(outcome.domains)}]`,
473
515
  );
474
516
 
475
- if (outcome.reason === "ok" && outcome.domains.length > 0) {
476
- lastNonEmptyDomains = outcome.domains;
477
- if (outcome.domains.length === stableCount) {
478
- stableIterations += 1;
479
- if (stableIterations >= STABLE_POLL_THRESHOLD) {
480
- const dump = await dumpHtml(evaluator, outcome.domains.length, "stable");
481
- logPhase(
482
- `phase=dom-scrape-complete result=ok count=${outcome.domains.length} polls=${polls} stable_polls=${stableIterations} unstable=false domains=[${formatDomains(outcome.domains)}] ${dumpField(dump, "stable")}`,
483
- );
484
- return outcome.domains;
485
- }
517
+ if (outcome.reason === "ok" && count > 0) {
518
+ if (count > maxCount) {
519
+ // New high-water mark. Post-stable increases reset the run counter —
520
+ // the new stable window must also satisfy the threshold to qualify
521
+ // as `unstable=false`.
522
+ maxCount = count;
523
+ maxDomains = outcome.domains;
524
+ consecutiveAtMax = 1;
525
+ } else if (count === maxCount) {
526
+ maxDomains = outcome.domains;
527
+ consecutiveAtMax += 1;
486
528
  } else {
487
- stableCount = outcome.domains.length;
488
- stableIterations = 1;
529
+ // count > 0 && count < maxCount — the page shrunk mid-poll
530
+ // (virtual-scroll pagination, zone deletion concurrent with scrape,
531
+ // SPA re-render collapsing rows). Preserve the high-water snapshot;
532
+ // flag the trajectory as unstable.
533
+ seenDecrease = true;
534
+ consecutiveAtMax = 0;
489
535
  }
536
+ finalCount = count;
490
537
  } else {
491
- // `ok` with zero domains OR a non-ok reason: treat as still-hydrating.
492
- // Keep polling; the final iteration's zero result is the empty-account
493
- // signal. Reset stability tracking so a 0 N → 0 sequence doesn't
494
- // falsely satisfy the threshold.
495
- stableCount = -1;
496
- stableIterations = 0;
538
+ // Empty poll or non-ok reason (no-account-id SPA mid-navigation):
539
+ // the page momentarily showed no zones, breaking any trailing at-max
540
+ // run. Don't flip `seenDecrease` treating a hydration gap as a
541
+ // "shrink" would be a false positive on the leading empty polls of
542
+ // every scrape. `finalCount` reflects the last poll's observed count
543
+ // (always 0 in this branch, since `scrapeCurrentPage` returns empty
544
+ // domains on any non-ok reason), so the stream log's `final_count`
545
+ // field accurately names what the last poll saw, not a stale value
546
+ // from an earlier successful observation.
547
+ consecutiveAtMax = 0;
548
+ finalCount = count;
497
549
  }
498
550
  } catch (err) {
499
551
  logPhase(
@@ -503,31 +555,33 @@ export async function scrapeDomains(evaluator: CdpEvaluator): Promise<string[]>
503
555
  await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
504
556
  }
505
557
 
506
- // Deadline reached. Two distinct branches:
558
+ // Deadline reached. Two branches:
507
559
  //
508
- // (i) We saw non-empty results but they never stabilised across two
509
- // consecutive polls the page is either paginating or re-rendering
510
- // the zone list. Return the last non-empty observation, flag
511
- // `unstable=true` on the phase line, and snapshot the DOM so
512
- // partial-capture-that-also-races is diagnosable (Task 608 extends
513
- // the dump to this path — pre-task, only empty-or-drift dumped).
560
+ // (i) We observed at least one non-empty poll. Return the max-count
561
+ // snapshot (which, when `finalCount === maxCount`, is also the last
562
+ // non-empty observation). `unstable=true` whenever any signal suggests
563
+ // the page wasn't settled: shrinkage, end-below-max, or fewer than
564
+ // STABLE_POLL_THRESHOLD consecutive trailing polls at max.
514
565
  //
515
- // (ii) We never saw non-empty results this is either a genuinely empty
516
- // account OR CF has drifted the href URL shape so Source A yields
517
- // nothing. The `empty-or-drift` body-dump branch snapshots the page
518
- // HTML so the operator can distinguish the two by inspecting the
519
- // dump file.
520
- if (lastNonEmptyDomains.length > 0) {
521
- const dump = await dumpHtml(evaluator, lastNonEmptyDomains.length, "unstable");
566
+ // (ii) Every poll was empty — either a genuinely empty account OR CF
567
+ // drifted the href shape. The `empty-or-drift` dump is the operator's
568
+ // single-artifact signal for distinguishing the two.
569
+ if (maxCount > 0) {
570
+ const unstable =
571
+ seenDecrease ||
572
+ finalCount !== maxCount ||
573
+ consecutiveAtMax < STABLE_POLL_THRESHOLD;
574
+ const mode: DumpMode = unstable ? "unstable" : "stable";
575
+ const dump = await dumpHtml(evaluator, maxCount, mode);
522
576
  logPhase(
523
- `phase=dom-scrape-complete result=ok count=${lastNonEmptyDomains.length} polls=${polls} stable_polls=${stableIterations} unstable=true domains=[${formatDomains(lastNonEmptyDomains)}] ${dumpField(dump, "unstable")}`,
577
+ `phase=dom-scrape-complete result=ok count=${maxCount} total_polls=${polls} max_count=${maxCount} final_count=${finalCount} stable_polls=${consecutiveAtMax} unstable=${unstable} domains=[${formatDomains(maxDomains)}] ${dumpField(dump, mode)}`,
524
578
  );
525
- return lastNonEmptyDomains;
579
+ return maxDomains;
526
580
  }
527
581
 
528
582
  const dump = await dumpHtml(evaluator, 0, "empty-or-drift");
529
583
  logPhase(
530
- `phase=dom-scrape-complete result=empty-or-drift count=0 polls=${polls} lastReason=${lastOutcome?.reason ?? "unknown"} ${dumpField(dump, "empty-or-drift")}`,
584
+ `phase=dom-scrape-complete result=empty-or-drift count=0 total_polls=${polls} max_count=0 final_count=0 stable_polls=0 lastReason=${lastOutcome?.reason ?? "unknown"} ${dumpField(dump, "empty-or-drift")}`,
531
585
  );
532
586
  return [];
533
587
  }
@@ -7,15 +7,27 @@
7
7
  *
8
8
  * Used by: contact-delete, contact-update, contact-export, contact-erase.
9
9
  * NOT used by: contact-create (dedup OR logic), contact-lookup (name search).
10
+ *
11
+ * Task 602 — trashed Person nodes are excluded by default. `contact-erase`
12
+ * passes `includeTrashed: true` because GDPR Article 17 must cascade-delete
13
+ * trashed persons too (they were marked but not yet emptied). Trashed
14
+ * persons also have nulled email/telephone (UNIQUE_KEYS_BY_LABEL snapshot),
15
+ * so identifier-by-email/telephone already fails — the filter is primarily
16
+ * relevant to the nodeId path and guards against the legacy deletedAt
17
+ * soft-delete state surfaced by `notTrashed()`.
10
18
  */
11
19
  export interface PersonIdentifier {
12
20
  nodeId?: string;
13
21
  email?: string;
14
22
  telephone?: string;
15
23
  }
24
+ export interface ResolveOptions {
25
+ /** Set true for GDPR erasure paths that must match trashed persons too. */
26
+ includeTrashed?: boolean;
27
+ }
16
28
  export interface ResolvedMatch {
17
29
  matchClause: string;
18
30
  queryParams: Record<string, unknown>;
19
31
  }
20
- export declare function resolvePersonMatch(identifier: PersonIdentifier, accountId: string): ResolvedMatch;
32
+ export declare function resolvePersonMatch(identifier: PersonIdentifier, accountId: string, options?: ResolveOptions): ResolvedMatch;
21
33
  //# sourceMappingURL=resolve-person.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-person.d.ts","sourceRoot":"","sources":["../../src/lib/resolve-person.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,gBAAgB,EAC5B,SAAS,EAAE,MAAM,GAChB,aAAa,CA2Bf"}
1
+ {"version":3,"file":"resolve-person.d.ts","sourceRoot":"","sources":["../../src/lib/resolve-person.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,gBAAgB,EAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,cAAmB,GAC3B,aAAa,CAiCf"}
@@ -7,30 +7,45 @@
7
7
  *
8
8
  * Used by: contact-delete, contact-update, contact-export, contact-erase.
9
9
  * NOT used by: contact-create (dedup OR logic), contact-lookup (name search).
10
+ *
11
+ * Task 602 — trashed Person nodes are excluded by default. `contact-erase`
12
+ * passes `includeTrashed: true` because GDPR Article 17 must cascade-delete
13
+ * trashed persons too (they were marked but not yet emptied). Trashed
14
+ * persons also have nulled email/telephone (UNIQUE_KEYS_BY_LABEL snapshot),
15
+ * so identifier-by-email/telephone already fails — the filter is primarily
16
+ * relevant to the nodeId path and guards against the legacy deletedAt
17
+ * soft-delete state surfaced by `notTrashed()`.
10
18
  */
11
- export function resolvePersonMatch(identifier, accountId) {
19
+ import { notTrashed } from "../../../../../lib/graph-trash/dist/index.js";
20
+ export function resolvePersonMatch(identifier, accountId, options = {}) {
12
21
  const { nodeId, email, telephone } = identifier;
22
+ const { includeTrashed = false } = options;
13
23
  if (!nodeId && !email && !telephone) {
14
24
  throw new Error("Either nodeId, email, or telephone must be provided");
15
25
  }
16
26
  const queryParams = { accountId };
27
+ const trashSuffix = includeTrashed ? "" : ` AND ${notTrashed("p")}`;
17
28
  let matchClause;
18
29
  if (nodeId) {
19
30
  if (nodeId.includes(":")) {
20
- matchClause = `MATCH (p:Person) WHERE elementId(p) = $nodeId AND p.accountId = $accountId`;
31
+ matchClause = `MATCH (p:Person) WHERE elementId(p) = $nodeId AND p.accountId = $accountId${trashSuffix}`;
21
32
  queryParams.nodeId = nodeId;
22
33
  }
23
34
  else {
24
- matchClause = `MATCH (p:Person) WHERE id(p) = $nodeId AND p.accountId = $accountId`;
35
+ matchClause = `MATCH (p:Person) WHERE id(p) = $nodeId AND p.accountId = $accountId${trashSuffix}`;
25
36
  queryParams.nodeId = parseInt(nodeId, 10);
26
37
  }
27
38
  }
28
39
  else if (email) {
29
- matchClause = `MATCH (p:Person {email: $email, accountId: $accountId})`;
40
+ matchClause = includeTrashed
41
+ ? `MATCH (p:Person {email: $email, accountId: $accountId})`
42
+ : `MATCH (p:Person {email: $email, accountId: $accountId}) WHERE ${notTrashed("p")}`;
30
43
  queryParams.email = email.toLowerCase();
31
44
  }
32
45
  else {
33
- matchClause = `MATCH (p:Person {telephone: $telephone, accountId: $accountId})`;
46
+ matchClause = includeTrashed
47
+ ? `MATCH (p:Person {telephone: $telephone, accountId: $accountId})`
48
+ : `MATCH (p:Person {telephone: $telephone, accountId: $accountId}) WHERE ${notTrashed("p")}`;
34
49
  queryParams.telephone = telephone.trim();
35
50
  }
36
51
  return { matchClause, queryParams };
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-person.js","sourceRoot":"","sources":["../../src/lib/resolve-person.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAaH,MAAM,UAAU,kBAAkB,CAChC,UAA4B,EAC5B,SAAiB;IAEjB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;IAEhD,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,WAAW,GAA4B,EAAE,SAAS,EAAE,CAAC;IAE3D,IAAI,WAAmB,CAAC;IACxB,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,GAAG,4EAA4E,CAAC;YAC3F,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,qEAAqE,CAAC;YACpF,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,EAAE,CAAC;QACjB,WAAW,GAAG,yDAAyD,CAAC;QACxE,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,iEAAiE,CAAC;QAChF,WAAW,CAAC,SAAS,GAAG,SAAU,CAAC,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"resolve-person.js","sourceRoot":"","sources":["../../src/lib/resolve-person.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAkB1E,MAAM,UAAU,kBAAkB,CAChC,UAA4B,EAC5B,SAAiB,EACjB,UAA0B,EAAE;IAE5B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;IAChD,MAAM,EAAE,cAAc,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAE3C,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,WAAW,GAA4B,EAAE,SAAS,EAAE,CAAC;IAC3D,MAAM,WAAW,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;IAEpE,IAAI,WAAmB,CAAC;IACxB,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,GAAG,6EAA6E,WAAW,EAAE,CAAC;YACzG,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,sEAAsE,WAAW,EAAE,CAAC;YAClG,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,EAAE,CAAC;QACjB,WAAW,GAAG,cAAc;YAC1B,CAAC,CAAC,yDAAyD;YAC3D,CAAC,CAAC,iEAAiE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACvF,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,cAAc;YAC1B,CAAC,CAAC,iEAAiE;YACnE,CAAC,CAAC,yEAAyE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/F,WAAW,CAAC,SAAS,GAAG,SAAU,CAAC,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AACtC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"contact-create.d.ts","sourceRoot":"","sources":["../../src/tools/contact-create.ts"],"names":[],"mappings":"AAqBA,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CA+F9B"}
1
+ {"version":3,"file":"contact-create.d.ts","sourceRoot":"","sources":["../../src/tools/contact-create.ts"],"names":[],"mappings":"AAsBA,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAmG9B"}
@@ -1,4 +1,5 @@
1
1
  import { getSession } from "../lib/neo4j.js";
2
+ import { notTrashed } from "../../../../../lib/graph-trash/dist/index.js";
2
3
  const OLLAMA_URL = process.env.OLLAMA_URL ?? "http://localhost:11434";
3
4
  const EMBED_MODEL = process.env.EMBED_MODEL ?? "nomic-embed-text";
4
5
  async function computeEmbedding(text) {
@@ -38,8 +39,12 @@ export async function contactCreate(params) {
38
39
  dedupConditions.push("p.telephone = $telephone");
39
40
  dedupParams.telephone = normalizedPhone;
40
41
  }
42
+ // Dedup only matches live persons. Trashed persons already have null
43
+ // email/telephone (UNIQUE_KEYS_BY_LABEL snapshot), so OR-matching by
44
+ // those keys would miss them anyway — the notTrashed() filter is
45
+ // belt-and-braces against the legacy deletedAt soft-delete state.
41
46
  const existing = await session.run(`MATCH (p:Person {accountId: $accountId})
42
- WHERE ${dedupConditions.join(" OR ")}
47
+ WHERE (${dedupConditions.join(" OR ")}) AND ${notTrashed("p")}
43
48
  RETURN elementId(p) AS nodeId, p.email AS email, p.telephone AS telephone`, dedupParams);
44
49
  if (existing.records.length > 0) {
45
50
  const matchedEmail = existing.records[0].get("email");
@@ -1 +1 @@
1
- {"version":3,"file":"contact-create.js","sourceRoot":"","sources":["../../src/tools/contact-create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contact-create.js","sourceRoot":"","sources":["../../src/tools/contact-create.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"contact-delete.d.ts","sourceRoot":"","sources":["../../src/tools/contact-delete.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,mBAAmB;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CA8C9B"}
1
+ {"version":3,"file":"contact-delete.d.ts","sourceRoot":"","sources":["../../src/tools/contact-delete.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,mBAAmB;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CA+C9B"}
@@ -3,7 +3,7 @@ import { resolvePersonMatch } from "../lib/resolve-person.js";
3
3
  import { trashNode } from "../../../../../lib/graph-trash/dist/index.js";
4
4
  export async function contactDelete(params) {
5
5
  const { nodeId, email, telephone, reason, accountId } = params;
6
- const { matchClause, queryParams } = resolvePersonMatch({ nodeId, email, telephone }, accountId);
6
+ const { matchClause, queryParams } = resolvePersonMatch({ nodeId, email, telephone }, accountId, { includeTrashed: true });
7
7
  const session = getSession();
8
8
  try {
9
9
  const lookup = await session.run(`${matchClause}
@@ -1 +1 @@
1
- {"version":3,"file":"contact-delete.js","sourceRoot":"","sources":["../../src/tools/contact-delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AA8BzE,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B;IAE3B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAE/D,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,kBAAkB,CACrD,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAC5B,SAAU,CACX,CAAC;IAEF,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,GAAG,WAAW;;;;mCAIe,EAC7B,WAAW,CACZ,CAAC;QAEF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAW,CAAC;QACnD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAkB,CAAC;QACpE,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAkB,CAAC;QACxE,MAAM,UAAU,GAAG,WAAW,IAAI,WAAW,IAAI,MAAM,IAAI,SAAS,CAAC;QAErE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;YAC7B,OAAO;YACP,SAAS,EAAE,SAAU;YACrB,SAAS,EAAE,GAAG;YACd,EAAE,EAAE,gBAAgB;YACpB,MAAM;SACP,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,SAAS,EAAE,GAAG;YACd,UAAU;SACX,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"contact-delete.js","sourceRoot":"","sources":["../../src/tools/contact-delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AA8BzE,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B;IAE3B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAE/D,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,kBAAkB,CACrD,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAC5B,SAAU,EACV,EAAE,cAAc,EAAE,IAAI,EAAE,CACzB,CAAC;IAEF,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,GAAG,WAAW;;;;mCAIe,EAC7B,WAAW,CACZ,CAAC;QAEF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAW,CAAC;QACnD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAkB,CAAC;QACpE,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAkB,CAAC;QACxE,MAAM,UAAU,GAAG,WAAW,IAAI,WAAW,IAAI,MAAM,IAAI,SAAS,CAAC;QAErE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;YAC7B,OAAO;YACP,SAAS,EAAE,SAAU;YACrB,SAAS,EAAE,GAAG;YACd,EAAE,EAAE,gBAAgB;YACpB,MAAM;SACP,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,SAAS,EAAE,GAAG;YACd,UAAU;SACX,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"contact-erase.d.ts","sourceRoot":"","sources":["../../src/tools/contact-erase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,KAAK,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,YAAY,CAAC;AAE7D,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAqL7B"}
1
+ {"version":3,"file":"contact-erase.d.ts","sourceRoot":"","sources":["../../src/tools/contact-erase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,KAAK,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,YAAY,CAAC;AAE7D,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAsL7B"}
@@ -16,7 +16,7 @@ import { resolvePersonMatch } from "../lib/resolve-person.js";
16
16
  export async function contactErase(params) {
17
17
  const { nodeId, email, telephone, confirm = false, accountId } = params;
18
18
  const startMs = Date.now();
19
- const { matchClause, queryParams } = resolvePersonMatch({ nodeId, email, telephone }, accountId);
19
+ const { matchClause, queryParams } = resolvePersonMatch({ nodeId, email, telephone }, accountId, { includeTrashed: true });
20
20
  const session = getSession();
21
21
  try {
22
22
  // Step 1: Resolve Person node and gather its properties
@@ -1 +1 @@
1
- {"version":3,"file":"contact-erase.js","sourceRoot":"","sources":["../../src/tools/contact-erase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAgC9D,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAA0B;IAE1B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,GAAG,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IACxE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE3B,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,kBAAkB,CACrD,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAC5B,SAAS,CACV,CAAC;IAEF,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,wDAAwD;QACxD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC,GAAG,WAAW;;mEAE+C,EAC7D,WAAW,CACZ,CAAC;QAEF,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtC,MAAM,UAAU,GAAG,KAAK,IAAI,SAAS,IAAI,MAAM,IAAI,SAAS,CAAC;YAC7D,OAAO,CAAC,KAAK,CACX,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,WAAW;gBACnB,UAAU;gBACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;aAChC,CAAC,CACH,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAW,CAAC;QAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAkB,CAAC;QAC/D,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAkB,CAAC;QAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAkB,CAAC;QAC3D,MAAM,UAAU,GAAG,WAAW,IAAI,WAAW,IAAI,MAAM,IAAI,SAAS,CAAC;QAErE,sCAAsC;QACtC,MAAM,MAAM,GAAgB;YAC1B,QAAQ,EAAE,CAAC;YACX,aAAa,EAAE,CAAC;YAChB,MAAM,EAAE,CAAC;YACT,YAAY,EAAE,CAAC;YACf,MAAM,EAAE,CAAC;SACV,CAAC;QAEF,+CAA+C;QAC/C,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,GAAG,CACvC;;qEAE6D,EAC7D,EAAE,SAAS,EAAE,SAAS,EAAE,CACzB,CAAC;YACF,IAAI,eAAe,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,MAAM,CAAC,aAAa,GAAI,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAqB,CAAC,GAAG,IAAI,CAAC,CAAC;gBACjG,MAAM,CAAC,QAAQ,GAAI,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAqB,CAAC,GAAG,IAAI,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,GAAG,CACxC;;uCAE+B,EAC/B,EAAE,WAAW,EAAE,SAAS,EAAE,CAC3B,CAAC;YACF,IAAI,gBAAgB,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxC,MAAM,CAAC,MAAM,GAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAqB,CAAC,GAAG,IAAI,CAAC,CAAC;YAC9F,CAAC;QACH,CAAC;QAED,qBAAqB;QACrB,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,GAAG,CACxC;;qCAE+B,EAC/B,EAAE,YAAY,EAAE,CACjB,CAAC;QACF,IAAI,gBAAgB,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,YAAY,GAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAqB,CAAC,GAAG,IAAI,CAAC,CAAC;QACpG,CAAC;QAED,wCAAwC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACX,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,SAAS;gBACjB,UAAU;gBACV,SAAS,EAAE,KAAK;gBAChB,MAAM;gBACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;aAChC,CAAC,CACH,CAAC;YAEF,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAClD,CAAC;QAED,2DAA2D;QAC3D,MAAM,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAEtC,IAAI,CAAC;YACH,kDAAkD;YAClD,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,EAAE,CAAC,GAAG,CACV;2BACiB,EACjB,EAAE,SAAS,EAAE,SAAS,EAAE,CACzB,CAAC;gBAEF,qCAAqC;gBACrC,MAAM,EAAE,CAAC,GAAG,CACV;;2BAEiB,EACjB,EAAE,SAAS,EAAE,SAAS,EAAE,CACzB,CAAC;YACJ,CAAC;YAED,iDAAiD;YACjD,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,EAAE,CAAC,GAAG,CACV;;2BAEiB,EACjB,EAAE,WAAW,EAAE,SAAS,EAAE,CAC3B,CAAC;YACJ,CAAC;YAED,2CAA2C;YAC3C,MAAM,EAAE,CAAC,GAAG,CACV;;kBAEU,EACV,EAAE,YAAY,EAAE,CACjB,CAAC;YAEF,+EAA+E;YAC/E,MAAM,EAAE,CAAC,GAAG,CACV;yBACiB,EACjB,EAAE,YAAY,EAAE,CACjB,CAAC;YAEF,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CACX,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,OAAO;gBACf,UAAU;gBACV,SAAS,EAAE,IAAI;gBACf,MAAM;gBACN,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;gBACxD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;aAChC,CAAC,CACH,CAAC;YACF,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,OAAO,CAAC,KAAK,CACX,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,SAAS;YACjB,UAAU;YACV,SAAS,EAAE,IAAI;YACf,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;SAChC,CAAC,CACH,CAAC;QAEF,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IACjD,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"contact-erase.js","sourceRoot":"","sources":["../../src/tools/contact-erase.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"group-create.d.ts","sourceRoot":"","sources":["../../src/tools/group-create.ts"],"names":[],"mappings":"AAYA,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA8FvF"}
1
+ {"version":3,"file":"group-create.d.ts","sourceRoot":"","sources":["../../src/tools/group-create.ts"],"names":[],"mappings":"AAaA,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkGvF"}
@@ -1,5 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { getSession } from "../lib/neo4j.js";
3
+ import { notTrashed } from "../../../../../lib/graph-trash/dist/index.js";
3
4
  function generateGroupSlug(name) {
4
5
  const base = name
5
6
  .toLowerCase()
@@ -17,8 +18,11 @@ export async function groupCreate(params) {
17
18
  let groupSlug = generateGroupSlug(groupName);
18
19
  const session = getSession();
19
20
  try {
20
- // Check slug uniqueness
21
+ // Check slug uniqueness — only against live conversations. A trashed
22
+ // conversation holding the same slug would otherwise force an
23
+ // unnecessary slug suffix.
21
24
  const existing = await session.run(`MATCH (c:Conversation {groupSlug: $slug, accountId: $accountId})
25
+ WHERE ${notTrashed("c")}
22
26
  RETURN count(c) AS cnt`, { slug: groupSlug, accountId });
23
27
  if ((existing.records[0]?.get("cnt")?.toNumber?.() ?? 0) > 0) {
24
28
  groupSlug = `${groupSlug}-${randomUUID().slice(0, 4)}`;
@@ -51,9 +55,10 @@ export async function groupCreate(params) {
51
55
  const notFound = [];
52
56
  for (const identifier of participants) {
53
57
  const linkResult = await session.run(`MATCH (p:Person {accountId: $accountId})
54
- WHERE p.givenName + COALESCE(' ' + p.familyName, '') = $identifier
58
+ WHERE (p.givenName + COALESCE(' ' + p.familyName, '') = $identifier
55
59
  OR p.email = $identifier
56
- OR p.telephone = $identifier
60
+ OR p.telephone = $identifier)
61
+ AND ${notTrashed("p")}
57
62
  WITH p LIMIT 1
58
63
  MATCH (c:Conversation {conversationId: $conversationId})
59
64
  MERGE (p)-[r:PARTICIPATES_IN]->(c)
@@ -1 +1 @@
1
- {"version":3,"file":"group-create.js","sourceRoot":"","sources":["../../src/tools/group-create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"group-create.js","sourceRoot":"","sources":["../../src/tools/group-create.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"group-manage.d.ts","sourceRoot":"","sources":["../../src/tools/group-manage.ts"],"names":[],"mappings":"AAEA,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAoFvF"}
1
+ {"version":3,"file":"group-manage.d.ts","sourceRoot":"","sources":["../../src/tools/group-manage.ts"],"names":[],"mappings":"AAGA,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2FvF"}
@@ -1,10 +1,12 @@
1
1
  import { getSession } from "../lib/neo4j.js";
2
+ import { notTrashed } from "../../../../../lib/graph-trash/dist/index.js";
2
3
  export async function groupManage(params) {
3
4
  const { groupSlug, action, participant, accountId } = params;
4
5
  const session = getSession();
5
6
  try {
6
- // Find the group
7
+ // Find the group (skip trashed — they should behave as not-found).
7
8
  const groupResult = await session.run(`MATCH (c:Conversation {groupSlug: $groupSlug, accountId: $accountId, type: 'group'})
9
+ WHERE ${notTrashed("c")}
8
10
  RETURN c.conversationId AS conversationId, c.groupName AS groupName`, { groupSlug, accountId });
9
11
  const record = groupResult.records[0];
10
12
  if (!record) {
@@ -16,9 +18,10 @@ export async function groupManage(params) {
16
18
  if (!participant)
17
19
  throw new Error("participant is required for add action");
18
20
  const addResult = await session.run(`MATCH (p:Person {accountId: $accountId})
19
- WHERE p.givenName + COALESCE(' ' + p.familyName, '') = $participant
21
+ WHERE (p.givenName + COALESCE(' ' + p.familyName, '') = $participant
20
22
  OR p.email = $participant
21
- OR p.telephone = $participant
23
+ OR p.telephone = $participant)
24
+ AND ${notTrashed("p")}
22
25
  WITH p LIMIT 1
23
26
  MATCH (c:Conversation {conversationId: $conversationId})
24
27
  MERGE (p)-[r:PARTICIPATES_IN]->(c)
@@ -34,9 +37,10 @@ export async function groupManage(params) {
34
37
  if (!participant)
35
38
  throw new Error("participant is required for remove action");
36
39
  const removeResult = await session.run(`MATCH (p:Person {accountId: $accountId})-[r:PARTICIPATES_IN]->(c:Conversation {conversationId: $conversationId})
37
- WHERE p.givenName + COALESCE(' ' + p.familyName, '') = $participant
40
+ WHERE (p.givenName + COALESCE(' ' + p.familyName, '') = $participant
38
41
  OR p.email = $participant
39
- OR p.telephone = $participant
42
+ OR p.telephone = $participant)
43
+ AND ${notTrashed("p")}
40
44
  DELETE r
41
45
  RETURN count(r) AS removed`, { accountId, participant, conversationId });
42
46
  const removed = removeResult.records[0]?.get("removed")?.toNumber?.() ?? 0;
@@ -45,8 +49,12 @@ export async function groupManage(params) {
45
49
  }
46
50
  console.error(`[group] participant-removed id=${conversationId.slice(0, 8)}… name=${participant}`);
47
51
  }
48
- // Always return current participants
52
+ // Always return current participants. Trashed persons are filtered out
53
+ // so the group view reflects active membership only — the PARTICIPATES_IN
54
+ // edge survives soft-delete, but the participant list shouldn't surface
55
+ // them.
49
56
  const listResult = await session.run(`MATCH (p:Person)-[r:PARTICIPATES_IN]->(c:Conversation {conversationId: $conversationId})
57
+ WHERE ${notTrashed("p")}
50
58
  RETURN r.displayName AS displayName
51
59
  ORDER BY r.joinedAt ASC`, { conversationId });
52
60
  const participants = listResult.records.map((r) => r.get("displayName"));
@@ -1 +1 @@
1
- {"version":3,"file":"group-manage.js","sourceRoot":"","sources":["../../src/tools/group-manage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAgB7C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAyB;IACzD,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAE7D,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,iBAAiB;QACjB,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC;2EACqE,EACrE,EAAE,SAAS,EAAE,SAAS,EAAE,CACzB,CAAC;QAEF,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAW,CAAC;QAC9D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAW,CAAC;QAEpD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW;gBAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAE5E,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC;;;;;;;;oCAQ4B,EAC5B,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,CAC3C,CAAC;YAEF,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAuB,CAAC;YACrE,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,sBAAsB,WAAW,EAAE,CAAC,CAAC;YACvD,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,gCAAgC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QAC5F,CAAC;aAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,WAAW;gBAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAE/E,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC;;;;;oCAK4B,EAC5B,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,CAC3C,CAAC;YAEF,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC;YAC3E,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,mCAAmC,WAAW,EAAE,CAAC,CAAC;YACpE,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,kCAAkC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,WAAW,EAAE,CAAC,CAAC;QACrG,CAAC;QAED,qCAAqC;QACrC,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC;;+BAEyB,EACzB,EAAE,cAAc,EAAE,CACnB,CAAC;QAEF,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CACzC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAW,CACtC,CAAC;QAEF,OAAO;YACL,MAAM;YACN,SAAS;YACT,WAAW,EAAE,WAAW,IAAI,SAAS;YACrC,YAAY;SACb,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"group-manage.js","sourceRoot":"","sources":["../../src/tools/group-manage.ts"],"names":[],"mappings":"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"}