@rubytech/create-maxy-code 0.1.59 → 0.1.60

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 (125) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/loop/PLUGIN.md +13 -1
  3. package/payload/platform/plugins/loop/mcp/dist/index.js +8 -7
  4. package/payload/platform/plugins/loop/mcp/dist/index.js.map +1 -1
  5. package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.d.ts +3 -0
  6. package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.d.ts.map +1 -0
  7. package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.js +48 -0
  8. package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.js.map +1 -0
  9. package/payload/platform/plugins/loop/mcp/dist/lib/key-store.d.ts +22 -0
  10. package/payload/platform/plugins/loop/mcp/dist/lib/key-store.d.ts.map +1 -0
  11. package/payload/platform/plugins/loop/mcp/dist/lib/key-store.js +165 -0
  12. package/payload/platform/plugins/loop/mcp/dist/lib/key-store.js.map +1 -0
  13. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.d.ts +1 -1
  14. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +1 -1
  15. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.js +4 -39
  16. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.js.map +1 -1
  17. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.d.ts.map +1 -1
  18. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.js +5 -15
  19. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.js.map +1 -1
  20. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.d.ts.map +1 -1
  21. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.js +11 -28
  22. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.js.map +1 -1
  23. package/payload/platform/plugins/loop/mcp/src/index.ts +10 -7
  24. package/payload/platform/plugins/loop/mcp/src/lib/file-crypto.ts +54 -0
  25. package/payload/platform/plugins/loop/mcp/src/lib/key-store.ts +221 -0
  26. package/payload/platform/plugins/loop/mcp/src/lib/loop-api.ts +5 -42
  27. package/payload/platform/plugins/loop/mcp/src/tools/key-deregister.ts +5 -20
  28. package/payload/platform/plugins/loop/mcp/src/tools/key-register.ts +14 -39
  29. package/payload/platform/plugins/property-data/PLUGIN.md +14 -1
  30. package/payload/platform/plugins/property-data/mcp/dist/index.js +14 -11
  31. package/payload/platform/plugins/property-data/mcp/dist/index.js.map +1 -1
  32. package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.d.ts +3 -0
  33. package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.d.ts.map +1 -0
  34. package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.js +49 -0
  35. package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.js.map +1 -0
  36. package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.d.ts +15 -0
  37. package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.d.ts.map +1 -0
  38. package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.js +135 -0
  39. package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.js.map +1 -0
  40. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +0 -1
  41. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -1
  42. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js +11 -22
  43. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -1
  44. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -1
  45. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js +2 -2
  46. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -1
  47. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -1
  48. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js +5 -15
  49. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -1
  50. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -1
  51. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js +30 -23
  52. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -1
  53. package/payload/platform/plugins/property-data/mcp/src/index.ts +16 -11
  54. package/payload/platform/plugins/property-data/mcp/src/lib/file-crypto.ts +55 -0
  55. package/payload/platform/plugins/property-data/mcp/src/lib/key-store.ts +181 -0
  56. package/payload/platform/plugins/property-data/mcp/src/lib/propertydata-api.ts +9 -24
  57. package/payload/platform/plugins/property-data/mcp/src/tools/endpoints.ts +2 -2
  58. package/payload/platform/plugins/property-data/mcp/src/tools/key-deregister.ts +5 -17
  59. package/payload/platform/plugins/property-data/mcp/src/tools/key-register.ts +29 -33
  60. package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +13 -1
  61. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/index.js +8 -7
  62. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/index.js.map +1 -1
  63. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/file-crypto.d.ts +3 -0
  64. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/file-crypto.d.ts.map +1 -0
  65. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/file-crypto.js +48 -0
  66. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/file-crypto.js.map +1 -0
  67. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/key-store.d.ts +22 -0
  68. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/key-store.d.ts.map +1 -0
  69. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/key-store.js +165 -0
  70. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/key-store.js.map +1 -0
  71. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.d.ts +1 -1
  72. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +1 -1
  73. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.js +4 -39
  74. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/loop-api.js.map +1 -1
  75. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-deregister.d.ts.map +1 -1
  76. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-deregister.js +5 -15
  77. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-deregister.js.map +1 -1
  78. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-register.d.ts.map +1 -1
  79. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-register.js +11 -28
  80. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/tools/key-register.js.map +1 -1
  81. package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/index.ts +10 -7
  82. package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/file-crypto.ts +54 -0
  83. package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/key-store.ts +221 -0
  84. package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/loop-api.ts +5 -42
  85. package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/key-deregister.ts +5 -20
  86. package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/tools/key-register.ts +14 -39
  87. package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +14 -1
  88. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js +14 -11
  89. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js.map +1 -1
  90. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/file-crypto.d.ts +3 -0
  91. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/file-crypto.d.ts.map +1 -0
  92. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/file-crypto.js +49 -0
  93. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/file-crypto.js.map +1 -0
  94. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/key-store.d.ts +15 -0
  95. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/key-store.d.ts.map +1 -0
  96. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/key-store.js +135 -0
  97. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/key-store.js.map +1 -0
  98. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +0 -1
  99. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -1
  100. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js +11 -22
  101. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -1
  102. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -1
  103. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js +2 -2
  104. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -1
  105. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -1
  106. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js +5 -15
  107. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -1
  108. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -1
  109. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js +30 -23
  110. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -1
  111. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/index.ts +16 -11
  112. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/file-crypto.ts +55 -0
  113. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/key-store.ts +181 -0
  114. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/propertydata-api.ts +9 -24
  115. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/endpoints.ts +2 -2
  116. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-deregister.ts +5 -17
  117. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-register.ts +29 -33
  118. package/payload/server/public/assets/{admin-nqCBFiSl.js → admin-Bp-BjBCX.js} +51 -51
  119. package/payload/server/public/index.html +1 -1
  120. package/payload/server/server.js +4 -3
  121. package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.d.ts +0 -51
  122. package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.d.ts.map +0 -1
  123. package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.js +0 -196
  124. package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/dist/index.js.map +0 -1
  125. package/payload/premium-plugins/real-agent/lib/mcp-stderr-tee/package.json +0 -7
@@ -0,0 +1,135 @@
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
2
+ import { resolve, dirname } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { getSession } from "./neo4j.js";
5
+ import { encrypt, decrypt } from "./crypto.js";
6
+ import { encryptWith, decryptWith } from "./file-crypto.js";
7
+ class Neo4jKeyStore {
8
+ backendName = "neo4j";
9
+ backendPath = process.env.NEO4J_URI ?? "<unset>";
10
+ async load(accountId) {
11
+ const session = getSession();
12
+ try {
13
+ const result = await session.run(`MATCH (k:PropertyDataKey {accountId: $accountId})
14
+ RETURN k.encryptedKey AS encryptedKey,
15
+ k.createdAt AS createdAt,
16
+ k.updatedAt AS updatedAt`, { accountId });
17
+ if (result.records.length === 0)
18
+ return null;
19
+ const r = result.records[0];
20
+ return {
21
+ apiKey: decrypt(r.get("encryptedKey")),
22
+ createdAt: r.get("createdAt") ?? "",
23
+ updatedAt: r.get("updatedAt") ?? "",
24
+ };
25
+ }
26
+ finally {
27
+ await session.close();
28
+ }
29
+ }
30
+ async save(accountId, apiKey) {
31
+ const encryptedKey = encrypt(apiKey);
32
+ const now = new Date().toISOString();
33
+ const session = getSession();
34
+ try {
35
+ await session.run(`CREATE INDEX property_data_key_account IF NOT EXISTS
36
+ FOR (k:PropertyDataKey) ON (k.accountId)`, {});
37
+ await session.run(`MERGE (k:PropertyDataKey {accountId: $accountId})
38
+ ON CREATE SET k.encryptedKey = $encryptedKey, k.createdAt = $now, k.updatedAt = $now
39
+ ON MATCH SET k.encryptedKey = $encryptedKey, k.updatedAt = $now`, { accountId, encryptedKey, now });
40
+ }
41
+ finally {
42
+ await session.close();
43
+ }
44
+ }
45
+ async delete(accountId) {
46
+ const session = getSession();
47
+ try {
48
+ const result = await session.run(`MATCH (k:PropertyDataKey {accountId: $accountId})
49
+ DELETE k
50
+ RETURN count(k) AS deleted`, { accountId });
51
+ const deleted = result.records[0]?.get("deleted")?.toNumber?.() ?? 0;
52
+ return deleted > 0;
53
+ }
54
+ finally {
55
+ await session.close();
56
+ }
57
+ }
58
+ }
59
+ const LABEL = "property-data";
60
+ class FileKeyStore {
61
+ backendName = "file";
62
+ backendPath;
63
+ storePath;
64
+ keyFilePath;
65
+ constructor() {
66
+ const home = homedir();
67
+ this.storePath = resolve(home, ".claude/.realagent-property-data-key.enc");
68
+ this.keyFilePath = resolve(home, ".claude/.realagent-property-data-encryption-key");
69
+ this.backendPath = this.storePath;
70
+ }
71
+ ensureDir() {
72
+ mkdirSync(dirname(this.storePath), { recursive: true });
73
+ }
74
+ readAll() {
75
+ if (!existsSync(this.storePath))
76
+ return {};
77
+ const blob = readFileSync(this.storePath, "utf-8").trim();
78
+ if (!blob)
79
+ return {};
80
+ const json = decryptWith(blob, this.keyFilePath, LABEL);
81
+ return JSON.parse(json);
82
+ }
83
+ writeAll(env) {
84
+ this.ensureDir();
85
+ const blob = encryptWith(JSON.stringify(env), this.keyFilePath, LABEL);
86
+ writeFileSync(this.storePath, blob, { mode: 0o600 });
87
+ }
88
+ async load(accountId) {
89
+ const env = this.readAll();
90
+ const entry = env[accountId];
91
+ if (!entry)
92
+ return null;
93
+ // The encryptedKey field is double-encrypted: the file blob is decrypted
94
+ // above, the inner field is the original AES-GCM-wrapped key. Keep the
95
+ // inner layer so an unauthenticated read of decrypted JSON still doesn't
96
+ // expose the API key directly in process memory until decryptWith runs.
97
+ return {
98
+ apiKey: decryptWith(entry.encryptedKey, this.keyFilePath, LABEL),
99
+ createdAt: entry.createdAt,
100
+ updatedAt: entry.updatedAt,
101
+ };
102
+ }
103
+ async save(accountId, apiKey) {
104
+ const env = this.readAll();
105
+ const now = new Date().toISOString();
106
+ const encryptedKey = encryptWith(apiKey, this.keyFilePath, LABEL);
107
+ const prev = env[accountId];
108
+ env[accountId] = {
109
+ encryptedKey,
110
+ createdAt: prev?.createdAt ?? now,
111
+ updatedAt: now,
112
+ };
113
+ this.writeAll(env);
114
+ }
115
+ async delete(accountId) {
116
+ const env = this.readAll();
117
+ if (!(accountId in env))
118
+ return false;
119
+ delete env[accountId];
120
+ this.writeAll(env);
121
+ return true;
122
+ }
123
+ }
124
+ let cached = null;
125
+ export function selectKeyStore() {
126
+ if (cached)
127
+ return cached;
128
+ cached = process.env.PROPERTY_DATA_STANDALONE === "1" ? new FileKeyStore() : new Neo4jKeyStore();
129
+ return cached;
130
+ }
131
+ // Test seam — used by unit tests to reset the cached store between cases.
132
+ export function _resetKeyStoreForTests() {
133
+ cached = null;
134
+ }
135
+ //# sourceMappingURL=key-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-store.js","sourceRoot":"","sources":["../../src/lib/key-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAqB5D,MAAM,aAAa;IACR,WAAW,GAAG,OAAO,CAAC;IACtB,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC;IAE1D,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B;;;yCAGiC,EACjC,EAAE,SAAS,EAAE,CACd,CAAC;YACF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC7C,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC5B,OAAO;gBACL,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBACtC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE;gBACnC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE;aACpC,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,MAAc;QAC1C,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,GAAG,CACf;kDAC0C,EAC1C,EAAE,CACH,CAAC;YACF,MAAM,OAAO,CAAC,GAAG,CACf;;0EAEkE,EAClE,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,CACjC,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAiB;QAC5B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B;;oCAE4B,EAC5B,EAAE,SAAS,EAAE,CACd,CAAC;YACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC;YACrE,OAAO,OAAO,GAAG,CAAC,CAAC;QACrB,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;CACF;AAWD,MAAM,KAAK,GAAG,eAAe,CAAC;AAE9B,MAAM,YAAY;IACP,WAAW,GAAG,MAAM,CAAC;IACrB,WAAW,CAAS;IACZ,SAAS,CAAS;IAClB,WAAW,CAAS;IAErC;QACE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,0CAA0C,CAAC,CAAC;QAC3E,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,iDAAiD,CAAC,CAAC;QACpF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;IACpC,CAAC;IAEO,SAAS;QACf,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAEO,OAAO;QACb,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,OAAO,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAiB,CAAC;IAC1C,CAAC;IAEO,QAAQ,CAAC,GAAiB;QAChC,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACvE,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,yEAAyE;QACzE,uEAAuE;QACvE,yEAAyE;QACzE,wEAAwE;QACxE,OAAO;YACL,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC;YAChE,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,MAAc;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;QAC5B,GAAG,CAAC,SAAS,CAAC,GAAG;YACf,YAAY;YACZ,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,GAAG;YACjC,SAAS,EAAE,GAAG;SACf,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAiB;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACtC,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC;QACtB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,IAAI,MAAM,GAAoB,IAAI,CAAC;AAEnC,MAAM,UAAU,cAAc;IAC5B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC;IACjG,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,sBAAsB;IACpC,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC"}
@@ -13,7 +13,6 @@ export declare class BadResponseError extends Error {
13
13
  constructor(endpoint: string, length: number);
14
14
  }
15
15
  export interface PropertyDataKey {
16
- encryptedKey: string;
17
16
  createdAt: string;
18
17
  updatedAt: string;
19
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"propertydata-api.d.ts","sourceRoot":"","sources":["../../src/lib/propertydata-api.ts"],"names":[],"mappings":"AAkBA,qBAAa,qBAAsB,SAAQ,KAAK;;CAK/C;AAED,qBAAa,iBAAkB,SAAQ,KAAK;aAExB,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;aAChB,eAAe,EAAE,MAAM;gBAFvB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM;CAK1C;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aACb,QAAQ,EAAE,MAAM;aAAkB,MAAM,EAAE,MAAM;gBAAhD,QAAQ,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM;CAI7E;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAoBvF;AAED,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI7E;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;CACrD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDzE"}
1
+ {"version":3,"file":"propertydata-api.d.ts","sourceRoot":"","sources":["../../src/lib/propertydata-api.ts"],"names":[],"mappings":"AAiBA,qBAAa,qBAAsB,SAAQ,KAAK;;CAK/C;AAED,qBAAa,iBAAkB,SAAQ,KAAK;aAExB,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;aAChB,eAAe,EAAE,MAAM;gBAFvB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM;CAK1C;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aACb,QAAQ,EAAE,MAAM;aAAkB,MAAM,EAAE,MAAM;gBAAhD,QAAQ,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM;CAI7E;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAIvF;AAED,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7E;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;CACrD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDzE"}
@@ -1,5 +1,4 @@
1
- import { getSession } from "./neo4j.js";
2
- import { decrypt } from "./crypto.js";
1
+ import { selectKeyStore } from "./key-store.js";
3
2
  // PropertyData API V1 client. Every endpoint is a GET against
4
3
  // https://api.propertydata.co.uk/<endpoint> with `key=<api-key>` plus
5
4
  // endpoint-specific query params. Response envelope:
@@ -42,30 +41,20 @@ export class BadResponseError extends Error {
42
41
  }
43
42
  }
44
43
  export async function loadAccountKey(accountId) {
45
- const session = getSession();
46
- try {
47
- const result = await session.run(`MATCH (k:PropertyDataKey {accountId: $accountId})
48
- RETURN k.encryptedKey AS encryptedKey,
49
- k.createdAt AS createdAt,
50
- k.updatedAt AS updatedAt`, { accountId });
51
- if (result.records.length === 0)
52
- return null;
53
- const r = result.records[0];
54
- return {
55
- encryptedKey: r.get("encryptedKey"),
56
- createdAt: r.get("createdAt") ?? "",
57
- updatedAt: r.get("updatedAt") ?? "",
58
- };
59
- }
60
- finally {
61
- await session.close();
62
- }
44
+ const stored = await selectKeyStore().load(accountId);
45
+ if (!stored)
46
+ return null;
47
+ return { createdAt: stored.createdAt, updatedAt: stored.updatedAt };
63
48
  }
64
49
  export async function resolveAccountApiKey(accountId) {
65
- const stored = await loadAccountKey(accountId);
50
+ // Bypass for one-shot CLI runs: explicit env var beats stored key.
51
+ const envKey = process.env.PROPERTY_DATA_API_KEY;
52
+ if (envKey && envKey.trim())
53
+ return envKey.trim();
54
+ const stored = await selectKeyStore().load(accountId);
66
55
  if (!stored)
67
56
  throw new KeyNotRegisteredError();
68
- return decrypt(stored.encryptedKey);
57
+ return stored.apiKey;
69
58
  }
70
59
  export async function propertyDataCall(opts) {
71
60
  const { endpoint, toolName, accountId, params } = opts;
@@ -1 +1 @@
1
- {"version":3,"file":"propertydata-api.js","sourceRoot":"","sources":["../../src/lib/propertydata-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"propertydata-api.js","sourceRoot":"","sources":["../../src/lib/propertydata-api.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/tools/endpoints.ts"],"names":[],"mappings":"AAMA,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAY5D,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBAA8D,CAAC;AACpG,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBAA8D,CAAC;AACpG,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,WAAW,GAAI,GAAG,IAAI,oBAA0D,CAAC;AAM9F,eAAO,MAAM,YAAY,GAAI,GAAG,IAAI,oBACuB,CAAC;AAC5D,eAAO,MAAM,gBAAgB,GAAI,GAAG,IAAI,oBAC6B,CAAC;AACtE,eAAO,MAAM,KAAK,GAAI,GAAG,IAAI,oBAA4C,CAAC;AAC1E,eAAO,MAAM,SAAS,GAAI,GAAG,IAAI,oBAAsD,CAAC;AACxF,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,oBAAoB,GAAI,GAAG,IAAI,oBAC6B,CAAC;AAC1E,eAAO,MAAM,gBAAgB,GAAI,GAAG,IAAI,oBAC2B,CAAC;AACpE,eAAO,MAAM,SAAS,GAAI,GAAG,IAAI,oBAAsD,CAAC;AACxF,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBACsB,CAAC"}
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/tools/endpoints.ts"],"names":[],"mappings":"AAMA,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAY5D,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBAA8D,CAAC;AACpG,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBAA8D,CAAC;AACpG,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAkD,CAAC;AACrF,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,MAAM,GAAI,GAAG,IAAI,oBAA8C,CAAC;AAC7E,eAAO,MAAM,WAAW,GAAI,GAAG,IAAI,oBAA2D,CAAC;AAM/F,eAAO,MAAM,YAAY,GAAI,GAAG,IAAI,oBACuB,CAAC;AAC5D,eAAO,MAAM,gBAAgB,GAAI,GAAG,IAAI,oBAC6B,CAAC;AACtE,eAAO,MAAM,KAAK,GAAI,GAAG,IAAI,oBAA4C,CAAC;AAC1E,eAAO,MAAM,SAAS,GAAI,GAAG,IAAI,oBAAsD,CAAC;AACxF,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,oBAAoB,GAAI,GAAG,IAAI,oBAC6B,CAAC;AAC1E,eAAO,MAAM,gBAAgB,GAAI,GAAG,IAAI,oBAC2B,CAAC;AACpE,eAAO,MAAM,SAAS,GAAI,GAAG,IAAI,oBAAsD,CAAC;AACxF,eAAO,MAAM,UAAU,GAAI,GAAG,IAAI,oBAAwD,CAAC;AAC3F,eAAO,MAAM,aAAa,GAAI,GAAG,IAAI,oBACsB,CAAC"}
@@ -11,12 +11,12 @@ function call(toolName, endpoint, args) {
11
11
  export const valuationSale = (a) => call("property-data-valuation-sale", "valuation-sale", a);
12
12
  export const valuationRent = (a) => call("property-data-valuation-rent", "valuation-rent", a);
13
13
  export const prices = (a) => call("property-data-prices", "prices", a);
14
- export const pricesRent = (a) => call("property-data-prices-rent", "prices-rent", a);
14
+ export const pricesRent = (a) => call("property-data-prices-rent", "rents", a);
15
15
  export const soldPrices = (a) => call("property-data-sold-prices", "sold-prices", a);
16
16
  export const demand = (a) => call("property-data-demand", "demand", a);
17
17
  export const yields = (a) => call("property-data-yields", "yields", a);
18
18
  export const growth = (a) => call("property-data-growth", "growth", a);
19
- export const nationalHpi = (a) => call("property-data-national-hpi", "national-hpi", a);
19
+ export const nationalHpi = (a) => call("property-data-national-hpi", "national-data", a);
20
20
  // Task 144 — 10 additional read endpoints (£/sqft, area risk,
21
21
  // planning precedent, UPRN, demand-rent, property-type mix).
22
22
  // All inherit the same observability + error contract as above.
@@ -1 +1 @@
1
- {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/tools/endpoints.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/tools/endpoints.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"key-deregister.d.ts","sourceRoot":"","sources":["../../src/tools/key-deregister.ts"],"names":[],"mappings":"AAEA,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhF"}
1
+ {"version":3,"file":"key-deregister.d.ts","sourceRoot":"","sources":["../../src/tools/key-deregister.ts"],"names":[],"mappings":"AAEA,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhF"}
@@ -1,19 +1,9 @@
1
- import { getSession } from "../lib/neo4j.js";
1
+ import { selectKeyStore } from "../lib/key-store.js";
2
2
  export async function keyDeregister(params) {
3
- const { accountId } = params;
4
- const session = getSession();
5
- try {
6
- const result = await session.run(`MATCH (k:PropertyDataKey {accountId: $accountId})
7
- DELETE k
8
- RETURN count(k) AS deleted`, { accountId });
9
- const deleted = result.records[0]?.get("deleted")?.toNumber?.() ?? 0;
10
- if (deleted === 0) {
11
- throw new Error("No PropertyData API key is registered for this account.");
12
- }
3
+ const deleted = await selectKeyStore().delete(params.accountId);
4
+ if (!deleted) {
5
+ throw new Error("No PropertyData API key is registered for this account.");
13
6
  }
14
- finally {
15
- await session.close();
16
- }
17
- console.error(`[property-data] key-op op=deregister account=${accountId}`);
7
+ console.error(`[property-data] key-op op=deregister account=${params.accountId}`);
18
8
  }
19
9
  //# sourceMappingURL=key-deregister.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"key-deregister.js","sourceRoot":"","sources":["../../src/tools/key-deregister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA6B;IAC/D,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAC7B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B;;kCAE4B,EAC5B,EAAE,SAAS,EAAE,CACd,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC;QACrE,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,gDAAgD,SAAS,EAAE,CAAC,CAAC;AAC7E,CAAC"}
1
+ {"version":3,"file":"key-deregister.js","sourceRoot":"","sources":["../../src/tools/key-deregister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA6B;IAC/D,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAChE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,gDAAgD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;AACpF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"key-register.d.ts","sourceRoot":"","sources":["../../src/tools/key-register.ts"],"names":[],"mappings":"AA2BA,wBAAsB,WAAW,CAAC,MAAM,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BhB"}
1
+ {"version":3,"file":"key-register.d.ts","sourceRoot":"","sources":["../../src/tools/key-register.ts"],"names":[],"mappings":"AA6CA,wBAAsB,WAAW,CAAC,MAAM,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhB"}
@@ -1,43 +1,50 @@
1
- import { getSession } from "../lib/neo4j.js";
2
- import { encrypt } from "../lib/crypto.js";
1
+ import { selectKeyStore } from "../lib/key-store.js";
3
2
  import { PropertyDataError } from "../lib/propertydata-api.js";
4
3
  const BASE_URL = "https://api.propertydata.co.uk";
5
4
  const REQUEST_TIMEOUT_MS = 15_000;
6
- // Validate by hitting a cheap endpoint that returns success on any valid key:
7
- // /national-hpi takes no postcode and is rate-cheap. Treat a 200 as the key
8
- // passing PropertyData's authentication check; treat 401/403 as an explicit
9
- // key rejection so the operator gets an actionable message; treat anything
10
- // else as an unverified-key error (network, upstream outage).
5
+ // Validate the key against PropertyData's /valuation-sale endpoint with no
6
+ // inputs a valid key returns HTTP 400 + body code 701 "Missing input:
7
+ // property_type" (proof the key was accepted), without consuming a credit.
8
+ // An invalid key returns auth failure (401/403) or a different upstream code.
9
+ // Evidence: probing `/national-hpi` returns code X01 "Invalid API endpoint"
10
+ // — that path does not exist on PropertyData; `/valuation-sale` does.
11
11
  async function validateApiKey(apiKey) {
12
- const url = `${BASE_URL}/national-hpi?key=${encodeURIComponent(apiKey)}`;
12
+ // Probe /valuation-sale with one input. Evidence-backed envelopes:
13
+ // invalid key → {code:"X03", message:"Invalid input: key"}
14
+ // valid key → {code:"701", message:"Missing input: property_type"} (no credit)
15
+ // PropertyData does not charge for missing-input errors, so this is a free probe.
16
+ const url = `${BASE_URL}/valuation-sale?key=${encodeURIComponent(apiKey)}&postcode=SW1A1AA`;
13
17
  const response = await fetch(url, {
14
18
  headers: { Accept: "application/json" },
15
19
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
16
20
  });
21
+ const body = await response.text().catch(() => "");
17
22
  if (response.status === 401 || response.status === 403) {
18
23
  throw new Error(`PropertyData rejected the API key (HTTP ${response.status}).`);
19
24
  }
25
+ let parsed = {};
26
+ try {
27
+ parsed = JSON.parse(body);
28
+ }
29
+ catch { /* fall through */ }
30
+ if (parsed.code === "X03") {
31
+ throw new Error(`PropertyData rejected the API key (code=X03 ${parsed.message ?? "Invalid input: key"}).`);
32
+ }
33
+ // 701 (missing-input) or status:"success" both prove the key was authenticated.
34
+ // Any other envelope: surface raw so the operator sees the upstream error.
35
+ if (parsed.status === "success" || parsed.code === "701")
36
+ return;
37
+ if (parsed.status === "error") {
38
+ throw new Error(`PropertyData validate probe returned unexpected envelope (code=${parsed.code ?? "?"} message=${parsed.message ?? "?"}).`);
39
+ }
20
40
  if (!response.ok) {
21
- const body = await response.text().catch(() => "");
22
- throw new PropertyDataError(response.status, "national-hpi", body.slice(0, 200));
41
+ throw new PropertyDataError(response.status, "valuation-sale", body.slice(0, 200));
23
42
  }
24
43
  }
25
44
  export async function keyRegister(params) {
26
45
  const { apiKey, accountId } = params;
27
46
  await validateApiKey(apiKey);
28
- const encryptedKey = encrypt(apiKey);
29
- const now = new Date().toISOString();
30
- const session = getSession();
31
- try {
32
- await session.run(`CREATE INDEX property_data_key_account IF NOT EXISTS
33
- FOR (k:PropertyDataKey) ON (k.accountId)`, {});
34
- await session.run(`MERGE (k:PropertyDataKey {accountId: $accountId})
35
- ON CREATE SET k.encryptedKey = $encryptedKey, k.createdAt = $now, k.updatedAt = $now
36
- ON MATCH SET k.encryptedKey = $encryptedKey, k.updatedAt = $now`, { accountId, encryptedKey, now });
37
- }
38
- finally {
39
- await session.close();
40
- }
47
+ await selectKeyStore().save(accountId, apiKey);
41
48
  console.error(`[property-data] key-op op=register account=${accountId}`);
42
49
  }
43
50
  //# sourceMappingURL=key-register.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"key-register.js","sourceRoot":"","sources":["../../src/tools/key-register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D,MAAM,QAAQ,GAAG,gCAAgC,CAAC;AAClD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,8EAA8E;AAC9E,4EAA4E;AAC5E,4EAA4E;AAC5E,2EAA2E;AAC3E,8DAA8D;AAC9D,KAAK,UAAU,cAAc,CAAC,MAAc;IAC1C,MAAM,GAAG,GAAG,GAAG,QAAQ,qBAAqB,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;IACzE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;QACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;KAChD,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,2CAA2C,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM,IAAI,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACnF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAGjC;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAErC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;IAE7B,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,CACf;gDAC0C,EAC1C,EAAE,CACH,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CACf;;wEAEkE,EAClE,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,CACjC,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,8CAA8C,SAAS,EAAE,CAAC,CAAC;AAC3E,CAAC"}
1
+ {"version":3,"file":"key-register.js","sourceRoot":"","sources":["../../src/tools/key-register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D,MAAM,QAAQ,GAAG,gCAAgC,CAAC;AAClD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,2EAA2E;AAC3E,wEAAwE;AACxE,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,sEAAsE;AAEtE,KAAK,UAAU,cAAc,CAAC,MAAc;IAC1C,mEAAmE;IACnE,6DAA6D;IAC7D,mFAAmF;IACnF,kFAAkF;IAClF,MAAM,GAAG,GAAG,GAAG,QAAQ,uBAAuB,kBAAkB,CAAC,MAAM,CAAC,mBAAmB,CAAC;IAC5F,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;QACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;KAChD,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACnD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,2CAA2C,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,MAAM,GAAyD,EAAE,CAAC;IACtE,IAAI,CAAC;QAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAC/D,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,+CAA+C,MAAM,CAAC,OAAO,IAAI,oBAAoB,IAAI,CAAC,CAAC;IAC7G,CAAC;IACD,gFAAgF;IAChF,2EAA2E;IAC3E,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO;IACjE,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,kEAAkE,MAAM,CAAC,IAAI,IAAI,GAAG,YAAY,MAAM,CAAC,OAAO,IAAI,GAAG,IAAI,CAC1H,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAGjC;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IACrC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,cAAc,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC/C,OAAO,CAAC,KAAK,CAAC,8CAA8C,SAAS,EAAE,CAAC,CAAC;AAC3E,CAAC"}
@@ -1,5 +1,6 @@
1
- import { initStderrTee } from "../../../../../../platform/lib/mcp-stderr-tee/dist/index.js";
2
- initStderrTee("property-data");
1
+ // Logging-tee was a platform-wrapper concern: the platform's mcp-spawn-tee
2
+ // pipes our stderr where it wants. In standalone mode (Claude Code native
3
+ // spawn) the host owns the stderr pipe. Either way, we just write to stderr.
3
4
 
4
5
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
6
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -34,18 +35,22 @@ import {
34
35
  PropertyDataError,
35
36
  BadResponseError,
36
37
  } from "./lib/propertydata-api.js";
38
+ import { selectKeyStore } from "./lib/key-store.js";
37
39
 
38
- const accountId = process.env.ACCOUNT_ID;
39
- if (!accountId) {
40
- throw new Error("ACCOUNT_ID environment variable is required");
41
- }
40
+ // ACCOUNT_ID is the platform's tenant id; in standalone mode (Claude Code
41
+ // native spawn) there is no platform tenant, so "local" is the single-tenant
42
+ // stand-in. Same MCP body, env-selected backend.
43
+ const accountId = process.env.ACCOUNT_ID ?? "local";
42
44
 
43
45
  const server = new McpServer({
44
46
  name: "maxy-property-data",
45
47
  version: "0.1.0",
46
48
  });
47
49
 
48
- console.error(`[property-data] server started, account=${accountId}`);
50
+ const store = selectKeyStore();
51
+ console.error(
52
+ `[property-data] server started, account=${accountId} backend=${store.backendName} path=${store.backendPath}`,
53
+ );
49
54
 
50
55
  function errorEnvelope(err: unknown): { content: { type: "text"; text: string }[]; isError: true } {
51
56
  let text: string;
@@ -67,7 +72,7 @@ function endpointHandler<P extends Record<string, unknown>>(
67
72
  ) {
68
73
  return async (params: P) => {
69
74
  try {
70
- const text = await fn({ ...params, accountId: accountId as string });
75
+ const text = await fn({ ...params, accountId });
71
76
  return { content: [{ type: "text" as const, text }] };
72
77
  } catch (err) {
73
78
  return errorEnvelope(err);
@@ -87,7 +92,7 @@ server.tool(
87
92
  },
88
93
  async ({ apiKey }) => {
89
94
  try {
90
- await keyRegister({ apiKey, accountId: accountId as string });
95
+ await keyRegister({ apiKey, accountId });
91
96
  return {
92
97
  content: [
93
98
  {
@@ -108,7 +113,7 @@ server.tool(
108
113
  {},
109
114
  async () => {
110
115
  try {
111
- await keyDeregister({ accountId: accountId as string });
116
+ await keyDeregister({ accountId });
112
117
  return {
113
118
  content: [{ type: "text" as const, text: "PropertyData API key deregistered." }],
114
119
  };
@@ -124,7 +129,7 @@ server.tool(
124
129
  {},
125
130
  async () => {
126
131
  try {
127
- const text = await keyList({ accountId: accountId as string });
132
+ const text = await keyList({ accountId });
128
133
  return { content: [{ type: "text" as const, text }] };
129
134
  } catch (err) {
130
135
  return errorEnvelope(err);
@@ -0,0 +1,55 @@
1
+ import { randomBytes, createCipheriv, createDecipheriv } from "node:crypto";
2
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
3
+
4
+ // Standalone-mode crypto. Same AES-256-GCM envelope as crypto.ts, but the
5
+ // encryption-key file path is passed in (not derived from PLATFORM_ROOT /
6
+ // brand.json), so it can live under ~/.claude/ when the MCP is spawned by
7
+ // Claude Code natively.
8
+
9
+ const ALGORITHM = "aes-256-gcm";
10
+ const KEY_LENGTH = 32;
11
+ const IV_LENGTH = 12;
12
+ const AUTH_TAG_LENGTH = 16;
13
+
14
+ function loadOrGenerateKey(keyFilePath: string, label: string): Buffer {
15
+ if (existsSync(keyFilePath)) {
16
+ const hex = readFileSync(keyFilePath, "utf-8").trim();
17
+ const buf = Buffer.from(hex, "hex");
18
+ if (buf.length !== KEY_LENGTH) {
19
+ throw new Error(
20
+ `[${label}] encryption key at ${keyFilePath} is ${buf.length} bytes, expected ${KEY_LENGTH}.`,
21
+ );
22
+ }
23
+ return buf;
24
+ }
25
+ const key = randomBytes(KEY_LENGTH);
26
+ writeFileSync(keyFilePath, key.toString("hex"), { mode: 0o600 });
27
+ console.error(`[${label}] encryption key generated at ${keyFilePath}`);
28
+ return key;
29
+ }
30
+
31
+ export function encryptWith(plaintext: string, keyFilePath: string, label: string): string {
32
+ const key = loadOrGenerateKey(keyFilePath, label);
33
+ const iv = randomBytes(IV_LENGTH);
34
+ const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
35
+ let encrypted = cipher.update(plaintext, "utf-8", "hex");
36
+ encrypted += cipher.final("hex");
37
+ const authTag = cipher.getAuthTag().toString("hex");
38
+ return `${iv.toString("hex")}:${encrypted}:${authTag}`;
39
+ }
40
+
41
+ export function decryptWith(encryptedValue: string, keyFilePath: string, label: string): string {
42
+ const parts = encryptedValue.split(":");
43
+ if (parts.length !== 3) {
44
+ throw new Error(`[${label}] bad encrypted envelope (expected iv:ct:tag)`);
45
+ }
46
+ const key = loadOrGenerateKey(keyFilePath, label);
47
+ const iv = Buffer.from(parts[0], "hex");
48
+ const ciphertext = parts[1];
49
+ const authTag = Buffer.from(parts[2], "hex");
50
+ const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
51
+ decipher.setAuthTag(authTag);
52
+ let plaintext = decipher.update(ciphertext, "hex", "utf-8");
53
+ plaintext += decipher.final("utf-8");
54
+ return plaintext;
55
+ }