@rubytech/create-maxy 1.0.772 → 1.0.774

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy",
3
- "version": "1.0.772",
3
+ "version": "1.0.774",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy": "./dist/index.js"
@@ -623,20 +623,58 @@ server.tool("admin-add", "Add a new admin user to this account. Creates a device
623
623
  console.error(`${TAG} account.json write failed: ${err instanceof Error ? err.message : String(err)}`);
624
624
  return { content: [{ type: "text", text: `${TAG} User created in users.json but failed to add to account: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
625
625
  }
626
- // 3. Write to Neo4j (graph-level) partial failure is a warning, not an error
626
+ // 3. Write to Neo4j (graph-level): AdminUser + Person + OWNS atomically,
627
+ // plus ADMIN_OF edge to the LocalBusiness for this account.
628
+ // Task 830 — deterministic identity creation: never delegate node
629
+ // creation to the LLM. Person reuse rule mirrors writeAdminUserAndPerson
630
+ // in platform/ui/app/lib/neo4j-store.ts (case-insensitive exact match
631
+ // on givenName + familyName; partial-name ambiguity does NOT match —
632
+ // rationalisation is a separate agent-mediated concern).
627
633
  let neo4jWarning = "";
634
+ let personReused = false;
628
635
  try {
629
636
  const session = getSession();
630
637
  try {
631
638
  const createdAt = new Date().toISOString();
632
639
  const trimmedName = name.trim();
633
- await session.run(`MERGE (au:AdminUser {userId: $userId})
640
+ const firstSpace = trimmedName.search(/\s/);
641
+ const givenName = firstSpace === -1 ? trimmedName : trimmedName.slice(0, firstSpace).trim();
642
+ const familyName = firstSpace === -1 ? null : (trimmedName.slice(firstSpace + 1).trim() || null);
643
+ const result = await session.run(`MERGE (au:AdminUser {userId: $userId})
634
644
  ON CREATE SET au.name = $name, au.createdAt = $createdAt
635
- ON MATCH SET au.name = $name
645
+ ON MATCH SET au.name = $name, au.updatedAt = $createdAt
636
646
  WITH au
637
647
  MATCH (b:LocalBusiness {accountId: $accountId})
638
648
  MERGE (au)-[r:ADMIN_OF]->(b)
639
- ON CREATE SET r.role = 'admin', r.grantedAt = $createdAt`, { userId, name: trimmedName, createdAt, accountId: ACCOUNT_ID });
649
+ ON CREATE SET r.role = 'admin', r.grantedAt = $createdAt
650
+ WITH au
651
+ OPTIONAL MATCH (existingPerson:Person {accountId: $accountId})
652
+ WHERE toLower(existingPerson.givenName) = toLower($givenName)
653
+ AND coalesce(toLower(existingPerson.familyName), '') = coalesce(toLower($familyName), '')
654
+ WITH au, existingPerson
655
+ CALL {
656
+ WITH au, existingPerson
657
+ WITH au, existingPerson WHERE existingPerson IS NOT NULL
658
+ MERGE (au)-[:OWNS]->(existingPerson)
659
+ RETURN true AS reused
660
+ UNION
661
+ WITH au, existingPerson
662
+ WITH au WHERE existingPerson IS NULL
663
+ CREATE (newPerson:Person {
664
+ accountId: $accountId,
665
+ givenName: $givenName,
666
+ familyName: $familyName,
667
+ role: 'admin-personal',
668
+ scope: 'admin',
669
+ createdAt: $createdAt
670
+ })
671
+ MERGE (au)-[:OWNS]->(newPerson)
672
+ RETURN false AS reused
673
+ }
674
+ RETURN reused`, { userId, name: trimmedName, createdAt, accountId: ACCOUNT_ID, givenName, familyName });
675
+ if (result.records.length > 0) {
676
+ personReused = result.records[0].get("reused");
677
+ }
640
678
  }
641
679
  finally {
642
680
  await session.close();
@@ -647,6 +685,7 @@ server.tool("admin-add", "Add a new admin user to this account. Creates a device
647
685
  console.error(`${TAG} Neo4j sync failed during admin-add: userId=${userId} error=${errMsg} — files written, graph pending`);
648
686
  neo4jWarning = ` Note: Neo4j sync failed (${errMsg}) — the admin user is functional but the graph will need reconciliation on next seed.`;
649
687
  }
688
+ console.error(`${TAG} [admin-identity] adminuser-bound userId=${userId.slice(0, 8)} name=${name.trim()} personReused=${personReused}`);
650
689
  console.error(`${TAG} admin added: userId=${userId} userName=${name.trim()} accountId=${ACCOUNT_ID} role=admin addedBy=${callerUserId ?? "unknown"}`);
651
690
  return {
652
691
  content: [{