@rubytech/create-maxy 1.0.687 → 1.0.689

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 (24) hide show
  1. package/dist/__tests__/port-canonicalisation.test.js +193 -0
  2. package/dist/index.js +35 -74
  3. package/dist/port-resolution.js +109 -0
  4. package/package.json +3 -2
  5. package/payload/platform/package-lock.json +1253 -14
  6. package/payload/platform/plugins/docs/references/contacts-guide.md +2 -0
  7. package/payload/platform/plugins/docs/references/deployment.md +4 -2
  8. package/payload/platform/plugins/docs/references/platform.md +1 -1
  9. package/payload/platform/plugins/docs/references/troubleshooting.md +3 -1
  10. package/payload/platform/plugins/waitlist/mcp/dist/tools/__tests__/waitlist-persist.test.d.ts +2 -0
  11. package/payload/platform/plugins/waitlist/mcp/dist/tools/__tests__/waitlist-persist.test.d.ts.map +1 -0
  12. package/payload/platform/plugins/waitlist/mcp/dist/tools/__tests__/waitlist-persist.test.js +70 -0
  13. package/payload/platform/plugins/waitlist/mcp/dist/tools/__tests__/waitlist-persist.test.js.map +1 -0
  14. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.d.ts +20 -0
  15. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.d.ts.map +1 -1
  16. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.js +80 -0
  17. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.js.map +1 -1
  18. package/payload/platform/plugins/waitlist/mcp/package.json +4 -2
  19. package/payload/platform/plugins/waitlist/mcp/vitest.config.ts +9 -0
  20. package/payload/server/chunk-ZL2A4ROK.js +11416 -0
  21. package/payload/server/maxy-edge.js +411 -10
  22. package/payload/server/public/assets/{graph-tjXdtwk-.js → graph-MLjOrKLo.js} +14 -14
  23. package/payload/server/public/graph.html +1 -1
  24. package/payload/server/server.js +1087 -11876
@@ -57,6 +57,8 @@ This is different from GDPR erasure (`contact-erase`). Deleting a contact remove
57
57
 
58
58
  For businesses using Maxy's public agent: when a visitor expresses interest in signing up, the public agent collects their name and email in conversation. The waitlist plugin's scheduled extraction job processes these conversations and creates Person nodes with status `waitlist`.
59
59
 
60
+ Each waitlist-extracted Person is linked to the source conversation two ways: as a scalar `sessionId` on the Person record (used by data exports) and as a `PARTICIPATES_IN` graph edge (used by the graph view). Both are set atomically when the extraction runs, so the Person appears on `/graph` next to the conversation they were extracted from rather than as a standalone dot.
61
+
60
62
  To review the waitlist: "Show me the waitlist" or "Who's on the waitlist?"
61
63
 
62
64
  ## Exporting Contact Data (GDPR Subject Access)
@@ -70,8 +70,10 @@ The logs will show which service failed to start and why. Common causes:
70
70
 
71
71
  Each installed brand runs two per-brand `--user` systemd units (Task 662 + Task 664 — unit filenames are prefixed with the brand's `hostname` so two brands on the same device never share a unit file):
72
72
 
73
- - `{hostname}.service` — the admin + public HTTP server on `127.0.0.1:19199`. Restarted by the upgrade flow; short downtime is expected during steps 8→11 of an upgrade.
74
- - `{hostname}-edge.service` — the always-on public listener on the configured port (default 19200). Reverse-proxies HTTP to the main brand service and handles `/websockify` (VNC) WebSocket upgrades locally. Does NOT restart during an upgrade — the browser WebSocket stays connected by construction.
73
+ - `{hostname}.service` — the admin + public HTTP server on `127.0.0.1:19201` (public port + 1). Restarted by the upgrade flow; short downtime is expected during steps 8→11 of an upgrade. Task 666: the unit carries two port env vars — `PORT=<public>` (canonical public port, read by the upgrade detector) and `MAXY_UI_INTERNAL_PORT=<public+1>` (the port maxy-ui actually binds).
74
+ - `{hostname}-edge.service` — the always-on public listener on the configured port (default 19200). Reverse-proxies HTTP to the main brand service and handles `/websockify` (VNC) WebSocket upgrades locally. Task 666: also hosts `/api/admin/actions/*` and `/api/admin/version*` — the Software Update modal's own routes — so the log stream survives the brand service's restart window. Does NOT restart during an upgrade — the browser WebSocket stays connected by construction.
75
+
76
+ **Port-drift recovery (Task 666).** Devices upgraded between Tasks 647 and 666 may have drifted +1 on every upgrade because the pre-Task-666 installer wrote `Environment=PORT=<internal>` into `{hostname}.service` and the upgrade reader correctly treated `PORT=` as public. The first post-Task-666 install detects this (comparing maxy's PORT against the edge's EDGE_PORT) and emits a one-shot loud log: `[port-recovery] detected drift maxy=<X> edge=<Y> — pinning at <Y>`. Subsequent upgrades are silent. If your Cloudflare tunnel was pointing at a drifted port, the ingress `config.yml` still needs a one-time manual fix: `sed -i 's|localhost:<old>|localhost:<current>|' ~/.{configDir}/cloudflared/config.yml && cloudflared tunnel ingress validate`. Maxy never rewrites cloudflared config programmatically.
75
77
 
76
78
  Upgrade and Cloudflare setup (Task 664) run as detached actions: `systemd-run --user` transient units per invocation with stdout+stderr persisted to `~/.maxy/logs/actions/<actionId>.log` and streamed to the UI via SSE. No boot-time service file exists for these.
77
79
 
@@ -52,7 +52,7 @@ The memory graph is stored on your Pi. It never leaves your network.
52
52
 
53
53
  ## The Web Interface
54
54
 
55
- The web app runs on your Pi on port 19200. A small always-on front door (`maxy-edge`) owns that port and the remote terminal transport — so when the Software Update command restarts the app server, the browser-side terminal keeps streaming bytes exactly like an SSH session would. Login cookies are HMAC-signed with a shared key on disk, so both processes recognise the same session without any coordination and you do not have to log in again after an update. It provides:
55
+ The web app runs on your Pi on port 19200. A small always-on front door (`maxy-edge`) owns that port and the remote terminal transport — so when the Software Update command restarts the app server, the browser-side terminal keeps streaming bytes exactly like an SSH session would. The edge also hosts the update flow's own routes (the sudo prompt, the action launcher, the SSE progress stream, the installed-version poll), so the Software Update modal's log panel does not go blank during the app-server restart window — it keeps receiving lines, heartbeats, and the final exit event unbroken. Login cookies are HMAC-signed with a shared key on disk, so both processes recognise the same session without any coordination and you do not have to log in again after an update. It provides:
56
56
 
57
57
  - **Admin chat** (at `/`) — your primary interface, PIN-protected
58
58
  - **Public chat** (at `/{agent-name}`) — visitor-facing agents, each with their own URL. On public hostnames, the root path serves the default agent.
@@ -95,7 +95,9 @@ If the initial Cloudflare login fails during setup, Maxy will fall back to askin
95
95
 
96
96
  ## Action runner — upgrade or Cloudflare setup appears stuck
97
97
 
98
- Task 664 replaced the ttyd/xterm admin terminal with a detached action runner. Upgrades and Cloudflare setup now run under transient `systemd-run --user` units whose stdout+stderr land in a persisted per-action log, streamed to the browser via SSE.
98
+ Task 664 replaced the ttyd/xterm admin terminal with a detached action runner. Upgrades and Cloudflare setup now run under transient `systemd-run --user` units whose stdout+stderr land in a persisted per-action log, streamed to the browser via SSE. Task 666 moved the four routes that serve the modal (`/api/admin/actions/*`, `/api/admin/version`) onto `maxy-edge.service`, so the log panel's stream survives a mid-run restart of `maxy.service` without reconnecting.
99
+
100
+ **"Connection lost — reconnecting…" banner appears during an upgrade.** On post-Task-666 bundles this should never appear while the upgrade is in flight — the routes live on the always-on edge. If you see the banner during steps 8→11 of an upgrade on a current bundle, it is a **regression**, not expected behaviour: the routes have drifted back onto `maxy.service` or the edge's Hono dispatcher is not intercepting them. Check `~/.maxy/logs/edge.log` for `[edge-admin]` entries during the window; absence means the edge never received the request. The prebuild gate `platform/ui/scripts/check-edge-admin-routes.mjs` exists specifically to catch this drift before it ships.
99
101
 
100
102
  **Heartbeat stalled** (log panel header shows rising `silent Ns` amber badge).
101
103
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=waitlist-persist.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waitlist-persist.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/waitlist-persist.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Task 667 Issue 2 — regression gate for the PARTICIPATES_IN cypher shape.
3
+ *
4
+ * The waitlist extraction used to store the Conversation join only as
5
+ * `p.sessionId = $conversationId` (a scalar), and `/graph` traverses
6
+ * edges only — so every waitlist-extracted Person rendered as a
7
+ * graph-orphan. The fix writes the canonical `(p:Person)-[:PARTICIPATES_IN]->(c:Conversation)`
8
+ * edge on the same session as the Person MERGE.
9
+ *
10
+ * Behavioural verification (insert + re-run + tombstone cases) runs via
11
+ * the Real Agent cron cycle described in Task 667's Verification
12
+ * section — this test is the plain-text regression gate: if the
13
+ * composed cypher ever stops containing the expected MATCH / OPTIONAL
14
+ * MATCH / MERGE / ON CREATE SET clauses, the shape has drifted and
15
+ * the Pi-side behavioural test won't run until the next cron cycle,
16
+ * four hours later. The string assertions fire in milliseconds.
17
+ */
18
+ import { describe, it, expect } from "vitest";
19
+ import { PARTICIPATES_IN_CYPHER } from "../waitlist-persist.js";
20
+ describe("PARTICIPATES_IN_CYPHER (Task 667)", () => {
21
+ it("MATCHes the Person node scoped by email+accountId", () => {
22
+ expect(PARTICIPATES_IN_CYPHER).toMatch(/MATCH \(p:Person \{email: \$email, accountId: \$accountId\}\)/);
23
+ });
24
+ it("OPTIONAL MATCHes the Conversation scoped by conversationId+accountId", () => {
25
+ expect(PARTICIPATES_IN_CYPHER).toMatch(/OPTIONAL MATCH \(c:Conversation \{conversationId: \$conversationId, accountId: \$accountId\}\)/);
26
+ });
27
+ it("guards against the tombstone path via WHERE c IS NOT NULL", () => {
28
+ // A reference to a deleted/never-existed Conversation returns zero
29
+ // records rather than erroring — the caller logs `edge-skipped
30
+ // tombstone` and moves on. Dropping this clause would make the MERGE
31
+ // create a dangling `(p)-[:PARTICIPATES_IN]->(NULL)` (not permitted
32
+ // by Neo4j, so the whole extraction would throw instead of skip).
33
+ expect(PARTICIPATES_IN_CYPHER).toMatch(/WHERE c IS NOT NULL/);
34
+ });
35
+ it("MERGEs the PARTICIPATES_IN edge idempotently", () => {
36
+ expect(PARTICIPATES_IN_CYPHER).toMatch(/MERGE \(p\)-\[r:PARTICIPATES_IN\]->\(c\)/);
37
+ });
38
+ it("sets r.joinedAt = datetime() on CREATE only (matches group-manage.ts:51)", () => {
39
+ // Preserving joinedAt on MATCH is load-bearing for idempotency: a
40
+ // second cron cycle must not bump the timestamp. This test mirrors
41
+ // the invariant `group-manage` enforces.
42
+ expect(PARTICIPATES_IN_CYPHER).toMatch(/ON CREATE SET r\.joinedAt = datetime\(\)/);
43
+ expect(PARTICIPATES_IN_CYPHER).not.toMatch(/ON MATCH SET r\.joinedAt/);
44
+ });
45
+ it("reports edgeCreated via an OPTIONAL-MATCH pre-check", () => {
46
+ // The boolean drives the log line that distinguishes `edge-created`
47
+ // (fresh) from re-runs (idempotent no-op). Removing it collapses
48
+ // both into silence. The pre-check is an additional OPTIONAL MATCH
49
+ // against an `existing` edge (rather than an `EXISTS { }` projection)
50
+ // because `EXISTS { }` as a WITH-projection alias is Neo4j 5.13+;
51
+ // the OPTIONAL-MATCH form is safe across every 5.x minor version.
52
+ expect(PARTICIPATES_IN_CYPHER).toMatch(/OPTIONAL MATCH \(p\)-\[existing:PARTICIPATES_IN\]->\(c\)/);
53
+ expect(PARTICIPATES_IN_CYPHER).toMatch(/existing IS NOT NULL AS hadEdge/);
54
+ expect(PARTICIPATES_IN_CYPHER).toMatch(/NOT hadEdge AS edgeCreated/);
55
+ // Negative assertion: no EXISTS-subquery-as-projection syntax (older
56
+ // Neo4j CE installs throw SyntaxError on this form).
57
+ expect(PARTICIPATES_IN_CYPHER).not.toMatch(/EXISTS \{ MATCH [^}]+\} AS hadEdge/);
58
+ });
59
+ it("RETURNs conversationId so the caller can confirm which Conversation was linked", () => {
60
+ expect(PARTICIPATES_IN_CYPHER).toMatch(/RETURN c\.conversationId AS conversationId/);
61
+ });
62
+ it("never references p.sessionId (the legacy scalar join is write-untouched)", () => {
63
+ // The sessionId coexistence note in .docs/neo4j.md is load-bearing
64
+ // for contact-export.ts:122 — the edge and the scalar are
65
+ // defence-in-depth, not alternatives. If this cypher starts
66
+ // touching p.sessionId, the write-path semantics have drifted.
67
+ expect(PARTICIPATES_IN_CYPHER).not.toMatch(/p\.sessionId/);
68
+ });
69
+ });
70
+ //# sourceMappingURL=waitlist-persist.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waitlist-persist.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/waitlist-persist.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,sBAAsB,CAAC,CAAC,OAAO,CACpC,+DAA+D,CAChE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,CAAC,sBAAsB,CAAC,CAAC,OAAO,CACpC,gGAAgG,CACjG,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,mEAAmE;QACnE,+DAA+D;QAC/D,qEAAqE;QACrE,oEAAoE;QACpE,kEAAkE;QAClE,MAAM,CAAC,sBAAsB,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,sBAAsB,CAAC,CAAC,OAAO,CACpC,0CAA0C,CAC3C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,kEAAkE;QAClE,mEAAmE;QACnE,yCAAyC;QACzC,MAAM,CAAC,sBAAsB,CAAC,CAAC,OAAO,CACpC,0CAA0C,CAC3C,CAAC;QACF,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,oEAAoE;QACpE,iEAAiE;QACjE,mEAAmE;QACnE,sEAAsE;QACtE,kEAAkE;QAClE,kEAAkE;QAClE,MAAM,CAAC,sBAAsB,CAAC,CAAC,OAAO,CACpC,0DAA0D,CAC3D,CAAC;QACF,MAAM,CAAC,sBAAsB,CAAC,CAAC,OAAO,CACpC,iCAAiC,CAClC,CAAC;QACF,MAAM,CAAC,sBAAsB,CAAC,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACrE,qEAAqE;QACrE,qDAAqD;QACrD,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,MAAM,CAAC,sBAAsB,CAAC,CAAC,OAAO,CACpC,4CAA4C,CAC7C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,mEAAmE;QACnE,0DAA0D;QAC1D,4DAA4D;QAC5D,+DAA+D;QAC/D,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -59,5 +59,25 @@ export interface WaitlistPersistResult {
59
59
  filtered: number;
60
60
  errors: number;
61
61
  }
62
+ /**
63
+ * Cypher emitted on every waitlist extraction carrying a `conversationId`.
64
+ * Exported so a unit test can assert the cypher shape (MATCH, OPTIONAL
65
+ * MATCH, MERGE, ON CREATE SET) without spinning up a Neo4j driver.
66
+ * Plain-text regression gate; behavioural verification is via the Real
67
+ * Agent cron-cycle manual repro described in Task 667's Verification
68
+ * section.
69
+ *
70
+ * CREATE-vs-MATCH detection: an additional `OPTIONAL MATCH` against an
71
+ * `existing` edge runs before the MERGE and its `IS NOT NULL`
72
+ * projection drives the returned `edgeCreated` boolean. This form
73
+ * works across every Neo4j 5.x minor version; an `EXISTS { ... } AS
74
+ * hadEdge` in a WITH projection is a 5.13+-only alias form and
75
+ * produces `Neo.ClientError.Statement.SyntaxError` on older CE
76
+ * installs, silently swallowed by the outer `catch (edgeErr)` in
77
+ * `createOrUpdatePerson` — the Person would be written and the edge
78
+ * never would. The OPTIONAL-MATCH-before-MERGE form is the safe
79
+ * equivalent.
80
+ */
81
+ export declare const PARTICIPATES_IN_CYPHER = "MATCH (p:Person {email: $email, accountId: $accountId})\nOPTIONAL MATCH (c:Conversation {conversationId: $conversationId, accountId: $accountId})\nWHERE c IS NOT NULL\nOPTIONAL MATCH (p)-[existing:PARTICIPATES_IN]->(c)\nWITH p, c, existing IS NOT NULL AS hadEdge\nMERGE (p)-[r:PARTICIPATES_IN]->(c)\nON CREATE SET r.joinedAt = datetime()\nRETURN c.conversationId AS conversationId, NOT hadEdge AS edgeCreated";
62
82
  export declare function waitlistPersist(params: WaitlistPersistParams): Promise<WaitlistPersistResult>;
63
83
  //# sourceMappingURL=waitlist-persist.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"waitlist-persist.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-persist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAUH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAmTD,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAqFhC"}
1
+ {"version":3,"file":"waitlist-persist.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-persist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAUH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAgMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,sBAAsB,6ZAOmC,CAAC;AAgLvE,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAqFhC"}
@@ -163,6 +163,58 @@ function emailInSource(email, conversationId, index) {
163
163
  return allMessages ? allMessages.includes(emailLower) : true;
164
164
  }
165
165
  // ---------------------------------------------------------------------------
166
+ // Participation edge (Task 667)
167
+ //
168
+ // The waitlist extraction writes `p.sessionId = $conversationId` as a scalar
169
+ // join to the source PublicConversation, but `/graph` traverses edges only
170
+ // — so waitlist-extracted Persons rendered as graph-orphans despite sharing
171
+ // a Conversation with every other message on it. The canonical edge used
172
+ // by `group-create`, `group-manage`, and `neo4j-store.ts` is
173
+ // `(:Person)-[:PARTICIPATES_IN]->(:Conversation)` (.docs/neo4j.md "Group
174
+ // conversations"); the fix extends waitlist-persist to write that edge
175
+ // inside the same session as the Person MERGE, guarded by
176
+ // `conversationId` presence.
177
+ //
178
+ // Constraints honoured:
179
+ // - `r.joinedAt = datetime()` on CREATE mirrors group-manage.ts:51.
180
+ // On MATCH the existing timestamp is preserved (idempotent).
181
+ // - OPTIONAL MATCH on the Conversation so a reference to a deleted /
182
+ // never-existed Conversation produces a zero-record result rather
183
+ // than an error. The caller logs the skip, persists the Person,
184
+ // continues.
185
+ // - accountId scoping on both the Person MATCH and the Conversation
186
+ // MATCH — the edge is brand-scoped exactly like the nodes.
187
+ // - `EXISTS {}` subquery reports CREATE vs MATCH via a pre-check so
188
+ // the log line distinguishes fresh edges from idempotent re-runs.
189
+ // ---------------------------------------------------------------------------
190
+ /**
191
+ * Cypher emitted on every waitlist extraction carrying a `conversationId`.
192
+ * Exported so a unit test can assert the cypher shape (MATCH, OPTIONAL
193
+ * MATCH, MERGE, ON CREATE SET) without spinning up a Neo4j driver.
194
+ * Plain-text regression gate; behavioural verification is via the Real
195
+ * Agent cron-cycle manual repro described in Task 667's Verification
196
+ * section.
197
+ *
198
+ * CREATE-vs-MATCH detection: an additional `OPTIONAL MATCH` against an
199
+ * `existing` edge runs before the MERGE and its `IS NOT NULL`
200
+ * projection drives the returned `edgeCreated` boolean. This form
201
+ * works across every Neo4j 5.x minor version; an `EXISTS { ... } AS
202
+ * hadEdge` in a WITH projection is a 5.13+-only alias form and
203
+ * produces `Neo.ClientError.Statement.SyntaxError` on older CE
204
+ * installs, silently swallowed by the outer `catch (edgeErr)` in
205
+ * `createOrUpdatePerson` — the Person would be written and the edge
206
+ * never would. The OPTIONAL-MATCH-before-MERGE form is the safe
207
+ * equivalent.
208
+ */
209
+ export const PARTICIPATES_IN_CYPHER = `MATCH (p:Person {email: $email, accountId: $accountId})
210
+ OPTIONAL MATCH (c:Conversation {conversationId: $conversationId, accountId: $accountId})
211
+ WHERE c IS NOT NULL
212
+ OPTIONAL MATCH (p)-[existing:PARTICIPATES_IN]->(c)
213
+ WITH p, c, existing IS NOT NULL AS hadEdge
214
+ MERGE (p)-[r:PARTICIPATES_IN]->(c)
215
+ ON CREATE SET r.joinedAt = datetime()
216
+ RETURN c.conversationId AS conversationId, NOT hadEdge AS edgeCreated`;
217
+ // ---------------------------------------------------------------------------
166
218
  // Person node creation/update
167
219
  // ---------------------------------------------------------------------------
168
220
  async function createOrUpdatePerson(entry, accountId, discoveryNotes) {
@@ -254,6 +306,34 @@ async function createOrUpdatePerson(entry, accountId, discoveryNotes) {
254
306
  await session.run(`MATCH (p:Person {email: $email, accountId: $accountId})
255
307
  SET p.discoveryNotes = $mergedJson`, { email, accountId, mergedJson });
256
308
  }
309
+ // Task 667 — write the canonical Person→Conversation participation
310
+ // edge on the same session as the Person MERGE. Guarded by
311
+ // `conversationId` presence (waitlist-scan only sets it when the
312
+ // extraction came from a concrete Conversation). Missing Conversation
313
+ // (tombstoned / race / never existed) returns zero records — we log
314
+ // + skip rather than raise, because the Person record itself is the
315
+ // primary artefact of this tool and should survive a dangling
316
+ // reference. `p.sessionId` stays as-is for contact-export.ts (see
317
+ // .docs/neo4j.md coexistence note).
318
+ if (conversationId) {
319
+ try {
320
+ const edgeResult = await session.run(PARTICIPATES_IN_CYPHER, {
321
+ email, accountId, conversationId,
322
+ });
323
+ const edgeRecord = edgeResult.records[0];
324
+ if (!edgeRecord) {
325
+ console.error(`[waitlist-persist] edge-skipped tombstone person=${email} conversation=${conversationId} accountId=${accountId}`);
326
+ }
327
+ else if (edgeRecord.get("edgeCreated")) {
328
+ console.error(`[waitlist-persist] edge-created person=${email} conversation=${conversationId} accountId=${accountId}`);
329
+ }
330
+ }
331
+ catch (edgeErr) {
332
+ // Edge write is best-effort — a cypher error here must not
333
+ // undo the Person MERGE the operator just logged as created.
334
+ console.error(`[waitlist-persist] edge-error person=${email} conversation=${conversationId}: ${edgeErr instanceof Error ? edgeErr.message : String(edgeErr)}`);
335
+ }
336
+ }
257
337
  // Recompute embedding with discovery context
258
338
  if (created || updated || discoveryNotes) {
259
339
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"waitlist-persist.js","sourceRoot":"","sources":["../../src/tools/waitlist-persist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAiDjF,8EAA8E;AAC9E,0BAA0B;AAC1B,8EAA8E;AAE9E,SAAS,mBAAmB,CAAC,KAAsB;IACjD,MAAM,GAAG,GAAG,CAAC,CAAU,EAAiB,EAAE,CACxC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAEtD,MAAM,KAAK,GAAmB;QAC5B,YAAY,EAAE,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC;QACrC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;QACrB,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;QACvB,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC;QACjC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;QAC/B,iBAAiB,EAAE,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC;QAC/C,YAAY,EAAE,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC;KACtC,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAC1B,QAAwB,EACxB,QAAwB;IAExB,OAAO;QACL,YAAY,EAAE,QAAQ,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY;QAC5D,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI;QACpC,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK;QACvC,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU;QACtD,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,SAAS;QACnD,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB,IAAI,QAAQ,CAAC,iBAAiB;QAC3E,YAAY,EAAE,QAAQ,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY;KAC7D,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,SAAS,gBAAgB,CAAC,GAAY;IACpC,qEAAqE;IACrE,mEAAmE;IACnE,2DAA2D;IAC3D,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,iEAAiE;IACjE,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAwB,CAAC;IAClC,CAAC;IAED,gEAAgE;IAChE,gCAAgC;IAChC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,GAAG,GAAG,GAA8B,CAAC;QAE3C,2DAA2D;QAC3D,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAClD,4CAA4C;YAC5C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACpC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;oBAAE,OAAO,MAA2B,CAAC;YAChE,CAAC;YAAC,MAAM,CAAC;gBACP,wBAAwB;YAC1B,CAAC;YACD,MAAM,IAAI,KAAK,CACb,8EAA8E;gBAC9E,gEAAgE,CACjE,CAAC;QACJ,CAAC;QAED,mEAAmE;QACnE,2EAA2E;QAC3E,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,SAAS;YAAE,OAAO,SAA8B,CAAC;IACvD,CAAC;IAED,MAAM,IAAI,KAAK,CACb,uCAAuC;QACvC,sEAAsE,CACvE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,sBAAsB,CAC7B,aAAsB;IAEtB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAExC,IAAI,CAAC,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEtE,kDAAkD;IAClD,IAAI,SAAmC,CAAC;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QACjC,SAAS,GAAG,aAAyC,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,aAAwC,CAAC;QACrD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;YACrC,SAAS,GAAG,GAAG,CAAC,aAAyC,CAAC;QAC5D,CAAC;aAAM,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACzD,sCAAsC;YACtC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACpC,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;oBAClD,SAAS,GAAG,MAAM,CAAC,aAAyC,CAAC;gBAC/D,CAAC;qBAAM,CAAC;oBACN,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7D,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACvC,WAAW,IAAI,GAAG,GAAG,MAAM,CAAC;IAC9B,CAAC;IACD,2EAA2E;IAC3E,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAElC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CACpB,KAAa,EACb,cAAyC,EACzC,KAA0B;IAE1B,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,mCAAmC;IAEtE,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAEvC,oCAAoC;IACpC,IAAI,cAAc,IAAI,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC,GAAG,CAAC,cAAc,CAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACzD,CAAC;IAED,6BAA6B;IAC7B,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,8EAA8E;AAC9E,8BAA8B;AAC9B,8EAA8E;AAE9E,KAAK,UAAU,oBAAoB,CACjC,KAAsB,EACtB,SAAiB,EACjB,cAAqC;IAErC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,MAAM,QAAQ,GAAG,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7F,MAAM,UAAU,GAAG,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACjG,MAAM,OAAO,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/C,MAAM,SAAS,GAAG,QAAQ,IAAI,SAAS,CAAC;IAExC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,WAAW,GAAG,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ,IAAI,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE;YAC7F,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE;YAC/B,CAAC,CAAC,IAAI,CAAC;QACT,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CACX,mDAAmD,KAAK,yBAAyB,CAClF,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,WAAW,IAAI,WAAW,CAAC;QAC7C,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzE,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,IAAI,IAAI,CAAC;QAEpD,MAAM,QAAQ,GAAG;YACf,0BAA0B;YAC1B,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,uBAAuB;YACvB,oBAAoB;YACpB,0BAA0B;YAC1B,8BAA8B;YAC9B,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5D,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACxD,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAEvB,kDAAkD;QAClD,2EAA2E;QAC3E,4CAA4C;QAC5C,yEAAyE;QACzE,MAAM,UAAU,GAAG,OAAO;YACxB,CAAC,CAAC;gBACE,6GAA6G;gBAC7G,GAAG,CAAC,UAAU;oBACZ,CAAC,CAAC;wBACE,uIAAuI;qBACxI;oBACH,CAAC,CAAC,EAAE,CAAC;gBACP,oGAAoG;aACrG,CAAC,IAAI,CAAC,cAAc,CAAC;YACxB,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,aAAa,GAAG,UAAU;YAC9B,CAAC,CAAC,gBAAgB,UAAU,EAAE;YAC9B,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B;uBACiB,QAAQ;SACtB,aAAa;;;gDAG0B,EAC1C;YACE,KAAK;YACL,SAAS;YACT,SAAS;YACT,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,MAAM;YACN,SAAS;YACT,WAAW;YACX,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpC,CACF,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAY,CAAC;QACjD,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAW,CAAC;QACxD,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAkB,CAAC;QACtE,MAAM,OAAO,GAAG,CAAC,OAAO,IAAI,WAAW,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,CAAC;QAEjF,uEAAuE;QACvE,IAAI,UAAU,GAAG,cAAc,CAAC;QAChC,IAAI,CAAC,OAAO,IAAI,cAAc,EAAE,CAAC;YAC/B,IAAI,aAAa,GAA0B,IAAI,CAAC;YAChD,IAAI,gBAAgB,EAAE,CAAC;gBACrB,IAAI,CAAC;oBACH,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAmB,CAAC;gBACjE,CAAC;gBAAC,MAAM,CAAC;oBACP,6DAA6D;gBAC/D,CAAC;YACH,CAAC;YACD,UAAU,GAAG,aAAa;gBACxB,CAAC,CAAC,mBAAmB,CAAC,aAAa,EAAE,cAAc,CAAC;gBACpD,CAAC,CAAC,cAAc,CAAC;YACnB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YAC9C,MAAM,OAAO,CAAC,GAAG,CACf;4CACoC,EACpC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,CACjC,CAAC;QACJ,CAAC;QAED,6CAA6C;QAC7C,IAAI,OAAO,IAAI,OAAO,IAAI,cAAc,EAAE,CAAC;YACzC,IAAI,CAAC;gBACH,MAAM,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACtE,MAAM,gBAAgB,GAAG,wBAAwB,CAC/C,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,CACrD,CAAC;gBACF,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;gBAC3D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzB,MAAM,OAAO,CAAC,GAAG,CACf;0CAC8B,EAC9B,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,CAChC,CAAC;gBACJ,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,8CAA8C;YAChD,CAAC;QACH,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IACtC,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAA6B;IAE7B,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAC;IAE3F,+CAA+C;IAC/C,MAAM,OAAO,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAEjD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC;YACjD,gBAAgB,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC;IAED,8DAA8D;IAC9D,MAAM,SAAS,GAAG,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;IAE3D,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAC3B,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,iBAAiB;YACjB,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACpD,QAAQ,EAAE,CAAC;gBACX,SAAS;YACX,CAAC;YAED,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC/C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,QAAQ,EAAE,CAAC;gBACX,SAAS;YACX,CAAC;YAED,4DAA4D;YAC5D,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,EAAE,SAAS,CAAC,EAAE,CAAC;gBAC3D,OAAO,CAAC,KAAK,CACX,mDAAmD,KAAK,EAAE,CAC3D,CAAC;gBACF,QAAQ,EAAE,CAAC;gBACX,SAAS;YACX,CAAC;YAED,MAAM,cAAc,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,cAAc;gBAAE,kBAAkB,EAAE,CAAC;YAEzC,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,EACnB,SAAS,EACT,cAAc,CACf,CAAC;YAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC/B,gBAAgB,EAAE,CAAC;gBACrB,CAAC;qBAAM,CAAC;oBACN,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC1B,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,QAAQ,EAAE,CAAC;YACb,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACX,uCAAuC,KAAK,CAAC,KAAK,IAAI,SAAS,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACvH,CAAC;YACF,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IAED,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,MAAM;QACzB,OAAO;QACP,OAAO;QACP,QAAQ;QACR,gBAAgB;QAChB,kBAAkB;QAClB,QAAQ;QACR,MAAM;KACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"waitlist-persist.js","sourceRoot":"","sources":["../../src/tools/waitlist-persist.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,8 @@
6
6
  "main": "dist/index.js",
7
7
  "scripts": {
8
8
  "build": "tsc",
9
- "start": "node dist/index.js"
9
+ "start": "node dist/index.js",
10
+ "test": "vitest run"
10
11
  },
11
12
  "dependencies": {
12
13
  "@modelcontextprotocol/sdk": "^1.12.1",
@@ -16,6 +17,7 @@
16
17
  },
17
18
  "devDependencies": {
18
19
  "typescript": "^5.7.0",
19
- "@types/node": "^22.0.0"
20
+ "@types/node": "^22.0.0",
21
+ "vitest": "^4.1.2"
20
22
  }
21
23
  }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: "node",
6
+ include: ["src/**/__tests__/**/*.test.ts"],
7
+ testTimeout: 10_000,
8
+ },
9
+ });