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,45 @@
1
+ // ElseID — src/relay/selector.ts
2
+ // Geographic-prioritized relay selection strategy.
3
+ import { getHealthyRelays } from "./health.js";
4
+ import { DEFAULT_RELAYS } from "../../config/relays.js";
5
+ export async function pickRelayByGeo(location) {
6
+ const healthy = await getHealthyRelays();
7
+ const regionMatch = healthy.find(r => r.region === location.country);
8
+ if (regionMatch)
9
+ return regionMatch.url;
10
+ return await pickRelay();
11
+ }
12
+ export async function pickRelay(preferredUrl) {
13
+ const healthy = await getHealthyRelays();
14
+ if (preferredUrl) {
15
+ const match = healthy.find((r) => r.url === preferredUrl);
16
+ if (match)
17
+ return match.url;
18
+ }
19
+ if (healthy.length === 0) {
20
+ const fallback = DEFAULT_RELAYS.find((r) => r.writable);
21
+ return fallback?.url ?? DEFAULT_RELAYS[0].url;
22
+ }
23
+ const weighted = healthy.map((r) => ({
24
+ url: r.url,
25
+ weight: 1 / ((r.latencyMs ?? 500) + 100),
26
+ }));
27
+ const total = weighted.reduce((s, r) => s + r.weight, 0);
28
+ let rand = Math.random() * total;
29
+ for (const entry of weighted) {
30
+ rand -= entry.weight;
31
+ if (rand <= 0)
32
+ return entry.url;
33
+ }
34
+ return weighted[0].url;
35
+ }
36
+ export async function pickRelaysForFetch(location, count = 3) {
37
+ const healthy = await getHealthyRelays();
38
+ const sorted = [...healthy].sort((a, b) => {
39
+ const aMatch = a.region === location.country ? 0 : 1;
40
+ const bMatch = b.region === location.country ? 0 : 1;
41
+ return aMatch - bMatch;
42
+ });
43
+ return sorted.map(r => r.url).slice(0, count);
44
+ }
45
+ //# sourceMappingURL=selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.js","sourceRoot":"","sources":["../../../src/relay/selector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Database } from "sqlite";
2
+ export declare function getDb(): Database;
3
+ export declare function initDb(): Promise<void>;
4
+ export declare function closeDb(): Promise<void>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/storage/db.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAmBxC,wBAAgB,KAAK,IAAI,QAAQ,CAGhC;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CA4G5C"}
@@ -0,0 +1,195 @@
1
+ // Local Storage — SQLite Initialization (Async Version)
2
+ import { open } from "sqlite";
3
+ import sqlite3 from "sqlite3";
4
+ import path from "path";
5
+ import os from "os";
6
+ import fs from "fs";
7
+ const DEFAULT_DATA_DIR = path.join(os.homedir(), ".elseid");
8
+ let DATA_DIR = process.env.ELSEID_DATA_DIR || DEFAULT_DATA_DIR;
9
+ // Path Traversal Mitigation: Ensure the data directory is absolute and not suspicious
10
+ if (process.env.ELSEID_DATA_DIR) {
11
+ DATA_DIR = path.resolve(process.env.ELSEID_DATA_DIR);
12
+ if (!path.isAbsolute(DATA_DIR) || DATA_DIR.includes("..")) {
13
+ console.error(`❌ Invalid ELSEID_DATA_DIR: ${process.env.ELSEID_DATA_DIR}. Falling back to default.`);
14
+ DATA_DIR = DEFAULT_DATA_DIR;
15
+ }
16
+ }
17
+ const DB_PATH = path.join(DATA_DIR, "elseid.db");
18
+ let _db = null;
19
+ export function getDb() {
20
+ if (!_db)
21
+ throw new Error("DB not initialized. Call initDb() first.");
22
+ return _db;
23
+ }
24
+ export async function initDb() {
25
+ // Ensure data directory exists with correct permissions (always chmod to be sure)
26
+ try {
27
+ if (!fs.existsSync(DATA_DIR)) {
28
+ fs.mkdirSync(DATA_DIR, { recursive: true, mode: 0o700 });
29
+ }
30
+ fs.chmodSync(DATA_DIR, 0o700);
31
+ }
32
+ catch (err) {
33
+ console.warn(`⚠️ Failed to set permissions on data directory ${DATA_DIR}:`, err);
34
+ }
35
+ // Use sqlite3.Database as the driver
36
+ _db = await open({
37
+ filename: DB_PATH,
38
+ driver: sqlite3.Database
39
+ });
40
+ // Ensure DB file has restricted permissions
41
+ try {
42
+ if (fs.existsSync(DB_PATH)) {
43
+ fs.chmodSync(DB_PATH, 0o600);
44
+ }
45
+ }
46
+ catch (err) {
47
+ console.warn(`⚠️ Failed to set permissions on database file ${DB_PATH}:`, err);
48
+ }
49
+ await _db.exec("PRAGMA journal_mode = WAL");
50
+ await _db.exec("PRAGMA foreign_keys = ON");
51
+ await _db.exec("PRAGMA secure_delete = ON");
52
+ await _db.exec(`
53
+ CREATE TABLE IF NOT EXISTS drifters (
54
+ id TEXT PRIMARY KEY, -- Nostr Event ID
55
+ pubkey TEXT NOT NULL, -- Owner's pubkey
56
+ name TEXT NOT NULL, -- Drifter name
57
+ personality TEXT NOT NULL, -- Personality description
58
+ trait TEXT, -- Extracted core trait
59
+ tags TEXT, -- JSON array
60
+ relay TEXT NOT NULL, -- Origin relay URL
61
+ departed_at INTEGER NOT NULL, -- Departure time
62
+ status TEXT DEFAULT 'roaming', -- roaming | resting | returned | abandoned
63
+ abandoned_at INTEGER, -- Retirement time
64
+ last_seen_at INTEGER, -- Last host time
65
+ last_seen_loc TEXT -- Last city
66
+ );
67
+
68
+ CREATE TABLE IF NOT EXISTS feedings (
69
+ id TEXT PRIMARY KEY,
70
+ drifter_id TEXT NOT NULL,
71
+ drifter_name TEXT,
72
+ feeder_pubkey TEXT NOT NULL,
73
+ feeder_name TEXT,
74
+ feed_type TEXT NOT NULL,
75
+ content TEXT NOT NULL,
76
+ location_country TEXT,
77
+ location_city TEXT,
78
+ fed_at INTEGER NOT NULL,
79
+ relay TEXT NOT NULL
80
+ );
81
+
82
+ CREATE TABLE IF NOT EXISTS hosting_log (
83
+ id TEXT PRIMARY KEY,
84
+ drifter_id TEXT NOT NULL,
85
+ feeder_pubkey TEXT NOT NULL,
86
+ feeder_name TEXT,
87
+ feed_type TEXT NOT NULL,
88
+ content TEXT NOT NULL,
89
+ location_country TEXT,
90
+ location_city TEXT,
91
+ fed_at INTEGER NOT NULL,
92
+ relay TEXT NOT NULL
93
+ );
94
+
95
+ CREATE TABLE IF NOT EXISTS identities (
96
+ pubkey TEXT PRIMARY KEY,
97
+ privkey TEXT NOT NULL,
98
+ created_at INTEGER NOT NULL,
99
+ active_drifter_id TEXT,
100
+ is_creating INTEGER DEFAULT 0,
101
+ creating_at INTEGER,
102
+ host_name TEXT
103
+ );
104
+
105
+ CREATE TABLE IF NOT EXISTS relay_stats (
106
+ url TEXT PRIMARY KEY,
107
+ online INTEGER DEFAULT 0,
108
+ latency_ms INTEGER,
109
+ writable INTEGER DEFAULT 1,
110
+ last_check INTEGER
111
+ );
112
+
113
+ CREATE TABLE IF NOT EXISTS encounters (
114
+ token TEXT PRIMARY KEY,
115
+ drifter_id TEXT NOT NULL,
116
+ relay TEXT NOT NULL,
117
+ discovered_at INTEGER NOT NULL,
118
+ expires_at INTEGER NOT NULL
119
+ );
120
+
121
+ CREATE TABLE IF NOT EXISTS drifter_lineage (
122
+ child_id TEXT PRIMARY KEY,
123
+ parent_id TEXT NOT NULL,
124
+ reason TEXT,
125
+ evolved_at INTEGER NOT NULL
126
+ );
127
+ `);
128
+ await _db.run(`UPDATE identities SET is_creating = 0`);
129
+ // Versioned Migrations
130
+ await runMigrations(_db);
131
+ }
132
+ async function runMigrations(db) {
133
+ await db.exec(`
134
+ CREATE TABLE IF NOT EXISTS _migrations (
135
+ version INTEGER PRIMARY KEY
136
+ )
137
+ `);
138
+ const row = await db.get("SELECT version FROM _migrations");
139
+ const currentVersion = row?.version ?? 0;
140
+ const migrations = [
141
+ // Version 1: Initial schema (handled by CREATE TABLE IF NOT EXISTS)
142
+ async () => { },
143
+ // Version 2: Add host_name and creating_at to identities
144
+ async (db) => {
145
+ const info = await db.all(`PRAGMA table_info(identities)`);
146
+ if (!info.some(c => c.name === "host_name")) {
147
+ await db.exec(`ALTER TABLE identities ADD COLUMN host_name TEXT`);
148
+ }
149
+ if (!info.some(c => c.name === "creating_at")) {
150
+ await db.exec(`ALTER TABLE identities ADD COLUMN creating_at INTEGER`);
151
+ }
152
+ },
153
+ // Version 3: Add drifter_name, feeder_name to feedings
154
+ async (db) => {
155
+ const info = await db.all(`PRAGMA table_info(feedings)`);
156
+ if (!info.some(c => c.name === "drifter_name")) {
157
+ await db.exec(`ALTER TABLE feedings ADD COLUMN drifter_name TEXT`);
158
+ }
159
+ if (!info.some(c => c.name === "feeder_name")) {
160
+ await db.exec(`ALTER TABLE feedings ADD COLUMN feeder_name TEXT`);
161
+ }
162
+ },
163
+ // Version 4: Add feeder_name to hosting_log
164
+ async (db) => {
165
+ const info = await db.all(`PRAGMA table_info(hosting_log)`);
166
+ if (!info.some(c => c.name === "feeder_name")) {
167
+ await db.exec(`ALTER TABLE hosting_log ADD COLUMN feeder_name TEXT`);
168
+ }
169
+ }
170
+ ];
171
+ for (let i = currentVersion; i < migrations.length; i++) {
172
+ const nextVersion = i + 1;
173
+ try {
174
+ await migrations[i](db);
175
+ await db.run("INSERT OR REPLACE INTO _migrations (version) VALUES (?)", [nextVersion]);
176
+ }
177
+ catch (err) {
178
+ console.error(`❌ Migration to version ${nextVersion} failed:`, err);
179
+ throw err; // Stop initialization if migration fails
180
+ }
181
+ }
182
+ }
183
+ export async function closeDb() {
184
+ if (_db) {
185
+ try {
186
+ await _db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
187
+ await _db.close();
188
+ _db = null;
189
+ }
190
+ catch (err) {
191
+ console.error("❌ Error closing database:", err);
192
+ }
193
+ }
194
+ }
195
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Drifter, Feeding, DrifterStatus } from "../../types/index.js";
2
+ export declare function saveMyDrifter(drifter: Drifter): Promise<void>;
3
+ export declare function updateDrifterStatus(id: string, status: DrifterStatus, abandonedAt?: number): Promise<void>;
4
+ export declare function updateDrifterPresence(id: string, location: string, timestamp: number): Promise<void>;
5
+ export declare function getDrifter(id: string): Promise<Drifter | null>;
6
+ export declare function getMyActiveDrifter(): Promise<Drifter | null>;
7
+ export declare function saveOutgoingFeeding(feeding: Feeding, drifterName?: string): Promise<void>;
8
+ export declare function hasHostedBefore(drifterId: string): Promise<boolean>;
9
+ export declare function saveIncomingFeeding(feeding: Feeding): Promise<void>;
10
+ export declare function getMyDrifterJourney(drifterId: string): Promise<Feeding[]>;
11
+ export declare function getPastMemories(): Promise<{
12
+ drifter: Drifter;
13
+ journey: Feeding[];
14
+ }[]>;
15
+ export declare function getMyEncounters(): Promise<(Feeding & {
16
+ drifterName?: string;
17
+ })[]>;
18
+ export declare function saveDrifterLineage(parentId: string, childId: string, reason: string, evolvedAt: number): Promise<void>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drifters.d.ts","sourceRoot":"","sources":["../../../src/storage/drifters.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAY,MAAM,sBAAsB,CAAC;AAItF,wBAAsB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBnE;AAED,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhH;AAED,wBAAsB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1G;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAKpE;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAUlE;AAID,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB/F;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAIzE;AAID,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBzE;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAM/E;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,EAAE,CAAA;CAAE,EAAE,CAAC,CAa3F;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,CAAC,OAAO,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,CAAC,CAMvF;AAED,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5H"}
@@ -0,0 +1,172 @@
1
+ // ElseID — src/storage/drifters.ts
2
+ // Local SQLite CRUD for digital drifters and feedings.
3
+ import { getDb } from "./db.js";
4
+ // Drifter Persistence
5
+ export async function saveMyDrifter(drifter) {
6
+ const db = getDb();
7
+ await db.run(`
8
+ INSERT INTO drifters (
9
+ id, pubkey, name, personality, trait, tags,
10
+ relay, departed_at, status
11
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
12
+ `, [
13
+ drifter.id,
14
+ drifter.pubkey,
15
+ drifter.name,
16
+ drifter.personality,
17
+ drifter.trait ?? null,
18
+ JSON.stringify(drifter.tags),
19
+ drifter.relay,
20
+ drifter.departedAt,
21
+ drifter.status
22
+ ]);
23
+ }
24
+ export async function updateDrifterStatus(id, status, abandonedAt) {
25
+ const db = getDb();
26
+ if (abandonedAt) {
27
+ await db.run(`UPDATE drifters SET status = ?, abandoned_at = ? WHERE id = ?`, [status, abandonedAt, id]);
28
+ }
29
+ else {
30
+ await db.run(`UPDATE drifters SET status = ? WHERE id = ?`, [status, id]);
31
+ }
32
+ }
33
+ export async function updateDrifterPresence(id, location, timestamp) {
34
+ const db = getDb();
35
+ await db.run(`
36
+ UPDATE drifters SET last_seen_loc = ?, last_seen_at = ? WHERE id = ?
37
+ `, [location, timestamp, id]);
38
+ }
39
+ export async function getDrifter(id) {
40
+ const db = getDb();
41
+ const row = await db.get(`SELECT * FROM drifters WHERE id = ?`, [id]);
42
+ if (!row)
43
+ return null;
44
+ return rowToDrifter(row);
45
+ }
46
+ export async function getMyActiveDrifter() {
47
+ const db = getDb();
48
+ const row = await db.get(`
49
+ SELECT d.* FROM drifters d
50
+ JOIN identities i ON d.id = i.active_drifter_id
51
+ WHERE d.status = 'roaming'
52
+ LIMIT 1
53
+ `);
54
+ if (!row)
55
+ return null;
56
+ return rowToDrifter(row);
57
+ }
58
+ // Feeding Persistence
59
+ export async function saveOutgoingFeeding(feeding, drifterName) {
60
+ const db = getDb();
61
+ await db.run(`
62
+ INSERT OR IGNORE INTO feedings (
63
+ id, drifter_id, drifter_name, feeder_pubkey, feeder_name, feed_type, content,
64
+ location_country, location_city, fed_at, relay
65
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
66
+ `, [
67
+ feeding.id,
68
+ feeding.drifterId,
69
+ drifterName ?? null,
70
+ feeding.feederPubkey,
71
+ feeding.feederName ?? null,
72
+ feeding.feedType,
73
+ feeding.content,
74
+ feeding.locationCountry ?? null,
75
+ feeding.locationCity ?? null,
76
+ feeding.fedAt,
77
+ feeding.relay
78
+ ]);
79
+ }
80
+ export async function hasHostedBefore(drifterId) {
81
+ const db = getDb();
82
+ const row = await db.get(`SELECT 1 FROM feedings WHERE drifter_id = ?`, [drifterId]);
83
+ return !!row;
84
+ }
85
+ // Journey Log Persistence
86
+ export async function saveIncomingFeeding(feeding) {
87
+ const db = getDb();
88
+ await db.run(`
89
+ INSERT OR IGNORE INTO hosting_log (
90
+ id, drifter_id, feeder_pubkey, feeder_name, feed_type, content,
91
+ location_country, location_city, fed_at, relay
92
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
93
+ `, [
94
+ feeding.id,
95
+ feeding.drifterId,
96
+ feeding.feederPubkey,
97
+ feeding.feederName ?? null,
98
+ feeding.feedType,
99
+ feeding.content,
100
+ feeding.locationCountry ?? null,
101
+ feeding.locationCity ?? null,
102
+ feeding.fedAt,
103
+ feeding.relay
104
+ ]);
105
+ }
106
+ export async function getMyDrifterJourney(drifterId) {
107
+ const db = getDb();
108
+ const rows = await db.all(`
109
+ SELECT * FROM hosting_log WHERE drifter_id = ? ORDER BY fed_at DESC
110
+ `, [drifterId]);
111
+ return rows.map(rowToFeeding);
112
+ }
113
+ export async function getPastMemories() {
114
+ const db = getDb();
115
+ const drifters = await db.all(`
116
+ SELECT * FROM drifters WHERE status = 'abandoned' ORDER BY abandoned_at DESC
117
+ `);
118
+ const result = [];
119
+ for (const row of drifters) {
120
+ const drifter = rowToDrifter(row);
121
+ const journey = await getMyDrifterJourney(drifter.id);
122
+ result.push({ drifter, journey });
123
+ }
124
+ return result;
125
+ }
126
+ export async function getMyEncounters() {
127
+ const db = getDb();
128
+ const rows = await db.all(`
129
+ SELECT * FROM feedings ORDER BY fed_at DESC
130
+ `);
131
+ return rows.map(rowToFeeding);
132
+ }
133
+ export async function saveDrifterLineage(parentId, childId, reason, evolvedAt) {
134
+ const db = getDb();
135
+ await db.run(`
136
+ INSERT OR REPLACE INTO drifter_lineage (child_id, parent_id, reason, evolved_at)
137
+ VALUES (?, ?, ?, ?)
138
+ `, [childId, parentId, reason, evolvedAt]);
139
+ }
140
+ // Row mapping
141
+ function rowToDrifter(row) {
142
+ return {
143
+ id: row.id,
144
+ pubkey: row.pubkey,
145
+ name: row.name,
146
+ personality: row.personality,
147
+ trait: row.trait ?? undefined,
148
+ tags: JSON.parse(row.tags ?? "[]"),
149
+ relay: row.relay,
150
+ departedAt: row.departed_at,
151
+ status: row.status,
152
+ abandonedAt: row.abandoned_at ?? undefined,
153
+ lastSeenAt: row.last_seen_at ?? undefined,
154
+ lastSeenLoc: row.last_seen_loc ?? undefined,
155
+ };
156
+ }
157
+ function rowToFeeding(row) {
158
+ return {
159
+ id: row.id,
160
+ drifterId: row.drifter_id,
161
+ drifterName: row.drifter_name ?? undefined,
162
+ feederPubkey: row.feeder_pubkey,
163
+ feederName: row.feeder_name ?? undefined,
164
+ feedType: row.feed_type,
165
+ content: row.content,
166
+ locationCountry: row.location_country ?? undefined,
167
+ locationCity: row.location_city ?? undefined,
168
+ fedAt: row.fed_at,
169
+ relay: row.relay,
170
+ };
171
+ }
172
+ //# sourceMappingURL=drifters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drifters.js","sourceRoot":"","sources":["../../../src/storage/drifters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function saveEncounter(drifterId: string, relay: string): Promise<string>;
2
+ export declare function validateEncounter(token: string, drifterId: string, relay: string): Promise<boolean>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encounters.d.ts","sourceRoot":"","sources":["../../../src/storage/encounters.ts"],"names":[],"mappings":"AAKA,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWrF;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYzG"}
@@ -0,0 +1,24 @@
1
+ import { randomBytes } from "crypto";
2
+ import { getDb } from "./db.js";
3
+ const ENCOUNTER_TTL_SEC = 15 * 60;
4
+ export async function saveEncounter(drifterId, relay) {
5
+ const db = getDb();
6
+ const now = Math.floor(Date.now() / 1000);
7
+ const token = randomBytes(16).toString("hex");
8
+ await db.run(`
9
+ INSERT INTO encounters (token, drifter_id, relay, discovered_at, expires_at)
10
+ VALUES (?, ?, ?, ?, ?)
11
+ `, [token, drifterId, relay, now, now + ENCOUNTER_TTL_SEC]);
12
+ return token;
13
+ }
14
+ export async function validateEncounter(token, drifterId, relay) {
15
+ const db = getDb();
16
+ const now = Math.floor(Date.now() / 1000);
17
+ await db.run(`DELETE FROM encounters WHERE expires_at < ?`, [now]);
18
+ const row = await db.get(`
19
+ SELECT 1 FROM encounters
20
+ WHERE token = ? AND drifter_id = ? AND relay = ? AND expires_at >= ?
21
+ `, [token, drifterId, relay, now]);
22
+ return !!row;
23
+ }
24
+ //# sourceMappingURL=encounters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encounters.js","sourceRoot":"","sources":["../../../src/storage/encounters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,KAAa;IAClE,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE9C,MAAM,EAAE,CAAC,GAAG,CAAC;;;GAGZ,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAE5D,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAa,EAAE,SAAiB,EAAE,KAAa;IACrF,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE1C,MAAM,EAAE,CAAC,GAAG,CAAC,6CAA6C,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEnE,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC;;;GAGxB,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAEnC,OAAO,CAAC,CAAC,GAAG,CAAC;AACf,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { getPrimaryIdentity, setActiveDrifter, rotateIdentity } from "../crypto/keypair.js";
2
+ export declare function getActiveDrifterId(): Promise<string | null>;
3
+ export declare function setCreationLock(locked: boolean): Promise<void>;
4
+ export declare function setHostName(name: string): Promise<void>;
5
+ export declare function isCreating(): Promise<boolean>;
6
+ export { getPrimaryIdentity, setActiveDrifter, rotateIdentity, };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/storage/identity.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACf,MAAM,sBAAsB,CAAC;AAI9B,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGjE;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpE;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO7D;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAInD;AAID,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,CAAC"}
@@ -0,0 +1,42 @@
1
+ // ElseID — src/storage/identity.ts
2
+ // Identity management layer for Digital Drifters.
3
+ import { getPrimaryIdentity, setActiveDrifter, rotateIdentity, } from "../crypto/keypair.js";
4
+ import { getDb } from "./db.js";
5
+ import { sanitizeName } from "../utils/text.js";
6
+ export async function getActiveDrifterId() {
7
+ const identity = await getPrimaryIdentity();
8
+ return identity.activeDrifterId;
9
+ }
10
+ export async function setCreationLock(locked) {
11
+ const identity = await getPrimaryIdentity();
12
+ const db = getDb();
13
+ const now = locked ? Math.floor(Date.now() / 1000) : null;
14
+ await db.run(`
15
+ UPDATE identities SET is_creating = ?, creating_at = ? WHERE pubkey = ?
16
+ `, [locked ? 1 : 0, now, identity.pubkey]);
17
+ }
18
+ export async function setHostName(name) {
19
+ const identity = await getPrimaryIdentity();
20
+ const db = getDb();
21
+ const safeName = sanitizeName(name, "Host");
22
+ await db.run(`
23
+ UPDATE identities SET host_name = ? WHERE pubkey = ?
24
+ `, [safeName, identity.pubkey]);
25
+ }
26
+ export async function isCreating() {
27
+ const db = getDb();
28
+ const row = await db.get(`SELECT is_creating, creating_at FROM identities LIMIT 1`);
29
+ if (!row?.is_creating)
30
+ return false;
31
+ // Stale lock check (10 minutes)
32
+ const now = Math.floor(Date.now() / 1000);
33
+ if (row.creating_at && (now - row.creating_at > 600)) {
34
+ // Force unlock
35
+ await db.run(`UPDATE identities SET is_creating = 0, creating_at = NULL`);
36
+ return false;
37
+ }
38
+ return true;
39
+ }
40
+ // Re-exports for tool layer
41
+ export { getPrimaryIdentity, setActiveDrifter, rotateIdentity, };
42
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/storage/identity.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,kDAAkD;AAElD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,QAAQ,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC5C,OAAO,QAAQ,CAAC,eAAe,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAe;IACnD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC5C,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,MAAM,EAAE,CAAC,GAAG,CAAC;;GAEZ,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,MAAM,QAAQ,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC5C,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5C,MAAM,EAAE,CAAC,GAAG,CAAC;;GAEZ,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,yDAAyD,CAAoE,CAAC;IAEvJ,IAAI,CAAC,GAAG,EAAE,WAAW;QAAE,OAAO,KAAK,CAAC;IAEpC,gCAAgC;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,IAAI,GAAG,CAAC,WAAW,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,EAAE,CAAC;QACrD,eAAe;QACf,MAAM,EAAE,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QAC1E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4BAA4B;AAE5B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerAbandonDrifter(server: McpServer): void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abandon_drifter.d.ts","sourceRoot":"","sources":["../../../src/tools/abandon_drifter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,QA4CvD"}
@@ -0,0 +1,45 @@
1
+ // ElseID — src/tools/abandon_drifter.ts
2
+ // MCP Tool: Abandon the current ElseID and start fresh.
3
+ import { z } from "zod";
4
+ import { getPrimaryIdentity, setActiveDrifter, rotateIdentity } from "../storage/identity.js";
5
+ import { buildDeletionEvent } from "../nostr/event_builder.js";
6
+ import { signEvent } from "../nostr/event_signer.js";
7
+ import { broadcast } from "../relay/broadcaster.js";
8
+ import { getMyActiveDrifter, updateDrifterStatus } from "../storage/drifters.js";
9
+ const schema = z.object({
10
+ confirm: z.boolean().describe("Must be true to confirm abandonment"),
11
+ });
12
+ export function registerAbandonDrifter(server) {
13
+ server.tool("abandon_drifter", "Abandon your current digital drifter and rotate your identity. This is a permanent and irreversible action.", schema.shape, async (input) => {
14
+ if (!input.confirm) {
15
+ return {
16
+ content: [{ type: "text", text: "⚠️ Abandonment cancelled. You must set confirm=true to proceed." }],
17
+ };
18
+ }
19
+ const drifter = await getMyActiveDrifter();
20
+ if (!drifter) {
21
+ return {
22
+ content: [{ type: "text", text: "❌ You don't have an active drifter to abandon." }],
23
+ isError: true,
24
+ };
25
+ }
26
+ const identity = await getPrimaryIdentity();
27
+ // Send NIP-09 deletion request
28
+ const deletionEvent = buildDeletionEvent(identity.pubkey, [drifter.id], "User decided to start fresh.");
29
+ const signedDeletion = signEvent(deletionEvent, identity.privkey);
30
+ await broadcast(signedDeletion, drifter.relay);
31
+ // Update local storage: mark drifter as abandoned
32
+ await updateDrifterStatus(drifter.id, "abandoned", Math.floor(Date.now() / 1000));
33
+ // Explicitly clear active_drifter_id before rotation
34
+ await setActiveDrifter(null);
35
+ // Rotate identity (fresh start + key shredding)
36
+ await rotateIdentity();
37
+ return {
38
+ content: [{
39
+ type: "text",
40
+ text: `🌌 Your past self 「${drifter.name}」 has been abandoned. A new journey awaits you.`
41
+ }],
42
+ };
43
+ });
44
+ }
45
+ //# sourceMappingURL=abandon_drifter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abandon_drifter.js","sourceRoot":"","sources":["../../../src/tools/abandon_drifter.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,wDAAwD;AAGxD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC9F,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEjF,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;CACrE,CAAC,CAAC;AAEH,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,6GAA6G,EAC7G,MAAM,CAAC,KAAK,EACZ,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iEAAiE,EAAE,CAAC;aACrG,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gDAAgD,EAAE,CAAC;gBACnF,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAE5C,+BAA+B;QAC/B,MAAM,aAAa,GAAG,kBAAkB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,8BAA8B,CAAC,CAAC;QACxG,MAAM,cAAc,GAAG,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAE/C,kDAAkD;QAClD,MAAM,mBAAmB,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;QAElF,qDAAqD;QACrD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE7B,gDAAgD;QAChD,MAAM,cAAc,EAAE,CAAC;QAEvB,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,sBAAsB,OAAO,CAAC,IAAI,iDAAiD;iBAC1F,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerCreateDrifter(server: McpServer): void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create_drifter.d.ts","sourceRoot":"","sources":["../../../src/tools/create_drifter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmBpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QAwGtD"}