@rubytech/create-maxy-code 0.1.329 → 0.1.331

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 (130) hide show
  1. package/dist/index.js +19 -2
  2. package/package.json +1 -1
  3. package/payload/platform/config/brand.json +1 -0
  4. package/payload/platform/lib/account-enumeration/dist/index.d.ts +33 -0
  5. package/payload/platform/lib/account-enumeration/dist/index.d.ts.map +1 -1
  6. package/payload/platform/lib/account-enumeration/dist/index.js +76 -0
  7. package/payload/platform/lib/account-enumeration/dist/index.js.map +1 -1
  8. package/payload/platform/lib/account-enumeration/src/index.ts +78 -0
  9. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  10. package/payload/platform/plugins/admin/PLUGIN.md +13 -1
  11. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-authoring-skill-gate.test.js +1 -2
  12. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-authoring-skill-gate.test.js.map +1 -1
  13. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.d.ts +1 -1
  14. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.d.ts.map +1 -1
  15. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.js +18 -13
  16. package/payload/platform/plugins/admin/mcp/dist/content-producer-authoring-skills.js.map +1 -1
  17. package/payload/platform/plugins/admin/mcp/dist/index.js +102 -0
  18. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  19. package/payload/platform/plugins/admin/mcp/dist/tools/__tests__/account-lifecycle.test.d.ts +2 -0
  20. package/payload/platform/plugins/admin/mcp/dist/tools/__tests__/account-lifecycle.test.d.ts.map +1 -0
  21. package/payload/platform/plugins/admin/mcp/dist/tools/__tests__/account-lifecycle.test.js +57 -0
  22. package/payload/platform/plugins/admin/mcp/dist/tools/__tests__/account-lifecycle.test.js.map +1 -0
  23. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts +34 -0
  24. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts.map +1 -0
  25. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js +78 -0
  26. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js.map +1 -0
  27. package/payload/platform/plugins/admin/skills/plainly/SKILL.md +7 -0
  28. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +2 -2
  29. package/payload/platform/plugins/contacts/mcp/dist/index.js +1 -1
  30. package/payload/platform/plugins/contacts/mcp/dist/index.js.map +1 -1
  31. package/payload/platform/plugins/contacts/mcp/dist/tools/__tests__/contact-lookup.test.d.ts +2 -0
  32. package/payload/platform/plugins/contacts/mcp/dist/tools/__tests__/contact-lookup.test.d.ts.map +1 -0
  33. package/payload/platform/plugins/contacts/mcp/dist/tools/__tests__/contact-lookup.test.js +71 -0
  34. package/payload/platform/plugins/contacts/mcp/dist/tools/__tests__/contact-lookup.test.js.map +1 -0
  35. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts +1 -0
  36. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.d.ts.map +1 -1
  37. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js +10 -3
  38. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-lookup.js.map +1 -1
  39. package/payload/platform/plugins/contacts/mcp/package.json +4 -2
  40. package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
  41. package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
  42. package/payload/platform/plugins/memory/PLUGIN.md +1 -1
  43. package/payload/platform/plugins/memory/mcp/dist/index.js +3 -1
  44. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  45. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-lookup-by-name.test.js +39 -0
  46. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-lookup-by-name.test.js.map +1 -1
  47. package/payload/platform/plugins/memory/mcp/dist/tools/memory-lookup-by-name.d.ts.map +1 -1
  48. package/payload/platform/plugins/memory/mcp/dist/tools/memory-lookup-by-name.js +13 -1
  49. package/payload/platform/plugins/memory/mcp/dist/tools/memory-lookup-by-name.js.map +1 -1
  50. package/payload/platform/plugins/slides/skills/deck-system/SKILL.md +1 -1
  51. package/payload/platform/scripts/__tests__/provision-role-stamp.test.sh +40 -0
  52. package/payload/platform/scripts/__tests__/sweep-durability.test.sh +103 -0
  53. package/payload/platform/scripts/lib/provision-account-dir.sh +319 -0
  54. package/payload/platform/scripts/lib/resolve-account-dir.sh +79 -132
  55. package/payload/platform/scripts/setup-account.sh +28 -361
  56. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  57. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +4 -0
  58. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  59. package/payload/platform/services/claude-session-manager/dist/config.d.ts +18 -0
  60. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  61. package/payload/platform/services/claude-session-manager/dist/config.js +63 -7
  62. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  63. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  64. package/payload/platform/services/claude-session-manager/dist/http-server.js +44 -2
  65. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  66. package/payload/platform/services/claude-session-manager/dist/index.js +50 -2
  67. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  68. package/payload/platform/services/claude-session-manager/dist/rc-child-log.d.ts +13 -0
  69. package/payload/platform/services/claude-session-manager/dist/rc-child-log.d.ts.map +1 -0
  70. package/payload/platform/services/claude-session-manager/dist/rc-child-log.js +52 -0
  71. package/payload/platform/services/claude-session-manager/dist/rc-child-log.js.map +1 -0
  72. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  73. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +7 -0
  74. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  75. package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts +5 -0
  76. package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts.map +1 -1
  77. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js +8 -0
  78. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js.map +1 -1
  79. package/payload/platform/services/claude-session-manager/dist/stuck-turn.d.ts +70 -0
  80. package/payload/platform/services/claude-session-manager/dist/stuck-turn.d.ts.map +1 -0
  81. package/payload/platform/services/claude-session-manager/dist/stuck-turn.js +213 -0
  82. package/payload/platform/services/claude-session-manager/dist/stuck-turn.js.map +1 -0
  83. package/payload/platform/services/webchat-channel/dist/instructions.d.ts.map +1 -1
  84. package/payload/platform/services/webchat-channel/dist/instructions.js +25 -1
  85. package/payload/platform/services/webchat-channel/dist/instructions.js.map +1 -1
  86. package/payload/platform/services/webchat-channel/dist/notification.d.ts +17 -0
  87. package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -1
  88. package/payload/platform/services/webchat-channel/dist/notification.js +14 -0
  89. package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -1
  90. package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -1
  91. package/payload/platform/services/webchat-channel/dist/server.js +66 -2
  92. package/payload/platform/services/webchat-channel/dist/server.js.map +1 -1
  93. package/payload/platform/services/webchat-channel/dist/turn-follow.d.ts +28 -0
  94. package/payload/platform/services/webchat-channel/dist/turn-follow.d.ts.map +1 -0
  95. package/payload/platform/services/webchat-channel/dist/turn-follow.js +188 -0
  96. package/payload/platform/services/webchat-channel/dist/turn-follow.js.map +1 -0
  97. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  98. package/payload/platform/services/whatsapp-channel/dist/notification.js +24 -1
  99. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  100. package/payload/platform/templates/account.json +2 -0
  101. package/payload/premium-plugins/management-consulting/skills/pitch-deck/SKILL.md +44 -37
  102. package/payload/server/public/assets/AdminLoginScreens-DexSvtjD.js +1 -0
  103. package/payload/server/public/assets/AdminShell-Bf9tndNg.js +1 -0
  104. package/payload/server/public/assets/{Checkbox-DWGpkJD5.js → Checkbox-D58GsKoQ.js} +1 -1
  105. package/payload/server/public/assets/{OperatorConversations-BWu6GMQM.css → OperatorConversations-CDdp2nVn.css} +1 -1
  106. package/payload/server/public/assets/OperatorConversations-RmqANYz8.js +9 -0
  107. package/payload/server/public/assets/{admin-CnIlm4Yi.js → admin-CH5Vkkt4.js} +1 -1
  108. package/payload/server/public/assets/{browser-ePr5LxPd.js → browser-BwDtzSlr.js} +1 -1
  109. package/payload/server/public/assets/chat-3GY0LmYH.js +1 -0
  110. package/payload/server/public/assets/data-CttrzhfL.js +1 -0
  111. package/payload/server/public/assets/{graph-B5uxt5YB.js → graph-CZSdF2jv.js} +3 -3
  112. package/payload/server/public/assets/{graph-labels-fx-bv3Y-.js → graph-labels-Bi0fu8Ns.js} +1 -1
  113. package/payload/server/public/assets/operator-BEivxmRy.js +1 -0
  114. package/payload/server/public/assets/page-DUvT07SB.js +30 -0
  115. package/payload/server/public/assets/{public-DXAdRKJe.js → public-B3eIlVbd.js} +1 -1
  116. package/payload/server/public/browser.html +4 -4
  117. package/payload/server/public/chat.html +5 -5
  118. package/payload/server/public/data.html +4 -4
  119. package/payload/server/public/graph.html +6 -6
  120. package/payload/server/public/index.html +6 -6
  121. package/payload/server/public/operator.html +7 -7
  122. package/payload/server/public/public.html +5 -5
  123. package/payload/server/server.js +314 -222
  124. package/payload/server/public/assets/AdminLoginScreens-DstNf4M-.js +0 -1
  125. package/payload/server/public/assets/AdminShell-B5EcXCYR.js +0 -1
  126. package/payload/server/public/assets/OperatorConversations-CSQnX7Dx.js +0 -9
  127. package/payload/server/public/assets/chat-XjXSornk.js +0 -1
  128. package/payload/server/public/assets/data-DuObS80U.js +0 -1
  129. package/payload/server/public/assets/operator-CIGXegWd.js +0 -1
  130. package/payload/server/public/assets/page-BVOAwj-e.js +0 -30
@@ -0,0 +1,57 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, mkdirSync, writeFileSync, existsSync, rmSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { listAccountsFromDir, isHouseAccount, archiveAccountDir } from "../account-lifecycle.js";
7
+ const HOUSE = "11111111-1111-1111-1111-111111111111";
8
+ const CLIENT = "22222222-2222-2222-2222-222222222222";
9
+ function seed(root, id, role) {
10
+ mkdirSync(join(root, id), { recursive: true });
11
+ writeFileSync(join(root, id, "account.json"), JSON.stringify({ accountId: id, role }));
12
+ }
13
+ const mk = () => mkdtempSync(join(tmpdir(), "acct-lifecycle-"));
14
+ test("listAccountsFromDir returns registered accounts with roles", () => {
15
+ const root = mk();
16
+ try {
17
+ seed(root, HOUSE, "house");
18
+ seed(root, CLIENT, "client");
19
+ mkdirSync(join(root, "not-a-uuid")); // ignored
20
+ const list = listAccountsFromDir(root).sort((a, b) => a.accountId.localeCompare(b.accountId));
21
+ assert.equal(list.length, 2);
22
+ assert.deepEqual(list.find((a) => a.accountId === HOUSE), { accountId: HOUSE, role: "house", isHouse: true });
23
+ assert.deepEqual(list.find((a) => a.accountId === CLIENT), { accountId: CLIENT, role: "client", isHouse: false });
24
+ }
25
+ finally {
26
+ rmSync(root, { recursive: true });
27
+ }
28
+ });
29
+ test("isHouseAccount distinguishes house from client", () => {
30
+ const root = mk();
31
+ try {
32
+ seed(root, HOUSE, "house");
33
+ seed(root, CLIENT, "client");
34
+ assert.equal(isHouseAccount(root, HOUSE), true);
35
+ assert.equal(isHouseAccount(root, CLIENT), false);
36
+ }
37
+ finally {
38
+ rmSync(root, { recursive: true });
39
+ }
40
+ });
41
+ test("archiveAccountDir moves the dir to .trash and reports it absent", () => {
42
+ const root = mk();
43
+ try {
44
+ seed(root, CLIENT, "client");
45
+ const { trashPath, dirAbsent } = archiveAccountDir(root, CLIENT, "20260618T000000Z");
46
+ assert.equal(dirAbsent, true);
47
+ assert.equal(existsSync(join(root, CLIENT)), false);
48
+ assert.equal(existsSync(trashPath), true);
49
+ assert.equal(existsSync(join(trashPath, "account.json")), true);
50
+ // archived account is no longer in the registry
51
+ assert.equal(listAccountsFromDir(root).length, 0);
52
+ }
53
+ finally {
54
+ rmSync(root, { recursive: true });
55
+ }
56
+ });
57
+ //# sourceMappingURL=account-lifecycle.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-lifecycle.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/account-lifecycle.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export interface AccountSummary {
2
+ accountId: string;
3
+ role: string;
4
+ isHouse: boolean;
5
+ }
6
+ /** Enumerate the registry: every UUID dir with a parseable account.json, with
7
+ * its role. An unparseable account.json is excluded (corruption discipline,
8
+ * mirrors account-enumeration). */
9
+ export declare function listAccountsFromDir(accountsDir: string): AccountSummary[];
10
+ /** True iff `id` is the house account. Used to refuse delete/purge of the house. */
11
+ export declare function isHouseAccount(accountsDir: string, id: string): boolean;
12
+ /** Move a live account dir into `data/accounts/.trash/<id>-<ts>/`. Graph rows are
13
+ * retained (purge is a separate, typed-confirmation step). Returns the trash
14
+ * path and whether the live dir is now absent (the verified post-condition). */
15
+ export declare function archiveAccountDir(accountsDir: string, id: string, ts: string): {
16
+ trashPath: string;
17
+ dirAbsent: boolean;
18
+ };
19
+ /** Scaffold a new client account dir by invoking the shared
20
+ * `provision_account_dir` shell function (the same path setup-account.sh uses
21
+ * for the house). Synchronous — throws on non-zero exit, which the caller turns
22
+ * into a tool error. */
23
+ export declare function provisionClientAccount(opts: {
24
+ platformRoot: string;
25
+ accountsDir: string;
26
+ accountId: string;
27
+ usersFile: string;
28
+ }): string;
29
+ /** Cypher for the account-scoped node count and the irreversible purge. The
30
+ * purge deletes every node carrying the accountId (account scope is a property,
31
+ * never an edge — see CLAUDE.md), detaching its relationships. */
32
+ export declare const ACCOUNT_NODE_COUNT_CYPHER = "MATCH (n) WHERE n.accountId = $id RETURN count(n) AS c";
33
+ export declare const ACCOUNT_PURGE_CYPHER = "MATCH (n) WHERE n.accountId = $id DETACH DELETE n";
34
+ //# sourceMappingURL=account-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-lifecycle.d.ts","sourceRoot":"","sources":["../../src/tools/account-lifecycle.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;oCAEoC;AACpC,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,EAAE,CAoBzE;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED;;iFAEiF;AACjF,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAO3C;AAED;;;yBAGyB;AACzB,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAoBT;AAED;;mEAEmE;AACnE,eAAO,MAAM,yBAAyB,2DAA2D,CAAC;AAClG,eAAO,MAAM,oBAAoB,sDAAsD,CAAC"}
@@ -0,0 +1,78 @@
1
+ // Account lifecycle helpers (Task 983) — pure / side-effecting building blocks
2
+ // for the admin-core account_create / account_list / account_delete /
3
+ // account_purge tools. Kept out of index.ts (which connects its stdio transport
4
+ // at import time and so cannot be imported by a unit test) so the enumeration,
5
+ // house-guard, archive, and provision logic are testable in isolation.
6
+ import { execFileSync } from "node:child_process";
7
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync } from "node:fs";
8
+ import { join, resolve } from "node:path";
9
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
10
+ /** Enumerate the registry: every UUID dir with a parseable account.json, with
11
+ * its role. An unparseable account.json is excluded (corruption discipline,
12
+ * mirrors account-enumeration). */
13
+ export function listAccountsFromDir(accountsDir) {
14
+ let names;
15
+ try {
16
+ names = readdirSync(accountsDir);
17
+ }
18
+ catch {
19
+ return [];
20
+ }
21
+ const out = [];
22
+ for (const name of names) {
23
+ if (!UUID_RE.test(name))
24
+ continue;
25
+ const configPath = resolve(accountsDir, name, "account.json");
26
+ try {
27
+ const cfg = JSON.parse(readFileSync(configPath, "utf-8"));
28
+ const role = typeof cfg.role === "string" ? cfg.role : "";
29
+ out.push({ accountId: name, role, isHouse: role === "house" });
30
+ }
31
+ catch {
32
+ // missing/unparseable account.json — not a registered account
33
+ }
34
+ }
35
+ return out;
36
+ }
37
+ /** True iff `id` is the house account. Used to refuse delete/purge of the house. */
38
+ export function isHouseAccount(accountsDir, id) {
39
+ return listAccountsFromDir(accountsDir).some((a) => a.accountId === id && a.isHouse);
40
+ }
41
+ /** Move a live account dir into `data/accounts/.trash/<id>-<ts>/`. Graph rows are
42
+ * retained (purge is a separate, typed-confirmation step). Returns the trash
43
+ * path and whether the live dir is now absent (the verified post-condition). */
44
+ export function archiveAccountDir(accountsDir, id, ts) {
45
+ const liveDir = join(accountsDir, id);
46
+ const trashRoot = join(accountsDir, ".trash");
47
+ mkdirSync(trashRoot, { recursive: true });
48
+ const trashPath = join(trashRoot, `${id}-${ts}`);
49
+ renameSync(liveDir, trashPath);
50
+ return { trashPath, dirAbsent: !existsSync(liveDir) };
51
+ }
52
+ /** Scaffold a new client account dir by invoking the shared
53
+ * `provision_account_dir` shell function (the same path setup-account.sh uses
54
+ * for the house). Synchronous — throws on non-zero exit, which the caller turns
55
+ * into a tool error. */
56
+ export function provisionClientAccount(opts) {
57
+ const accountDir = join(opts.accountsDir, opts.accountId);
58
+ execFileSync("bash", ["-c", '. "$SCRIPT_DIR/lib/provision-account-dir.sh"; provision_account_dir "$ACCT_DIR" "$ACCT_ID" client'], {
59
+ env: {
60
+ ...process.env,
61
+ TEMPLATES_DIR: join(opts.platformRoot, "templates"),
62
+ PROJECT_DIR: opts.platformRoot,
63
+ SCRIPT_DIR: join(opts.platformRoot, "scripts"),
64
+ USERS_FILE: opts.usersFile,
65
+ ACCT_DIR: accountDir,
66
+ ACCT_ID: opts.accountId,
67
+ },
68
+ encoding: "utf-8",
69
+ stdio: ["ignore", "pipe", "pipe"],
70
+ });
71
+ return accountDir;
72
+ }
73
+ /** Cypher for the account-scoped node count and the irreversible purge. The
74
+ * purge deletes every node carrying the accountId (account scope is a property,
75
+ * never an edge — see CLAUDE.md), detaching its relationships. */
76
+ export const ACCOUNT_NODE_COUNT_CYPHER = "MATCH (n) WHERE n.accountId = $id RETURN count(n) AS c";
77
+ export const ACCOUNT_PURGE_CYPHER = "MATCH (n) WHERE n.accountId = $id DETACH DELETE n";
78
+ //# sourceMappingURL=account-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-lifecycle.js","sourceRoot":"","sources":["../../src/tools/account-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -96,6 +96,13 @@ Length is dictated by the concept's richness AND by what the user has already su
96
96
  - **No follow-up offers.** End on the definition.
97
97
  - **Strip AI tells.** See the AI-tells catalogue below. Plain English is the *spoken* register, which rules out patterns that AI writing reaches for but humans rarely use in conversation.
98
98
 
99
+ ## Second pass
100
+
101
+ Run this after the precision pass, reading the candidate as a reader rather than as the writer. Two questions, and both must pass before the output ships.
102
+
103
+ - **Would a person say this out loud?** Read it aloud. A sentence that only works on the page (a formula spoken letter by letter, a clause you have to re-read to parse) fails; rewrite it in the spoken register.
104
+ - **Would a stranger flag this as AI?** If a reader who never saw the draft would point at a sentence and call it machine-written, that sentence carries a tell the precision pass missed. Strip it.
105
+
99
106
  ## AI tells to strip
100
107
 
101
108
  These are patterns common in AI-generated prose but rare in actual human writing, especially in spoken or conversational registers. Strip every one on the precision pass. The list grows as more patterns are surfaced.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: platform-architecture
3
3
  description: Use when grounding any documented-surface claim about what Maxy ships — plugins, skills, specialists, install/deploy flows, internals. This is the install catalogue, not evidence of what is enabled on the current account. For install state on this account, call `capabilities-here`; for documented surface, cite the `Source:` URL inline.
4
- content-hash: sha256:b3f1611fcb4116496aadfdfa39e64fce9061f0611c6d926545f6c6523688fc73
4
+ content-hash: sha256:7ce8254f9b8096d919d2be7aa4f6c5a30f5e6dbe1f61007ee00f05af81020445
5
5
  brand: maxy-code
6
6
  product-name: Maxy
7
7
  ---
@@ -2601,7 +2601,7 @@ authoritative. This section names the surfaces and what backs each.
2601
2601
  |---|---|---|
2602
2602
  | `+ New session` button | Opens `NewSessionModal`, which POSTs `{channel, permissionMode, model, initialMessage}` to `/api/admin/claude-sessions`. | `claude-sessions.ts` |
2603
2603
  | Mode trigger | Per-`(accountId, userId)` `SpawnPreference` for `permissionMode` and `model`; persists across reload, tab, device. | `session-defaults.ts` |
2604
- | Nav rows (Chat / People / Agents / Projects / Tasks / Artefacts) | People, Agents, Tasks open the artefact-pane Graph filtered to the matching label. Chat selects the active conversation. Artefacts swaps the list to editable documents. | `graph-search.ts`, `graph-subgraph.ts`, `sidebar-artefacts.ts` |
2604
+ | Nav rows (Chat / People / Agents / Projects / Tasks / Artefacts) | People, Agents, Tasks open the artefact-pane Graph filtered to the matching label. Chat selects the active conversation. Artefacts swaps the list to editable documents. **The "Projects" row is brand-aware:** its visible term and the graph label it filters to both come from the injected `window.__BRAND__.primaryContainer` (`brand.json` → `server/index.ts` inject → `brand.ts` `brandPrimaryContainer()`), so Maxy reads "Projects" → `:Project`, SiteOffice "Jobs" → `:Job`, Real Agent "Properties" → `:Property`. A brand JSON missing `primaryContainer` falls back to Project/Projects (server logs `[brand] op=primaryContainer-default reason=absent brand=<hostname>`; the populated case logs `[brand] op=inject primaryContainer=<label>/<term>`). | `graph-search.ts`, `graph-subgraph.ts`, `sidebar-artefacts.ts` |
2605
2605
  | Sessions list (Active / Archived / All) | Live row store driven by SSE; manual reconcile button on the segmented control re-fetches the full id set. Every listed row carries two launch actions: the claude.ai/code resume (`ExternalLink`) and a chat-launch (`MessageSquare`) that opens `/chat?session=<full sessionId>` — the admin webchat pointed at that exact session; sending there resumes a stopped session with the webchat channel bound to that id (see `admin-webchat-native-channel.md`, "Session-targeted mode"). At the ≤720 px drawer breakpoint each row stacks into two lines — dot + title + id/stamp, then the action icons — with a divider between rows and actions at full opacity (the desktop hover-gated 0.5 opacity never resolves on touch). Below a 400 px list width each row's action icons collapse to a single `MoreHorizontal` ellipsis trigger; its popover menu lists the same actions as the inline icons but labels them with concise verbs (`Resume in claude.ai/code`, `Open in webchat`, `Stop`, `Archive` / `Unarchive`, `Rename`, `Delete`, `Re-seat`) rather than the inline icon buttons' verbose per-session aria-labels — the inline buttons keep those verbose labels because an icon-only control needs the full descriptive accessible name. **Re-seat:** Re-seat is a member action of the one `SessionRowActions` cluster, not a separate sibling control — wide it is the sliders icon inline with the other icons (sharing the cluster geometry and alignment); collapsed it is the `Re-seat` menu item, which expands the model/mode/effort form inline inside the overflow menu. The form (`SessionReseatControl`) forks the session via `/api/admin/session-reseat` and navigates to the fork (the same fork mechanism `/chat`'s pickers drive); its model picker defaults to the row's current model (a `model` field on each row, read from the JSONL tail), and mode and effort each carry a "Keep" option that omits the field. The overflow menu and the Re-seat form render through a `document.body` portal, fixed-positioned from the trigger's rect (right-aligned, flipped above the trigger when there is no room below), so neither is clipped by `.side-list`'s `overflow-y:auto`; Escape, a pointerdown outside the trigger/popover, and any scroll or resize dismiss them. | `/claude-sessions/events`, `/claude-sessions`, `/session-reseat` |
2606
2606
  | Channel reader nav rows (WhatsApp / Telegram) | One conditional nav row **per interactive channel that has ≥1 admin session**. Each row carries its brand glyph (WhatsApp `#25D366`, Telegram `#229ED9`); a channel with no admin session shows no row, and no install ever shows an always-empty "No conversations" row. The channel list loads **once on sidebar mount** (the per-channel counts must be known before the nav renders), so a failed load shows one muted, non-clickable line instead of channel rows. Clicking a channel row lists that channel's admin conversations; each conversation row shows a **display name** resolved by precedence `operatorName ?? whatsappName ?? senderId ?? title`: the bound `Person givenName familyName` when a `senderId`→`userId` binding exists, else the persisted WhatsApp display name (`pushName`, read from the latest `:Message:WhatsAppMessage.senderName`), else the raw `senderId`, else the agent title; the agent session title is the hover tooltip only. Under the name each row shows a **last-message-time breadcrumb** (`conv-timestamp`, same markup as the Sessions rows) formatted from the row's `lastMessageAt` (the last parseable turn's `ts`); a session with no parseable turn shows no time, never "Invalid Date". **Re-seat:** each channel conversation row carries a `SessionRowActions` cluster whose sole action is Re-seat (the row is a `conv-with-actions` shell whose open click moved onto an inner button so the cluster can sit beside it), so a WhatsApp/Telegram session's model/mode/effort is re-seatable from the dashboard exactly like a webchat row — wide it is the inline sliders icon, and below the 400 px width it folds into the `…` overflow menu identically to the Sessions rows; the channel reader row carries the same `model` field for the picker default. A click on a conversation **opens its transcript on the home surface**: on `/` it selects in place, and from any other route (`/graph`, `/data`, `/browser`) it navigates to `/?wa=<sessionId>&projectDir=<dir>`, which the root shell hydrates on mount (then strips the query so a later refresh does not re-pin a closed conversation). Server logs `[wa-reader] op=operator-name-fallback senderId=… source=whatsapp-pushname` when the pushName fallback fires and `[wa-reader] op=conversations count=<n> withTimestamp=<m>` per list build; the client logs `[admin-ui] wa-open route=… via=<in-place\|navigate> …` and `[admin-ui] wa-hydrate route=/ …`. | `/whatsapp-reader/conversations` |
2607
2607
  | Channel transcript (`<Transcript>`) | Reads one session's JSONL over SSE (`/whatsapp-reader/stream`) and renders both sides plus tool calls — the turns claude.ai/code hides because channel inbound is stamped `isMeta`. Every turn shows its time-of-day (HH:MM from the turn's `ts`; a null/unparseable `ts` shows no time, never "Invalid Date"). `tool-call`/`tool-result` turns render as **collapsed cards** (chevron + label + time, default collapsed, expandable per card; one card's state never affects another) so the human↔agent text is not buried in JSON; the three conversation kinds always render in full. The thread **follows the tail**: it opens at the newest turn and pins to the bottom on each live append **only while the operator is already within 32 px of the bottom** — a scroll up suppresses the jump so reading history is never yanked. While the operator is scrolled up a **jump-to-bottom control** (`.wa-jump`, bottom-right of the viewport) appears; clicking it scrolls to the newest turn and re-arms follow-tail, and it hides again at the bottom. The thread scrolls inside its grid cell (header/sidebar/footer fixed). The stream sends a 20 s heartbeat so an idle Cloudflare tunnel does not idle-drop, tags each frame with a byte-offset `id:`, and resumes from the client's `Last-Event-ID` on reconnect (no duplicate backlog); the client clears the "Stream disconnected" banner on reopen and latches it only on a terminal CLOSED state. The thread also interleaves a collapsed `⚙ directive injected (N B)` row per turn, sorted by timestamp just before the turn it informed; expanding one fetches the exact stored `prompt-optimiser-directive` bytes for that turn. The entries are listed by `GET /whatsapp-reader/directives?sessionId=` and the bytes served by `GET /whatsapp-reader/directive?sessionId=&name=`, both admin-gated and account-scoped; a missing store degrades to no rows. A centered day-divider row (`.day-divider`) marks each local calendar-day crossover between consecutive turns so a thread spanning midnight is unambiguous. | `/whatsapp-reader/stream`, `/whatsapp-reader/directives`, `/whatsapp-reader/directive` |
@@ -108,7 +108,7 @@ eagerTool(server, "contact-create", "Create a new contact (schema:Person) in the
108
108
  eagerTool(server, "contact-lookup", "Search for contacts by email, telephone, name, or list recent contacts. Returns schema:Person nodes.", {
109
109
  email: z.string().optional().describe("Exact email match"),
110
110
  telephone: z.string().optional().describe("Exact phone number match"),
111
- name: z.string().optional().describe("Partial name search (first or last name)"),
111
+ name: z.string().optional().describe("Partial or full name search, matched against the composed givenName + familyName display name"),
112
112
  limit: z.number().int().optional().describe("Max results (default 10)"),
113
113
  }, async ({ email, telephone, name, limit }) => {
114
114
  if (!accountId)
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=contact-lookup.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-lookup.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/contact-lookup.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ // Task 985 — contact-lookup by name must recompose the split givenName +
2
+ // familyName pair. A Person stored givenName:"Jane" familyName:"Smith" was
3
+ // invisible to a search for "Jane Smith" because the old predicate tested the
4
+ // whole query against each field with CONTAINS ("jane smith" is a substring of
5
+ // neither "jane" nor "smith"). These tests lock the composed-substring predicate
6
+ // and the query-whitespace normalization. The live Neo4j CONTAINS filtering is
7
+ // exercised on the Pi; the predicate correctness is locked here.
8
+ import { describe, it, expect, beforeEach, vi } from "vitest";
9
+ const mockSession = {
10
+ run: vi.fn(),
11
+ close: vi.fn().mockResolvedValue(undefined),
12
+ };
13
+ vi.mock("../../lib/neo4j.js", () => ({
14
+ getSession: () => mockSession,
15
+ }));
16
+ vi.mock("../../../../../../lib/graph-trash/dist/index.js", () => ({
17
+ notTrashed: (alias) => `(NOT ${alias}:Trashed)`,
18
+ }));
19
+ vi.mock("neo4j-driver", () => ({
20
+ default: { int: (v) => v },
21
+ }));
22
+ import { contactLookup, normalizeNameQuery } from "../contact-lookup.js";
23
+ const ACCOUNT_ID = "20028fb5-db26-4de7-bff6-c5ec2d4fc766";
24
+ function personRecord(props, nodeId = "4:person:9") {
25
+ return {
26
+ get: (k) => (k === "nodeId" ? nodeId : { properties: props }),
27
+ };
28
+ }
29
+ beforeEach(() => {
30
+ mockSession.run.mockReset();
31
+ mockSession.close.mockClear();
32
+ });
33
+ describe("normalizeNameQuery", () => {
34
+ it("trims and collapses internal whitespace to single spaces", () => {
35
+ expect(normalizeNameQuery(" Jane Smith ")).toBe("Jane Smith");
36
+ });
37
+ it("leaves a single token unchanged", () => {
38
+ expect(normalizeNameQuery("Jane")).toBe("Jane");
39
+ });
40
+ it("collapses a tab/newline run between tokens", () => {
41
+ expect(normalizeNameQuery("Jane\t\nSmith")).toBe("Jane Smith");
42
+ });
43
+ });
44
+ describe("contact-lookup — composed full-name match (Task 985)", () => {
45
+ it("matches the composed givenName+familyName for a full-name query", async () => {
46
+ mockSession.run.mockResolvedValueOnce({
47
+ records: [personRecord({ givenName: "Jane", familyName: "Smith", source: "manual", status: "active", createdOn: "2026-01-01" })],
48
+ });
49
+ const hits = await contactLookup({ name: "Jane Smith", accountId: ACCOUNT_ID });
50
+ const [cypher, params] = mockSession.run.mock.calls[0];
51
+ expect(cypher).toContain("toLower(trim(coalesce(p.givenName, '') + ' ' + coalesce(p.familyName, ''))) CONTAINS toLower($name)");
52
+ expect(params.name).toBe("Jane Smith");
53
+ expect(hits).toHaveLength(1);
54
+ expect(hits[0].givenName).toBe("Jane");
55
+ expect(hits[0].familyName).toBe("Smith");
56
+ });
57
+ it("uses the same composed predicate for a single-token query (no per-field branch)", async () => {
58
+ mockSession.run.mockResolvedValueOnce({ records: [] });
59
+ await contactLookup({ name: "Jane", accountId: ACCOUNT_ID });
60
+ const [cypher, params] = mockSession.run.mock.calls[0];
61
+ expect(cypher).toContain("toLower(trim(coalesce(p.givenName, '') + ' ' + coalesce(p.familyName, ''))) CONTAINS toLower($name)");
62
+ expect(params.name).toBe("Jane");
63
+ });
64
+ it("normalizes whitespace in the threaded $name param", async () => {
65
+ mockSession.run.mockResolvedValueOnce({ records: [] });
66
+ await contactLookup({ name: " Jane Smith ", accountId: ACCOUNT_ID });
67
+ const [, params] = mockSession.run.mock.calls[0];
68
+ expect(params.name).toBe("Jane Smith");
69
+ });
70
+ });
71
+ //# sourceMappingURL=contact-lookup.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-lookup.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/contact-lookup.test.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ interface ContactLookupParams {
5
5
  accountId?: string;
6
6
  limit?: number;
7
7
  }
8
+ export declare function normalizeNameQuery(name: string): string;
8
9
  interface ContactRecord {
9
10
  nodeId: string;
10
11
  givenName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"contact-lookup.d.ts","sourceRoot":"","sources":["../../src/tools/contact-lookup.ts"],"names":[],"mappings":"AAIA,UAAU,mBAAmB;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,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,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,aAAa,EAAE,CAAC,CAkE1B"}
1
+ {"version":3,"file":"contact-lookup.d.ts","sourceRoot":"","sources":["../../src/tools/contact-lookup.ts"],"names":[],"mappings":"AAIA,UAAU,mBAAmB;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,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,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,aAAa,EAAE,CAAC,CAiE1B"}
@@ -1,6 +1,14 @@
1
1
  import neo4j from "neo4j-driver";
2
2
  import { getSession } from "../lib/neo4j.js";
3
3
  import { notTrashed } from "../../../../../lib/graph-trash/dist/index.js";
4
+ // A by-name query is matched against the read-time-composed display name
5
+ // (givenName + ' ' + familyName), so the full name the UI rendered resolves the
6
+ // person even though the schema forbids a canonical Person.name. Trim and
7
+ // collapse internal whitespace so " Jane Smith " matches the single-spaced
8
+ // composition; a single token is left unchanged and still matches either field.
9
+ export function normalizeNameQuery(name) {
10
+ return name.trim().replace(/\s+/g, " ");
11
+ }
4
12
  export async function contactLookup(params) {
5
13
  const { email, telephone, name, accountId, limit = 10 } = params;
6
14
  const session = getSession();
@@ -29,13 +37,12 @@ export async function contactLookup(params) {
29
37
  else if (name) {
30
38
  query = `
31
39
  MATCH (p:Person {accountId: $accountId})
32
- WHERE (toLower(p.givenName) CONTAINS toLower($name)
33
- OR toLower(p.familyName) CONTAINS toLower($name))
40
+ WHERE toLower(trim(coalesce(p.givenName, '') + ' ' + coalesce(p.familyName, ''))) CONTAINS toLower($name)
34
41
  AND ${trashFilter}
35
42
  RETURN p, elementId(p) AS nodeId
36
43
  LIMIT $limit
37
44
  `;
38
- queryParams = { name, accountId, limit: neo4j.int(limit) };
45
+ queryParams = { name: normalizeNameQuery(name), accountId, limit: neo4j.int(limit) };
39
46
  }
40
47
  else {
41
48
  query = `
@@ -1 +1 @@
1
- {"version":3,"file":"contact-lookup.js","sourceRoot":"","sources":["../../src/tools/contact-lookup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAsB1E,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B;IAE3B,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC;IAEjE,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,IAAI,KAAa,CAAC;QAClB,IAAI,WAAoC,CAAC;QAEzC,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,GAAG;;qCAEuB,WAAW;;;OAGzC,CAAC;YACF,WAAW,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACnF,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,KAAK,GAAG;;6CAE+B,WAAW;;;OAGjD,CAAC;YACF,WAAW,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACpF,CAAC;aAAM,IAAI,IAAI,EAAE,CAAC;YAChB,KAAK,GAAG;;;;iBAIG,WAAW;;;OAGrB,CAAC;YACF,WAAW,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,KAAK,GAAG;;gBAEE,WAAW;;;;OAIpB,CAAC;YACF,WAAW,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAErD,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACnC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;YACrC,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAW;gBACtC,SAAS,EAAE,CAAC,CAAC,SAAmB;gBAChC,UAAU,EAAE,CAAC,CAAC,UAAgC;gBAC9C,KAAK,EAAE,CAAC,CAAC,KAA2B;gBACpC,SAAS,EAAE,CAAC,CAAC,SAA+B;gBAC5C,QAAQ,EAAE,CAAC,CAAC,QAA8B;gBAC1C,MAAM,EAAE,CAAC,CAAC,MAAgB;gBAC1B,MAAM,EAAE,CAAC,CAAC,MAAgB;gBAC1B,SAAS,EAAE,CAAC,CAAC,SAAmB;aACjC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"contact-lookup.js","sourceRoot":"","sources":["../../src/tools/contact-lookup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAU1E,yEAAyE;AACzE,gFAAgF;AAChF,0EAA0E;AAC1E,8EAA8E;AAC9E,gFAAgF;AAChF,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC;AAcD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA2B;IAE3B,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC;IAEjE,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,IAAI,KAAa,CAAC;QAClB,IAAI,WAAoC,CAAC;QAEzC,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,GAAG;;qCAEuB,WAAW;;;OAGzC,CAAC;YACF,WAAW,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACnF,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,KAAK,GAAG;;6CAE+B,WAAW;;;OAGjD,CAAC;YACF,WAAW,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACpF,CAAC;aAAM,IAAI,IAAI,EAAE,CAAC;YAChB,KAAK,GAAG;;;iBAGG,WAAW;;;OAGrB,CAAC;YACF,WAAW,GAAG,EAAE,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvF,CAAC;aAAM,CAAC;YACN,KAAK,GAAG;;gBAEE,WAAW;;;;OAIpB,CAAC;YACF,WAAW,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAErD,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACnC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;YACrC,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAW;gBACtC,SAAS,EAAE,CAAC,CAAC,SAAmB;gBAChC,UAAU,EAAE,CAAC,CAAC,UAAgC;gBAC9C,KAAK,EAAE,CAAC,CAAC,KAA2B;gBACpC,SAAS,EAAE,CAAC,CAAC,SAA+B;gBAC5C,QAAQ,EAAE,CAAC,CAAC,QAA8B;gBAC1C,MAAM,EAAE,CAAC,CAAC,MAAgB;gBAC1B,MAAM,EAAE,CAAC,CAAC,MAAgB;gBAC1B,SAAS,EAAE,CAAC,CAAC,SAAmB;aACjC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -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",
@@ -14,6 +15,7 @@
14
15
  },
15
16
  "devDependencies": {
16
17
  "typescript": "^5.7.0",
17
- "@types/node": "^22.0.0"
18
+ "@types/node": "^22.0.0",
19
+ "vitest": "^4.1.2"
18
20
  }
19
21
  }
@@ -336,7 +336,7 @@ authoritative. This section names the surfaces and what backs each.
336
336
  |---|---|---|
337
337
  | `+ New session` button | Opens `NewSessionModal`, which POSTs `{channel, permissionMode, model, initialMessage}` to `/api/admin/claude-sessions`. | `claude-sessions.ts` |
338
338
  | Mode trigger | Per-`(accountId, userId)` `SpawnPreference` for `permissionMode` and `model`; persists across reload, tab, device. | `session-defaults.ts` |
339
- | Nav rows (Chat / People / Agents / Projects / Tasks / Artefacts) | People, Agents, Tasks open the artefact-pane Graph filtered to the matching label. Chat selects the active conversation. Artefacts swaps the list to editable documents. | `graph-search.ts`, `graph-subgraph.ts`, `sidebar-artefacts.ts` |
339
+ | Nav rows (Chat / People / Agents / Projects / Tasks / Artefacts) | People, Agents, Tasks open the artefact-pane Graph filtered to the matching label. Chat selects the active conversation. Artefacts swaps the list to editable documents. **The "Projects" row is brand-aware:** its visible term and the graph label it filters to both come from the injected `window.__BRAND__.primaryContainer` (`brand.json` → `server/index.ts` inject → `brand.ts` `brandPrimaryContainer()`), so Maxy reads "Projects" → `:Project`, SiteOffice "Jobs" → `:Job`, Real Agent "Properties" → `:Property`. A brand JSON missing `primaryContainer` falls back to Project/Projects (server logs `[brand] op=primaryContainer-default reason=absent brand=<hostname>`; the populated case logs `[brand] op=inject primaryContainer=<label>/<term>`). | `graph-search.ts`, `graph-subgraph.ts`, `sidebar-artefacts.ts` |
340
340
  | Sessions list (Active / Archived / All) | Live row store driven by SSE; manual reconcile button on the segmented control re-fetches the full id set. Every listed row carries two launch actions: the claude.ai/code resume (`ExternalLink`) and a chat-launch (`MessageSquare`) that opens `/chat?session=<full sessionId>` — the admin webchat pointed at that exact session; sending there resumes a stopped session with the webchat channel bound to that id (see `admin-webchat-native-channel.md`, "Session-targeted mode"). At the ≤720 px drawer breakpoint each row stacks into two lines — dot + title + id/stamp, then the action icons — with a divider between rows and actions at full opacity (the desktop hover-gated 0.5 opacity never resolves on touch). Below a 400 px list width each row's action icons collapse to a single `MoreHorizontal` ellipsis trigger; its popover menu lists the same actions as the inline icons but labels them with concise verbs (`Resume in claude.ai/code`, `Open in webchat`, `Stop`, `Archive` / `Unarchive`, `Rename`, `Delete`, `Re-seat`) rather than the inline icon buttons' verbose per-session aria-labels — the inline buttons keep those verbose labels because an icon-only control needs the full descriptive accessible name. **Re-seat:** Re-seat is a member action of the one `SessionRowActions` cluster, not a separate sibling control — wide it is the sliders icon inline with the other icons (sharing the cluster geometry and alignment); collapsed it is the `Re-seat` menu item, which expands the model/mode/effort form inline inside the overflow menu. The form (`SessionReseatControl`) forks the session via `/api/admin/session-reseat` and navigates to the fork (the same fork mechanism `/chat`'s pickers drive); its model picker defaults to the row's current model (a `model` field on each row, read from the JSONL tail), and mode and effort each carry a "Keep" option that omits the field. The overflow menu and the Re-seat form render through a `document.body` portal, fixed-positioned from the trigger's rect (right-aligned, flipped above the trigger when there is no room below), so neither is clipped by `.side-list`'s `overflow-y:auto`; Escape, a pointerdown outside the trigger/popover, and any scroll or resize dismiss them. | `/claude-sessions/events`, `/claude-sessions`, `/session-reseat` |
341
341
  | Channel reader nav rows (WhatsApp / Telegram) | One conditional nav row **per interactive channel that has ≥1 admin session**. Each row carries its brand glyph (WhatsApp `#25D366`, Telegram `#229ED9`); a channel with no admin session shows no row, and no install ever shows an always-empty "No conversations" row. The channel list loads **once on sidebar mount** (the per-channel counts must be known before the nav renders), so a failed load shows one muted, non-clickable line instead of channel rows. Clicking a channel row lists that channel's admin conversations; each conversation row shows a **display name** resolved by precedence `operatorName ?? whatsappName ?? senderId ?? title`: the bound `Person givenName familyName` when a `senderId`→`userId` binding exists, else the persisted WhatsApp display name (`pushName`, read from the latest `:Message:WhatsAppMessage.senderName`), else the raw `senderId`, else the agent title; the agent session title is the hover tooltip only. Under the name each row shows a **last-message-time breadcrumb** (`conv-timestamp`, same markup as the Sessions rows) formatted from the row's `lastMessageAt` (the last parseable turn's `ts`); a session with no parseable turn shows no time, never "Invalid Date". **Re-seat:** each channel conversation row carries a `SessionRowActions` cluster whose sole action is Re-seat (the row is a `conv-with-actions` shell whose open click moved onto an inner button so the cluster can sit beside it), so a WhatsApp/Telegram session's model/mode/effort is re-seatable from the dashboard exactly like a webchat row — wide it is the inline sliders icon, and below the 400 px width it folds into the `…` overflow menu identically to the Sessions rows; the channel reader row carries the same `model` field for the picker default. A click on a conversation **opens its transcript on the home surface**: on `/` it selects in place, and from any other route (`/graph`, `/data`, `/browser`) it navigates to `/?wa=<sessionId>&projectDir=<dir>`, which the root shell hydrates on mount (then strips the query so a later refresh does not re-pin a closed conversation). Server logs `[wa-reader] op=operator-name-fallback senderId=… source=whatsapp-pushname` when the pushName fallback fires and `[wa-reader] op=conversations count=<n> withTimestamp=<m>` per list build; the client logs `[admin-ui] wa-open route=… via=<in-place\|navigate> …` and `[admin-ui] wa-hydrate route=/ …`. | `/whatsapp-reader/conversations` |
342
342
  | Channel transcript (`<Transcript>`) | Reads one session's JSONL over SSE (`/whatsapp-reader/stream`) and renders both sides plus tool calls — the turns claude.ai/code hides because channel inbound is stamped `isMeta`. Every turn shows its time-of-day (HH:MM from the turn's `ts`; a null/unparseable `ts` shows no time, never "Invalid Date"). `tool-call`/`tool-result` turns render as **collapsed cards** (chevron + label + time, default collapsed, expandable per card; one card's state never affects another) so the human↔agent text is not buried in JSON; the three conversation kinds always render in full. The thread **follows the tail**: it opens at the newest turn and pins to the bottom on each live append **only while the operator is already within 32 px of the bottom** — a scroll up suppresses the jump so reading history is never yanked. While the operator is scrolled up a **jump-to-bottom control** (`.wa-jump`, bottom-right of the viewport) appears; clicking it scrolls to the newest turn and re-arms follow-tail, and it hides again at the bottom. The thread scrolls inside its grid cell (header/sidebar/footer fixed). The stream sends a 20 s heartbeat so an idle Cloudflare tunnel does not idle-drop, tags each frame with a byte-offset `id:`, and resumes from the client's `Last-Event-ID` on reconnect (no duplicate backlog); the client clears the "Stream disconnected" banner on reopen and latches it only on a terminal CLOSED state. The thread also interleaves a collapsed `⚙ directive injected (N B)` row per turn, sorted by timestamp just before the turn it informed; expanding one fetches the exact stored `prompt-optimiser-directive` bytes for that turn. The entries are listed by `GET /whatsapp-reader/directives?sessionId=` and the bytes served by `GET /whatsapp-reader/directive?sessionId=&name=`, both admin-gated and account-scoped; a missing store degrades to no rows. A centered day-divider row (`.day-divider`) marks each local calendar-day crossover between consecutive turns so a thread spanning midnight is unambiguous. | `/whatsapp-reader/stream`, `/whatsapp-reader/directives`, `/whatsapp-reader/directive` |
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memory",
3
- "description": "Graph memory plugin. Provides memory-search (with optional `fields` projection for known-shape lookups), memory-write, memory-update, memory-edge (create/delete typed directed edges between pre-existing nodes), memory-update-by-name (repair surface that resolves an elementId from a (label, name, accountId) tuple when search cannot return one), memory-lookup-by-name (deterministic read surface that returns nodes by case-insensitive exact `name` match, optionally constrained by labels, bypassing the memory-search ranking stack so a present entity is never missed because a diluted query ranked it below the cut), and the :Report surface (memory-report-write / memory-report-read-latest / memory-report-list) for reading from, writing to, and updating the Neo4j knowledge graph. Includes conversational memory — organic preference learning, evidence-backed recall, and transparent 'what do you know about me?' responses. Document ingestion goes through memory-ingest; the dispatched specialist produces typed-section JSON in-turn from the loaded ontology. Operator-solicited reclassify of an already-stored thread-shaped KD (today: email-thread KDs) is exposed as `kd-classify <attachmentId>` — runs a body-growth gate (proceed iff body grew ≥25% since the last classify, or first-ever classify), stages the body to a temp file under `$ACCOUNT_DIR/tmp/`, and returns a dispatch envelope for the `librarian`; on success `memory-ingest` replaces the prior :Section children and stamps `lastClassifiedAt` + `lastClassifiedBodyLength` on the parent KD. Two modes: `document` (default) for unstructured PDF/web content → :KnowledgeDocument (keyed on `attachmentId`) + :Section, and `chat` for conversation transcripts → :ConversationArchive (keyed on `conversationIdentity`) + :Section chunks; two parent labels, two writer paths chosen by which identity property is set. Conversation-archive Phase 2 splits across two read-only tools: `conversation-archive-list-chunks` pages chunk bodies for the dispatched specialist to read in-turn; `conversation-archive-derive-insights` converts the specialist's per-chunk claims into operator-facing proposals with per-kind cypher. `conversation-archive-enrich-rejection` records (or undoes) durable per-row rejections so already-triaged claims do not re-surface on re-runs. Ships five skills: `conversational-memory`, `document-ingest`, `conversation-archive` (source-agnostic transcript ingest for WhatsApp, Telegram, Signal, LinkedIn DMs, Zoom, meeting minutes, iMessage, Slack), `conversation-archive-mcp` (operator-initiated MCP-driven ingest for Granola, Otter, Circleback meetings — sibling of `conversation-archive` sharing the same writer surface and identity formula), and `conversation-archive-enrich` (per-row operator-gated insight derivation over a named archive's chunks). Ships three thinking-tool skills: `challenge` (adversarial retrieval — strongest counter-evidence from the graph for a given claim), `connect` (bridge-finding between two topics via shared graph neighbors), and `emerge` (clusters uncategorised KnowledgeDocument and Section nodes into operator-approved Concept proposals).",
3
+ "description": "Graph memory plugin. Provides memory-search (with optional `fields` projection for known-shape lookups), memory-write, memory-update, memory-edge (create/delete typed directed edges between pre-existing nodes), memory-update-by-name (repair surface that resolves an elementId from a (label, name, accountId) tuple when search cannot return one), memory-lookup-by-name (deterministic read surface that returns nodes by case-insensitive exact `name` match — a Person, which carries no `name`, is matched on its composed `givenName` + `familyName` display name instead — optionally constrained by labels, bypassing the memory-search ranking stack so a present entity is never missed because a diluted query ranked it below the cut), and the :Report surface (memory-report-write / memory-report-read-latest / memory-report-list) for reading from, writing to, and updating the Neo4j knowledge graph. Includes conversational memory — organic preference learning, evidence-backed recall, and transparent 'what do you know about me?' responses. Document ingestion goes through memory-ingest; the dispatched specialist produces typed-section JSON in-turn from the loaded ontology. Operator-solicited reclassify of an already-stored thread-shaped KD (today: email-thread KDs) is exposed as `kd-classify <attachmentId>` — runs a body-growth gate (proceed iff body grew ≥25% since the last classify, or first-ever classify), stages the body to a temp file under `$ACCOUNT_DIR/tmp/`, and returns a dispatch envelope for the `librarian`; on success `memory-ingest` replaces the prior :Section children and stamps `lastClassifiedAt` + `lastClassifiedBodyLength` on the parent KD. Two modes: `document` (default) for unstructured PDF/web content → :KnowledgeDocument (keyed on `attachmentId`) + :Section, and `chat` for conversation transcripts → :ConversationArchive (keyed on `conversationIdentity`) + :Section chunks; two parent labels, two writer paths chosen by which identity property is set. Conversation-archive Phase 2 splits across two read-only tools: `conversation-archive-list-chunks` pages chunk bodies for the dispatched specialist to read in-turn; `conversation-archive-derive-insights` converts the specialist's per-chunk claims into operator-facing proposals with per-kind cypher. `conversation-archive-enrich-rejection` records (or undoes) durable per-row rejections so already-triaged claims do not re-surface on re-runs. Ships five skills: `conversational-memory`, `document-ingest`, `conversation-archive` (source-agnostic transcript ingest for WhatsApp, Telegram, Signal, LinkedIn DMs, Zoom, meeting minutes, iMessage, Slack), `conversation-archive-mcp` (operator-initiated MCP-driven ingest for Granola, Otter, Circleback meetings — sibling of `conversation-archive` sharing the same writer surface and identity formula), and `conversation-archive-enrich` (per-row operator-gated insight derivation over a named archive's chunks). Ships three thinking-tool skills: `challenge` (adversarial retrieval — strongest counter-evidence from the graph for a given claim), `connect` (bridge-finding between two topics via shared graph neighbors), and `emerge` (clusters uncategorised KnowledgeDocument and Section nodes into operator-approved Concept proposals).",
4
4
  "version": "0.1.0",
5
5
  "author": {
6
6
  "name": "Rubytech LLC"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: memory
3
- description: "Graph memory plugin. Provides memory-search (with optional `fields` projection for known-shape lookups), memory-write, memory-update, memory-edge (create/delete typed directed edges between pre-existing nodes), memory-update-by-name (repair surface that resolves an elementId from a (label, name, accountId) tuple when search cannot return one), memory-lookup-by-name (deterministic read surface that returns nodes by case-insensitive exact `name` match, optionally constrained by labels, bypassing the memory-search ranking stack so a present entity is never missed because a diluted query ranked it below the cut), and the :Report surface (memory-report-write / memory-report-read-latest / memory-report-list) for reading from, writing to, and updating the Neo4j knowledge graph. Includes conversational memory — organic preference learning, evidence-backed recall, and transparent 'what do you know about me?' responses. Document ingestion goes through memory-ingest; the dispatched specialist produces typed-section JSON in-turn from the loaded ontology. Operator-solicited reclassify of an already-stored thread-shaped KD (today: email-thread KDs) is exposed as `kd-classify <attachmentId>` — runs a body-growth gate (proceed iff body grew ≥25% since the last classify, or first-ever classify), stages the body to a temp file under `$ACCOUNT_DIR/tmp/`, and returns a dispatch envelope for the `librarian`; on success `memory-ingest` replaces the prior :Section children and stamps `lastClassifiedAt` + `lastClassifiedBodyLength` on the parent KD. Two modes: `document` (default) for unstructured PDF/web content → :KnowledgeDocument (keyed on `attachmentId`) + :Section, and `chat` for conversation transcripts → :ConversationArchive (keyed on `conversationIdentity`) + :Section chunks; two parent labels, two writer paths chosen by which identity property is set. Conversation-archive Phase 2 splits across two read-only tools: `conversation-archive-list-chunks` pages chunk bodies for the dispatched specialist to read in-turn; `conversation-archive-derive-insights` converts the specialist's per-chunk claims into operator-facing proposals with per-kind cypher. `conversation-archive-enrich-rejection` records (or undoes) durable per-row rejections so already-triaged claims do not re-surface on re-runs. Ships five skills: `conversational-memory`, `document-ingest`, `conversation-archive` (source-agnostic transcript ingest for WhatsApp, Telegram, Signal, LinkedIn DMs, Zoom, meeting minutes, iMessage, Slack), `conversation-archive-mcp` (operator-initiated MCP-driven ingest for Granola, Otter, Circleback meetings — sibling of `conversation-archive` sharing the same writer surface and identity formula), and `conversation-archive-enrich` (per-row operator-gated insight derivation over a named archive's chunks). Ships three thinking-tool skills: `challenge` (adversarial retrieval — strongest counter-evidence from the graph for a given claim), `connect` (bridge-finding between two topics via shared graph neighbors), and `emerge` (clusters uncategorised KnowledgeDocument and Section nodes into operator-approved Concept proposals)."
3
+ description: "Graph memory plugin. Provides memory-search (with optional `fields` projection for known-shape lookups), memory-write, memory-update, memory-edge (create/delete typed directed edges between pre-existing nodes), memory-update-by-name (repair surface that resolves an elementId from a (label, name, accountId) tuple when search cannot return one), memory-lookup-by-name (deterministic read surface that returns nodes by case-insensitive exact `name` match — a Person, which carries no `name`, is matched on its composed `givenName` + `familyName` display name instead — optionally constrained by labels, bypassing the memory-search ranking stack so a present entity is never missed because a diluted query ranked it below the cut), and the :Report surface (memory-report-write / memory-report-read-latest / memory-report-list) for reading from, writing to, and updating the Neo4j knowledge graph. Includes conversational memory — organic preference learning, evidence-backed recall, and transparent 'what do you know about me?' responses. Document ingestion goes through memory-ingest; the dispatched specialist produces typed-section JSON in-turn from the loaded ontology. Operator-solicited reclassify of an already-stored thread-shaped KD (today: email-thread KDs) is exposed as `kd-classify <attachmentId>` — runs a body-growth gate (proceed iff body grew ≥25% since the last classify, or first-ever classify), stages the body to a temp file under `$ACCOUNT_DIR/tmp/`, and returns a dispatch envelope for the `librarian`; on success `memory-ingest` replaces the prior :Section children and stamps `lastClassifiedAt` + `lastClassifiedBodyLength` on the parent KD. Two modes: `document` (default) for unstructured PDF/web content → :KnowledgeDocument (keyed on `attachmentId`) + :Section, and `chat` for conversation transcripts → :ConversationArchive (keyed on `conversationIdentity`) + :Section chunks; two parent labels, two writer paths chosen by which identity property is set. Conversation-archive Phase 2 splits across two read-only tools: `conversation-archive-list-chunks` pages chunk bodies for the dispatched specialist to read in-turn; `conversation-archive-derive-insights` converts the specialist's per-chunk claims into operator-facing proposals with per-kind cypher. `conversation-archive-enrich-rejection` records (or undoes) durable per-row rejections so already-triaged claims do not re-surface on re-runs. Ships five skills: `conversational-memory`, `document-ingest`, `conversation-archive` (source-agnostic transcript ingest for WhatsApp, Telegram, Signal, LinkedIn DMs, Zoom, meeting minutes, iMessage, Slack), `conversation-archive-mcp` (operator-initiated MCP-driven ingest for Granola, Otter, Circleback meetings — sibling of `conversation-archive` sharing the same writer surface and identity formula), and `conversation-archive-enrich` (per-row operator-gated insight derivation over a named archive's chunks). Ships three thinking-tool skills: `challenge` (adversarial retrieval — strongest counter-evidence from the graph for a given claim), `connect` (bridge-finding between two topics via shared graph neighbors), and `emerge` (clusters uncategorised KnowledgeDocument and Section nodes into operator-approved Concept proposals)."
4
4
  tools:
5
5
  - name: memory-search
6
6
  publicAllowlist: false
@@ -341,7 +341,9 @@ eagerTool(server, "memory-search", "Search the knowledge graph using semantic ve
341
341
  eagerTool(server, "memory-lookup-by-name", "Deterministic by-name entity lookup. Returns every node whose `name` matches " +
342
342
  "the given name exactly (case-insensitive), bypassing the memory-search ranking " +
343
343
  "stack — a name match is a predicate, not a similarity score, so there is no " +
344
- "result cut to fall below. Use this when memory-search returns no result for a " +
344
+ "result cut to fall below. A Person carries no `name` property, so a Person is " +
345
+ "matched on its composed display name (`givenName` then `familyName`) instead. " +
346
+ "Use this when memory-search returns no result for a " +
345
347
  "named entity you believe exists, or when the operator asks for 'the X node' by " +
346
348
  "name. Optionally constrain by `labels`. Scoped to your account, allowed scopes, " +
347
349
  "slice, and agent the same way memory-search is, and excludes trashed nodes. " +