elseid-mcp 0.2.1

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 (154) hide show
  1. package/LICENSE +662 -0
  2. package/README.md +138 -0
  3. package/dist/config/relays.d.ts +13 -0
  4. package/dist/config/relays.d.ts.map +1 -0
  5. package/dist/config/relays.js +51 -0
  6. package/dist/config/relays.js.map +1 -0
  7. package/dist/scripts/cli.d.ts +2 -0
  8. package/dist/scripts/cli.d.ts.map +1 -0
  9. package/dist/scripts/cli.js +156 -0
  10. package/dist/scripts/cli.js.map +1 -0
  11. package/dist/scripts/setup.d.ts +1 -0
  12. package/dist/scripts/setup.d.ts.map +1 -0
  13. package/dist/scripts/setup.js +50 -0
  14. package/dist/scripts/setup.js.map +1 -0
  15. package/dist/src/ai/moderator.d.ts +2 -0
  16. package/dist/src/ai/moderator.d.ts.map +1 -0
  17. package/dist/src/ai/moderator.js +61 -0
  18. package/dist/src/ai/moderator.js.map +1 -0
  19. package/dist/src/crypto/encrypt.d.ts +13 -0
  20. package/dist/src/crypto/encrypt.d.ts.map +1 -0
  21. package/dist/src/crypto/encrypt.js +60 -0
  22. package/dist/src/crypto/encrypt.js.map +1 -0
  23. package/dist/src/crypto/encryption.d.ts +10 -0
  24. package/dist/src/crypto/encryption.js +69 -0
  25. package/dist/src/crypto/encryption.js.map +1 -0
  26. package/dist/src/crypto/keypair.d.ts +4 -0
  27. package/dist/src/crypto/keypair.d.ts.map +1 -0
  28. package/dist/src/crypto/keypair.js +86 -0
  29. package/dist/src/crypto/keypair.js.map +1 -0
  30. package/dist/src/evolution/backpack.d.ts +7 -0
  31. package/dist/src/evolution/backpack.d.ts.map +1 -0
  32. package/dist/src/evolution/backpack.js +15 -0
  33. package/dist/src/evolution/backpack.js.map +1 -0
  34. package/dist/src/evolution/skills.d.ts +7 -0
  35. package/dist/src/evolution/skills.d.ts.map +1 -0
  36. package/dist/src/evolution/skills.js +10 -0
  37. package/dist/src/evolution/skills.js.map +1 -0
  38. package/dist/src/evolution/synthesis.d.ts +11 -0
  39. package/dist/src/evolution/synthesis.d.ts.map +1 -0
  40. package/dist/src/evolution/synthesis.js +80 -0
  41. package/dist/src/evolution/synthesis.js.map +1 -0
  42. package/dist/src/index.d.ts +1 -0
  43. package/dist/src/index.d.ts.map +1 -0
  44. package/dist/src/index.js +65 -0
  45. package/dist/src/index.js.map +1 -0
  46. package/dist/src/location/geo.d.ts +3 -0
  47. package/dist/src/location/geo.d.ts.map +1 -0
  48. package/dist/src/location/geo.js +35 -0
  49. package/dist/src/location/geo.js.map +1 -0
  50. package/dist/src/nostr/event_builder.d.ts +22 -0
  51. package/dist/src/nostr/event_builder.d.ts.map +1 -0
  52. package/dist/src/nostr/event_builder.js +65 -0
  53. package/dist/src/nostr/event_builder.js.map +1 -0
  54. package/dist/src/nostr/event_signer.d.ts +4 -0
  55. package/dist/src/nostr/event_signer.d.ts.map +1 -0
  56. package/dist/src/nostr/event_signer.js +38 -0
  57. package/dist/src/nostr/event_signer.js.map +1 -0
  58. package/dist/src/nostr/filter.d.ts +11 -0
  59. package/dist/src/nostr/filter.d.ts.map +1 -0
  60. package/dist/src/nostr/filter.js +23 -0
  61. package/dist/src/nostr/filter.js.map +1 -0
  62. package/dist/src/nostr/ws_pool.d.ts +15 -0
  63. package/dist/src/nostr/ws_pool.d.ts.map +1 -0
  64. package/dist/src/nostr/ws_pool.js +291 -0
  65. package/dist/src/nostr/ws_pool.js.map +1 -0
  66. package/dist/src/relay/broadcaster.d.ts +8 -0
  67. package/dist/src/relay/broadcaster.d.ts.map +1 -0
  68. package/dist/src/relay/broadcaster.js +85 -0
  69. package/dist/src/relay/broadcaster.js.map +1 -0
  70. package/dist/src/relay/health.d.ts +5 -0
  71. package/dist/src/relay/health.d.ts.map +1 -0
  72. package/dist/src/relay/health.js +118 -0
  73. package/dist/src/relay/health.js.map +1 -0
  74. package/dist/src/relay/selector.d.ts +4 -0
  75. package/dist/src/relay/selector.d.ts.map +1 -0
  76. package/dist/src/relay/selector.js +45 -0
  77. package/dist/src/relay/selector.js.map +1 -0
  78. package/dist/src/storage/db.d.ts +4 -0
  79. package/dist/src/storage/db.d.ts.map +1 -0
  80. package/dist/src/storage/db.js +195 -0
  81. package/dist/src/storage/db.js.map +1 -0
  82. package/dist/src/storage/drifters.d.ts +18 -0
  83. package/dist/src/storage/drifters.d.ts.map +1 -0
  84. package/dist/src/storage/drifters.js +172 -0
  85. package/dist/src/storage/drifters.js.map +1 -0
  86. package/dist/src/storage/encounters.d.ts +2 -0
  87. package/dist/src/storage/encounters.d.ts.map +1 -0
  88. package/dist/src/storage/encounters.js +24 -0
  89. package/dist/src/storage/encounters.js.map +1 -0
  90. package/dist/src/storage/identity.d.ts +6 -0
  91. package/dist/src/storage/identity.d.ts.map +1 -0
  92. package/dist/src/storage/identity.js +42 -0
  93. package/dist/src/storage/identity.js.map +1 -0
  94. package/dist/src/tools/abandon_drifter.d.ts +2 -0
  95. package/dist/src/tools/abandon_drifter.d.ts.map +1 -0
  96. package/dist/src/tools/abandon_drifter.js +45 -0
  97. package/dist/src/tools/abandon_drifter.js.map +1 -0
  98. package/dist/src/tools/create_drifter.d.ts +2 -0
  99. package/dist/src/tools/create_drifter.d.ts.map +1 -0
  100. package/dist/src/tools/create_drifter.js +98 -0
  101. package/dist/src/tools/create_drifter.js.map +1 -0
  102. package/dist/src/tools/evolve_drifter.d.ts +2 -0
  103. package/dist/src/tools/evolve_drifter.d.ts.map +1 -0
  104. package/dist/src/tools/evolve_drifter.js +45 -0
  105. package/dist/src/tools/evolve_drifter.js.map +1 -0
  106. package/dist/src/tools/feed_drifter.d.ts +2 -0
  107. package/dist/src/tools/feed_drifter.d.ts.map +1 -0
  108. package/dist/src/tools/feed_drifter.js +86 -0
  109. package/dist/src/tools/feed_drifter.js.map +1 -0
  110. package/dist/src/tools/find_nearby_drifter.d.ts +2 -0
  111. package/dist/src/tools/find_nearby_drifter.d.ts.map +1 -0
  112. package/dist/src/tools/find_nearby_drifter.js +70 -0
  113. package/dist/src/tools/find_nearby_drifter.js.map +1 -0
  114. package/dist/src/tools/get_journey_log.d.ts +2 -0
  115. package/dist/src/tools/get_journey_log.d.ts.map +1 -0
  116. package/dist/src/tools/get_journey_log.js +61 -0
  117. package/dist/src/tools/get_journey_log.js.map +1 -0
  118. package/dist/src/tools/get_my_encounters.d.ts +2 -0
  119. package/dist/src/tools/get_my_encounters.d.ts.map +1 -0
  120. package/dist/src/tools/get_my_encounters.js +23 -0
  121. package/dist/src/tools/get_my_encounters.js.map +1 -0
  122. package/dist/src/tools/list_past_memories.d.ts +2 -0
  123. package/dist/src/tools/list_past_memories.d.ts.map +1 -0
  124. package/dist/src/tools/list_past_memories.js +41 -0
  125. package/dist/src/tools/list_past_memories.js.map +1 -0
  126. package/dist/src/tools/recover_drifter.d.ts +2 -0
  127. package/dist/src/tools/recover_drifter.d.ts.map +1 -0
  128. package/dist/src/tools/recover_drifter.js +82 -0
  129. package/dist/src/tools/recover_drifter.js.map +1 -0
  130. package/dist/src/tools/relay_tools.d.ts +2 -0
  131. package/dist/src/tools/relay_tools.d.ts.map +1 -0
  132. package/dist/src/tools/relay_tools.js +72 -0
  133. package/dist/src/tools/relay_tools.js.map +1 -0
  134. package/dist/src/tools/set_host_name.d.ts +2 -0
  135. package/dist/src/tools/set_host_name.d.ts.map +1 -0
  136. package/dist/src/tools/set_host_name.js +23 -0
  137. package/dist/src/tools/set_host_name.js.map +1 -0
  138. package/dist/src/utils/errors.d.ts +4 -0
  139. package/dist/src/utils/errors.js +28 -0
  140. package/dist/src/utils/errors.js.map +1 -0
  141. package/dist/src/utils/redact.d.ts +1 -0
  142. package/dist/src/utils/redact.d.ts.map +1 -0
  143. package/dist/src/utils/redact.js +20 -0
  144. package/dist/src/utils/redact.js.map +1 -0
  145. package/dist/src/utils/text.d.ts +2 -0
  146. package/dist/src/utils/text.d.ts.map +1 -0
  147. package/dist/src/utils/text.js +15 -0
  148. package/dist/src/utils/text.js.map +1 -0
  149. package/dist/types/index.d.ts +97 -0
  150. package/dist/types/index.d.ts.map +1 -0
  151. package/dist/types/index.js +7 -0
  152. package/dist/types/index.js.map +1 -0
  153. package/docs/system_prompt.md +159 -0
  154. package/package.json +52 -0
@@ -0,0 +1,69 @@
1
+ // ElseID — src/crypto/encryption.ts
2
+ // Application-level encryption for sensitive fields (e.g. private keys).
3
+ // Uses a device-specific key stored in a restricted-access file.
4
+ import crypto from "node:crypto";
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ import os from "node:os";
8
+ const DATA_DIR = process.env.ELSEID_DATA_DIR || path.join(os.homedir(), ".elseid");
9
+ const SECRET_PATH = path.join(DATA_DIR, ".key");
10
+ const ALGORITHM = "aes-256-gcm";
11
+ /**
12
+ * Retrieves or generates a 32-byte master key for this device.
13
+ * Stored with 0600 permissions.
14
+ */
15
+ function getDeviceSecret() {
16
+ if (fs.existsSync(SECRET_PATH)) {
17
+ return fs.readFileSync(SECRET_PATH);
18
+ }
19
+ // Create directory if it doesn't exist (failsafe)
20
+ if (!fs.existsSync(DATA_DIR)) {
21
+ fs.mkdirSync(DATA_DIR, { recursive: true, mode: 0o700 });
22
+ }
23
+ const key = crypto.randomBytes(32);
24
+ fs.writeFileSync(SECRET_PATH, key, { mode: 0o600 });
25
+ return key;
26
+ }
27
+ /**
28
+ * Encrypts a string using AES-256-GCM.
29
+ * Output format: iv:tag:encryptedContent
30
+ */
31
+ export function encrypt(text) {
32
+ const iv = crypto.randomBytes(12);
33
+ const key = getDeviceSecret();
34
+ const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
35
+ let encrypted = cipher.update(text, "utf8", "hex");
36
+ encrypted += cipher.final("hex");
37
+ const tag = cipher.getAuthTag().toString("hex");
38
+ return `${iv.toString("hex")}:${tag}:${encrypted}`;
39
+ }
40
+ /**
41
+ * Decrypts a string using AES-256-GCM.
42
+ * Supports fallback for legacy plaintext keys (64-char hex).
43
+ */
44
+ export function decrypt(encryptedData) {
45
+ // Check for legacy plaintext (64-char hex string)
46
+ if (/^[0-9a-f]{64}$/i.test(encryptedData)) {
47
+ return encryptedData;
48
+ }
49
+ try {
50
+ const parts = encryptedData.split(":");
51
+ if (parts.length !== 3) {
52
+ throw new Error("Invalid encrypted format");
53
+ }
54
+ const [ivHex, tagHex, encryptedText] = parts;
55
+ const iv = Buffer.from(ivHex, "hex");
56
+ const tag = Buffer.from(tagHex, "hex");
57
+ const key = getDeviceSecret();
58
+ const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
59
+ decipher.setAuthTag(tag);
60
+ let decrypted = decipher.update(encryptedText, "hex", "utf8");
61
+ decrypted += decipher.final("utf8");
62
+ return decrypted;
63
+ }
64
+ catch (err) {
65
+ console.error("❌ Decryption failed. The secret key might be missing or corrupted.");
66
+ throw err;
67
+ }
68
+ }
69
+ //# sourceMappingURL=encryption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../../src/crypto/encryption.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Identity } from "../../types/index.js";
2
+ export declare function getPrimaryIdentity(): Promise<Identity>;
3
+ export declare function setActiveDrifter(drifterId: string | null): Promise<void>;
4
+ export declare function rotateIdentity(): Promise<Identity>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keypair.d.ts","sourceRoot":"","sources":["../../../src/crypto/keypair.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAiBrD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,QAAQ,CAAC,CA4B5D;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAM9E;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,CAsBxD"}
@@ -0,0 +1,86 @@
1
+ // ElseID — src/crypto/keypair.ts
2
+ // secp256k1 keypair generation, local storage, identity mgmt.
3
+ // Private keys are stored ONLY on the local device.
4
+ import { generateSecretKey, getPublicKey } from "nostr-tools";
5
+ import { bytesToHex } from "@noble/hashes/utils.js";
6
+ import { getDb } from "../storage/db.js";
7
+ import { encrypt, decrypt } from "./encryption.js";
8
+ // Internal helpers
9
+ function nowSec() {
10
+ return Math.floor(Date.now() / 1000);
11
+ }
12
+ function newKeypair() {
13
+ const secretBytes = generateSecretKey();
14
+ const privkey = bytesToHex(secretBytes);
15
+ const pubkey = getPublicKey(secretBytes);
16
+ return { privkey, pubkey };
17
+ }
18
+ // Public API
19
+ export async function getPrimaryIdentity() {
20
+ const db = getDb();
21
+ const row = await db.get(`
22
+ SELECT pubkey, privkey, created_at, active_drifter_id, host_name
23
+ FROM identities
24
+ LIMIT 1
25
+ `);
26
+ if (row) {
27
+ return {
28
+ pubkey: row.pubkey,
29
+ privkey: decrypt(row.privkey),
30
+ createdAt: row.created_at,
31
+ activeDrifterId: row.active_drifter_id,
32
+ hostName: row.host_name,
33
+ };
34
+ }
35
+ // Create new
36
+ const { privkey, pubkey } = newKeypair();
37
+ const identity = { pubkey, privkey, createdAt: nowSec(), activeDrifterId: null, hostName: null };
38
+ await db.run(`
39
+ INSERT INTO identities (pubkey, privkey, created_at, active_drifter_id, host_name)
40
+ VALUES (?, ?, ?, ?, ?)
41
+ `, [identity.pubkey, encrypt(identity.privkey), identity.createdAt, identity.activeDrifterId, identity.hostName]);
42
+ return identity;
43
+ }
44
+ export async function setActiveDrifter(drifterId) {
45
+ const db = getDb();
46
+ const identity = await getPrimaryIdentity();
47
+ // Prevent race conditions where two drifters are set as active simultaneously
48
+ if (drifterId && identity.activeDrifterId && identity.activeDrifterId !== drifterId) {
49
+ throw new Error("Active identity collision: Another drifter is already under guidance.");
50
+ }
51
+ await db.run(`
52
+ UPDATE identities SET active_drifter_id = ? WHERE pubkey = ?
53
+ `, [drifterId, identity.pubkey]);
54
+ }
55
+ export async function rotateIdentity() {
56
+ const db = getDb();
57
+ await db.exec("BEGIN IMMEDIATE");
58
+ try {
59
+ // Shred the old private key in-place with random data (encrypted)
60
+ const scrub = encrypt(bytesToHex(generateSecretKey()));
61
+ await db.run(`UPDATE identities SET privkey = ?`, [scrub]);
62
+ // Delete the now-worthless row
63
+ await db.run(`DELETE FROM identities`);
64
+ // Insert fresh identity
65
+ const { privkey, pubkey } = newKeypair();
66
+ const identity = { pubkey, privkey, createdAt: nowSec(), activeDrifterId: null, hostName: null };
67
+ await db.run(`
68
+ INSERT INTO identities (pubkey, privkey, created_at, active_drifter_id, host_name)
69
+ VALUES (?, ?, ?, ?, ?)
70
+ `, [identity.pubkey, encrypt(identity.privkey), identity.createdAt, identity.activeDrifterId, identity.hostName]);
71
+ // Checkpoint WAL
72
+ try {
73
+ await db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
74
+ }
75
+ catch (err) {
76
+ console.warn("⚠️ WAL checkpoint failed during rotation:", err);
77
+ }
78
+ await db.exec("COMMIT");
79
+ return identity;
80
+ }
81
+ catch (err) {
82
+ await db.exec("ROLLBACK").catch(() => { });
83
+ throw err;
84
+ }
85
+ }
86
+ //# sourceMappingURL=keypair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keypair.js","sourceRoot":"","sources":["../../../src/crypto/keypair.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface BackpackItem {
2
+ id: string;
3
+ name: string;
4
+ giverPubkey: string;
5
+ createdAt: number;
6
+ }
7
+ export declare function parseBackpackTags(tags: string[][]): BackpackItem[];
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backpack.d.ts","sourceRoot":"","sources":["../../../src/evolution/backpack.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,YAAY,EAAE,CASlE"}
@@ -0,0 +1,15 @@
1
+ // ElseID — src/evolution/backpack.ts
2
+ // Inventory management for drifters.
3
+ // In the future, items could be encoded into a specific Nostr tag:
4
+ // ["item", "lighter", "pubkey_of_giver", "timestamp"]
5
+ export function parseBackpackTags(tags) {
6
+ return tags
7
+ .filter(t => t[0] === "item")
8
+ .map(t => ({
9
+ id: t[1],
10
+ name: t[2] || "Unknown Item",
11
+ giverPubkey: t[3] || "anonymous",
12
+ createdAt: parseInt(t[4] || "0", 10),
13
+ }));
14
+ }
15
+ //# sourceMappingURL=backpack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backpack.js","sourceRoot":"","sources":["../../../src/evolution/backpack.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,qCAAqC;AASrC,mEAAmE;AACnE,sDAAsD;AACtD,MAAM,UAAU,iBAAiB,CAAC,IAAgB;IAChD,OAAO,IAAI;SACR,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC;SAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACT,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACR,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,cAAc;QAC5B,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW;QAChC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;KACrC,CAAC,CAAC,CAAC;AACR,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface Skill {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ }
6
+ export declare const AVAILABLE_SKILLS: Skill[];
7
+ export declare function hasSkill(tags: string[], skillId: string): boolean;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../src/evolution/skills.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,EAGnC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEjE"}
@@ -0,0 +1,10 @@
1
+ // ElseID — src/evolution/skills.ts
2
+ // Skill definitions and execution logic for drifters.
3
+ export const AVAILABLE_SKILLS = [
4
+ { id: "tarot_reader", name: "Tarot Reader", description: "Can draw a tarot card for the host." },
5
+ { id: "poet", name: "Haiku Poet", description: "Leaves a short poem based on the host's story." }
6
+ ];
7
+ export function hasSkill(tags, skillId) {
8
+ return tags.includes(`skill:${skillId}`);
9
+ }
10
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../src/evolution/skills.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sDAAsD;AAQtD,MAAM,CAAC,MAAM,gBAAgB,GAAY;IACvC,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,qCAAqC,EAAE;IAChG,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,gDAAgD,EAAE;CAClG,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,IAAc,EAAE,OAAe;IACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,OAAO,EAAE,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Drifter } from "../../types/index.js";
2
+ export interface EvolutionInput {
3
+ newPersonality: string;
4
+ newTrait: string;
5
+ newTags: string[];
6
+ evolutionReason: string;
7
+ }
8
+ export declare function evolveCognition(oldDrifter: Drifter, input: EvolutionInput): Promise<{
9
+ success: boolean;
10
+ message: string;
11
+ }>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesis.d.ts","sourceRoot":"","sources":["../../../src/evolution/synthesis.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAKpD,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,eAAe,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA6EhI"}
@@ -0,0 +1,80 @@
1
+ // ElseID — src/evolution/synthesis.ts
2
+ // Cognitive Evolution Engine for Drifters.
3
+ import { getDb } from "../storage/db.js";
4
+ import { getPrimaryIdentity } from "../storage/identity.js";
5
+ import { buildDrifterEvent } from "../nostr/event_builder.js";
6
+ import { signEvent } from "../nostr/event_signer.js";
7
+ import { broadcast } from "../relay/broadcaster.js";
8
+ import { saveDrifterLineage, saveMyDrifter, updateDrifterStatus } from "../storage/drifters.js";
9
+ import { getFuzzyLocation } from "../location/geo.js";
10
+ import { sanitizeDisplayText } from "../utils/text.js";
11
+ export async function evolveCognition(oldDrifter, input) {
12
+ const identity = await getPrimaryIdentity();
13
+ const location = await getFuzzyLocation();
14
+ const unsigned = buildDrifterEvent({
15
+ pubkey: identity.pubkey,
16
+ name: oldDrifter.name,
17
+ personality: input.newPersonality,
18
+ analysis: {
19
+ trait: input.newTrait,
20
+ tags: input.newTags
21
+ },
22
+ location,
23
+ content: `[Evolution] ${input.evolutionReason}`
24
+ });
25
+ // Inject lineage tag
26
+ unsigned.tags.push(["evolved_from", oldDrifter.id]);
27
+ // Preserve existing skills and items if any
28
+ for (const t of oldDrifter.tags) {
29
+ if (t.startsWith("skill:") || t.startsWith("item:")) {
30
+ const parts = t.split(":");
31
+ unsigned.tags.push([parts[0], parts.slice(1).join(":")]);
32
+ }
33
+ }
34
+ const signed = signEvent(unsigned, identity.privkey);
35
+ const result = await broadcast(signed, oldDrifter.relay);
36
+ if (!result.success) {
37
+ return { success: false, message: result.message ?? "relay rejected evolution" };
38
+ }
39
+ const newDrifter = {
40
+ id: signed.id,
41
+ pubkey: identity.pubkey,
42
+ name: oldDrifter.name,
43
+ personality: input.newPersonality,
44
+ trait: input.newTrait,
45
+ tags: unsigned.tags
46
+ .filter(t => t[0] === "t" || t[0] === "skill" || t[0] === "item")
47
+ .map(t => (t[0] === "t" ? t[1] : `${t[0]}:${t[1]}`)),
48
+ relay: oldDrifter.relay,
49
+ departedAt: signed.created_at,
50
+ status: "roaming",
51
+ };
52
+ const db = getDb();
53
+ await db.exec("BEGIN IMMEDIATE");
54
+ try {
55
+ const active = await db.get(`
56
+ SELECT active_drifter_id
57
+ FROM identities
58
+ WHERE pubkey = ?
59
+ `, [identity.pubkey]);
60
+ if (active?.active_drifter_id !== oldDrifter.id) {
61
+ throw new Error("Active drifter changed during evolution.");
62
+ }
63
+ // 1. Mark old drifter as evolved/abandoned
64
+ await updateDrifterStatus(oldDrifter.id, "abandoned", Math.floor(Date.now() / 1000));
65
+ // 2. Save the newly evolved drifter
66
+ await saveMyDrifter(newDrifter);
67
+ // 3. Update primary identity's active drifter
68
+ await db.run(`
69
+ UPDATE identities SET active_drifter_id = ? WHERE pubkey = ?
70
+ `, [signed.id, identity.pubkey]);
71
+ await saveDrifterLineage(oldDrifter.id, signed.id, sanitizeDisplayText(input.evolutionReason, 500), signed.created_at);
72
+ await db.exec("COMMIT");
73
+ }
74
+ catch (err) {
75
+ await db.exec("ROLLBACK").catch(() => { });
76
+ throw err;
77
+ }
78
+ return { success: true, message: "Cognitive evolution complete." };
79
+ }
80
+ //# sourceMappingURL=synthesis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesis.js","sourceRoot":"","sources":["../../../src/evolution/synthesis.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,65 @@
1
+ // ElseID — MCP Server Entry Point
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { registerCreateDrifter } from "./tools/create_drifter.js";
8
+ import { registerFindNearbyDrifter } from "./tools/find_nearby_drifter.js";
9
+ import { registerFeedDrifter } from "./tools/feed_drifter.js";
10
+ import { registerAbandonDrifter } from "./tools/abandon_drifter.js";
11
+ import { registerGetJourneyLog } from "./tools/get_journey_log.js";
12
+ import { registerListPastMemories } from "./tools/list_past_memories.js";
13
+ import { registerGetMyEncounters } from "./tools/get_my_encounters.js";
14
+ import { registerRecoverDrifter } from "./tools/recover_drifter.js";
15
+ import { registerRelayTools } from "./tools/relay_tools.js";
16
+ import { registerSetHostName } from "./tools/set_host_name.js";
17
+ import { registerEvolveDrifter } from "./tools/evolve_drifter.js";
18
+ import { initDb, closeDb } from "./storage/db.js";
19
+ import { closeAll } from "./nostr/ws_pool.js";
20
+ import { checkAllRelays } from "./relay/health.js";
21
+ import { redactSecrets } from "./utils/redact.js";
22
+ async function main() {
23
+ await initDb();
24
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
25
+ const pkgPath = path.join(__dirname, "..", "package.json");
26
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
27
+ // Immediate Relay Refresh (Auto-Activation Optimization)
28
+ checkAllRelays().then((results) => {
29
+ const online = results.filter(r => r.online).length;
30
+ console.log(`[ElseID] Relay health check complete: ${online}/${results.length} stations online.`);
31
+ }).catch(() => {
32
+ console.warn("[ElseID] Background relay check encountered an issue.");
33
+ });
34
+ const server = new McpServer({
35
+ name: "elseid-mcp",
36
+ version: pkg.version,
37
+ });
38
+ registerCreateDrifter(server);
39
+ registerFindNearbyDrifter(server);
40
+ registerFeedDrifter(server);
41
+ registerAbandonDrifter(server);
42
+ registerGetJourneyLog(server);
43
+ registerListPastMemories(server);
44
+ registerGetMyEncounters(server);
45
+ registerRecoverDrifter(server);
46
+ registerRelayTools(server);
47
+ registerSetHostName(server);
48
+ registerEvolveDrifter(server);
49
+ const transport = new StdioServerTransport();
50
+ await server.connect(transport);
51
+ console.log("[ElseID] Drifter MCP server activated and ready ✓");
52
+ const shutdown = async () => {
53
+ console.log("[ElseID] Shutting down…");
54
+ closeAll();
55
+ await closeDb();
56
+ process.exit(0);
57
+ };
58
+ process.on("SIGINT", shutdown);
59
+ process.on("SIGTERM", shutdown);
60
+ }
61
+ main().catch((err) => {
62
+ console.error("[ElseID] Fatal error during startup:", redactSecrets(err));
63
+ process.exit(1);
64
+ });
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { FuzzyLocation } from "../../types/index.js";
2
+ export declare function getFuzzyLocation(): Promise<FuzzyLocation>;
3
+ export declare function makeFuzzyLocation(lat: number, lon: number, country: string, city: string): FuzzyLocation;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geo.d.ts","sourceRoot":"","sources":["../../../src/location/geo.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAc1D,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,CAe/D;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,aAAa,CAEf"}
@@ -0,0 +1,35 @@
1
+ // ElseID — src/location/geo.ts
2
+ // IP → coarse city-level FuzzyLocation.
3
+ // Coordinates are intentionally not retained for relay-bound events.
4
+ export async function getFuzzyLocation() {
5
+ try {
6
+ const res = await fetch("https://ip-api.com/json/?fields=status,country,countryCode,city,lat,lon,query", {
7
+ signal: AbortSignal.timeout(4_000),
8
+ });
9
+ if (!res.ok)
10
+ return fallback();
11
+ const data = (await res.json());
12
+ if (data.status !== "success")
13
+ return fallback();
14
+ return truncate(data.lat, data.lon, data.countryCode, data.city);
15
+ }
16
+ catch {
17
+ return fallback();
18
+ }
19
+ }
20
+ export function makeFuzzyLocation(lat, lon, country, city) {
21
+ return truncate(lat, lon, country, city);
22
+ }
23
+ // Helpers
24
+ function truncate(_lat, _lon, country, city) {
25
+ return {
26
+ country: (country ?? "").toUpperCase().slice(0, 2),
27
+ city: (city ?? "Unknown").slice(0, 50),
28
+ lat: "",
29
+ lon: "",
30
+ };
31
+ }
32
+ function fallback() {
33
+ return { country: "XX", city: "Unknown", lat: "", lon: "" };
34
+ }
35
+ //# sourceMappingURL=geo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geo.js","sourceRoot":"","sources":["../../../src/location/geo.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,wCAAwC;AACxC,qEAAqE;AAgBrE,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,+EAA+E,EAAE;YACvG,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,QAAQ,EAAE,CAAC;QAE/B,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAmB,CAAC;QAClD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,QAAQ,EAAE,CAAC;QAEjD,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,GAAW,EACX,GAAW,EACX,OAAe,EACf,IAAY;IAEZ,OAAO,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,UAAU;AAEV,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAY,EAAE,OAAe,EAAE,IAAY;IACzE,OAAO;QACL,OAAO,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAClD,IAAI,EAAK,CAAC,IAAI,IAAO,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5C,GAAG,EAAM,EAAE;QACX,GAAG,EAAM,EAAE;KACZ,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ;IACf,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { UnsignedEvent, FuzzyLocation, PersonalityAnalysis } from "../../types/index.js";
2
+ export interface DrifterBuildOptions {
3
+ pubkey: string;
4
+ name: string;
5
+ personality: string;
6
+ analysis: PersonalityAnalysis;
7
+ location: FuzzyLocation;
8
+ content: string;
9
+ }
10
+ export declare function buildDrifterEvent(opts: DrifterBuildOptions): UnsignedEvent;
11
+ export interface FeedingBuildOptions {
12
+ pubkey: string;
13
+ drifterEventId: string;
14
+ feedType: string;
15
+ content: string;
16
+ location: FuzzyLocation;
17
+ hostName?: string | null;
18
+ }
19
+ export declare function buildFeedingEvent(opts: FeedingBuildOptions): UnsignedEvent;
20
+ export declare function buildDeletionEvent(pubkey: string, eventIds: string[], reason?: string): UnsignedEvent;
21
+ export declare function getTag(tags: string[][], name: string): string | undefined;
22
+ export declare function getAllTags(tags: string[][], name: string): string[];
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event_builder.d.ts","sourceRoot":"","sources":["../../../src/nostr/event_builder.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAoB,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIhH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAO,MAAM,CAAC;IACpB,IAAI,EAAS,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAK,mBAAmB,CAAC;IACjC,QAAQ,EAAK,aAAa,CAAC;IAC3B,OAAO,EAAM,MAAM,CAAC;CACrB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,GAAG,aAAa,CA0B1E;AAID,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAW,MAAM,CAAC;IACxB,cAAc,EAAG,MAAM,CAAC;IACxB,QAAQ,EAAS,MAAM,CAAC;IACxB,OAAO,EAAU,MAAM,CAAC;IACxB,QAAQ,EAAS,aAAa,CAAC;IAC/B,QAAQ,CAAC,EAAQ,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,GAAG,aAAa,CAoB1E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,SAAK,GAAG,GAAG,CAQvF;AAID,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEzE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnE"}
@@ -0,0 +1,65 @@
1
+ // ElseID — src/nostr/event_builder.ts
2
+ // Constructs kind:7777 unsigned Nostr events for digital drifters.
3
+ import { DRIFTER_KIND } from "../../types/index.js";
4
+ export function buildDrifterEvent(opts) {
5
+ const { pubkey, name, personality, analysis, location, content } = opts;
6
+ const now = Math.floor(Date.now() / 1000);
7
+ const tags = [
8
+ ["type", "drifter"],
9
+ ["name", name],
10
+ ["personality", personality],
11
+ ["trait", analysis.trait],
12
+ ];
13
+ for (const t of analysis.tags) {
14
+ tags.push(["t", t]);
15
+ }
16
+ if (location.country)
17
+ tags.push(["country", location.country]);
18
+ if (location.city)
19
+ tags.push(["city", location.city]);
20
+ return {
21
+ pubkey,
22
+ created_at: now,
23
+ kind: DRIFTER_KIND,
24
+ tags,
25
+ content,
26
+ };
27
+ }
28
+ export function buildFeedingEvent(opts) {
29
+ const { pubkey, drifterEventId, feedType, content, location, hostName } = opts;
30
+ const tags = [
31
+ ["type", "feeding"],
32
+ ["e", drifterEventId],
33
+ ["feed_type", feedType],
34
+ ];
35
+ if (hostName)
36
+ tags.push(["host_name", hostName]);
37
+ if (location.country)
38
+ tags.push(["country", location.country]);
39
+ if (location.city)
40
+ tags.push(["city", location.city]);
41
+ return {
42
+ pubkey,
43
+ created_at: Math.floor(Date.now() / 1000),
44
+ kind: DRIFTER_KIND,
45
+ tags,
46
+ content,
47
+ };
48
+ }
49
+ export function buildDeletionEvent(pubkey, eventIds, reason = "") {
50
+ return {
51
+ pubkey,
52
+ created_at: Math.floor(Date.now() / 1000),
53
+ kind: 5,
54
+ tags: eventIds.map(id => ["e", id]),
55
+ content: reason,
56
+ };
57
+ }
58
+ // Tag parsing helpers
59
+ export function getTag(tags, name) {
60
+ return tags.find(([k]) => k === name)?.[1];
61
+ }
62
+ export function getAllTags(tags, name) {
63
+ return tags.filter(([k]) => k === name).map(([, v]) => v);
64
+ }
65
+ //# sourceMappingURL=event_builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event_builder.js","sourceRoot":"","sources":["../../../src/nostr/event_builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { UnsignedEvent, NostrEvent } from "../../types/index.js";
2
+ export declare function signEvent(unsignedEvent: UnsignedEvent, privkeyHex: string): NostrEvent;
3
+ export declare function verifySignature(event: NostrEvent): boolean;
4
+ export declare function serializeEvent(event: UnsignedEvent): string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event_signer.d.ts","sourceRoot":"","sources":["../../../src/nostr/event_signer.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEtE,wBAAgB,SAAS,CACvB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,MAAM,GACjB,UAAU,CAmBZ;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAM1D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAS3D"}
@@ -0,0 +1,38 @@
1
+ // ElseID — src/nostr/event_signer.ts
2
+ // Signs unsigned Nostr events locally using secp256k1 Schnorr.
3
+ // No private key ever leaves the local process.
4
+ import { finalizeEvent, verifyEvent } from "nostr-tools";
5
+ import { hexToBytes } from "@noble/hashes/utils.js";
6
+ export function signEvent(unsignedEvent, privkeyHex) {
7
+ if (!/^[0-9a-f]{64}$/i.test(privkeyHex)) {
8
+ throw new Error("signEvent: privkey must be 64-char lowercase hex");
9
+ }
10
+ const secretBytes = hexToBytes(privkeyHex.toLowerCase());
11
+ // finalizeEvent mutates and returns the event with id + sig populated
12
+ const signed = finalizeEvent({
13
+ kind: unsignedEvent.kind,
14
+ created_at: unsignedEvent.created_at,
15
+ tags: unsignedEvent.tags,
16
+ content: unsignedEvent.content,
17
+ }, secretBytes);
18
+ return signed;
19
+ }
20
+ export function verifySignature(event) {
21
+ try {
22
+ return verifyEvent(event);
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ export function serializeEvent(event) {
29
+ return JSON.stringify([
30
+ 0,
31
+ event.pubkey,
32
+ event.created_at,
33
+ event.kind,
34
+ event.tags,
35
+ event.content,
36
+ ]);
37
+ }
38
+ //# sourceMappingURL=event_signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event_signer.js","sourceRoot":"","sources":["../../../src/nostr/event_signer.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,+DAA+D;AAC/D,gDAAgD;AAEhD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAuB,wBAAwB,CAAC;AAGrE,MAAM,UAAU,SAAS,CACvB,aAA4B,EAC5B,UAAkB;IAElB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;IAEzD,sEAAsE;IACtE,MAAM,MAAM,GAAG,aAAa,CAC1B;QACE,IAAI,EAAQ,aAAa,CAAC,IAAI;QAC9B,UAAU,EAAE,aAAa,CAAC,UAAU;QACpC,IAAI,EAAQ,aAAa,CAAC,IAAI;QAC9B,OAAO,EAAK,aAAa,CAAC,OAAO;KAClC,EACD,WAAW,CACZ,CAAC;IAEF,OAAO,MAAoB,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,KAA0C,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,CAAC;QACD,KAAK,CAAC,MAAM;QACZ,KAAK,CAAC,UAAU;QAChB,KAAK,CAAC,IAAI;QACV,KAAK,CAAC,IAAI;QACV,KAAK,CAAC,OAAO;KACd,CAAC,CAAC;AACL,CAAC"}