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.
- package/LICENSE +662 -0
- package/README.md +138 -0
- package/dist/config/relays.d.ts +13 -0
- package/dist/config/relays.d.ts.map +1 -0
- package/dist/config/relays.js +51 -0
- package/dist/config/relays.js.map +1 -0
- package/dist/scripts/cli.d.ts +2 -0
- package/dist/scripts/cli.d.ts.map +1 -0
- package/dist/scripts/cli.js +156 -0
- package/dist/scripts/cli.js.map +1 -0
- package/dist/scripts/setup.d.ts +1 -0
- package/dist/scripts/setup.d.ts.map +1 -0
- package/dist/scripts/setup.js +50 -0
- package/dist/scripts/setup.js.map +1 -0
- package/dist/src/ai/moderator.d.ts +2 -0
- package/dist/src/ai/moderator.d.ts.map +1 -0
- package/dist/src/ai/moderator.js +61 -0
- package/dist/src/ai/moderator.js.map +1 -0
- package/dist/src/crypto/encrypt.d.ts +13 -0
- package/dist/src/crypto/encrypt.d.ts.map +1 -0
- package/dist/src/crypto/encrypt.js +60 -0
- package/dist/src/crypto/encrypt.js.map +1 -0
- package/dist/src/crypto/encryption.d.ts +10 -0
- package/dist/src/crypto/encryption.js +69 -0
- package/dist/src/crypto/encryption.js.map +1 -0
- package/dist/src/crypto/keypair.d.ts +4 -0
- package/dist/src/crypto/keypair.d.ts.map +1 -0
- package/dist/src/crypto/keypair.js +86 -0
- package/dist/src/crypto/keypair.js.map +1 -0
- package/dist/src/evolution/backpack.d.ts +7 -0
- package/dist/src/evolution/backpack.d.ts.map +1 -0
- package/dist/src/evolution/backpack.js +15 -0
- package/dist/src/evolution/backpack.js.map +1 -0
- package/dist/src/evolution/skills.d.ts +7 -0
- package/dist/src/evolution/skills.d.ts.map +1 -0
- package/dist/src/evolution/skills.js +10 -0
- package/dist/src/evolution/skills.js.map +1 -0
- package/dist/src/evolution/synthesis.d.ts +11 -0
- package/dist/src/evolution/synthesis.d.ts.map +1 -0
- package/dist/src/evolution/synthesis.js +80 -0
- package/dist/src/evolution/synthesis.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +65 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/location/geo.d.ts +3 -0
- package/dist/src/location/geo.d.ts.map +1 -0
- package/dist/src/location/geo.js +35 -0
- package/dist/src/location/geo.js.map +1 -0
- package/dist/src/nostr/event_builder.d.ts +22 -0
- package/dist/src/nostr/event_builder.d.ts.map +1 -0
- package/dist/src/nostr/event_builder.js +65 -0
- package/dist/src/nostr/event_builder.js.map +1 -0
- package/dist/src/nostr/event_signer.d.ts +4 -0
- package/dist/src/nostr/event_signer.d.ts.map +1 -0
- package/dist/src/nostr/event_signer.js +38 -0
- package/dist/src/nostr/event_signer.js.map +1 -0
- package/dist/src/nostr/filter.d.ts +11 -0
- package/dist/src/nostr/filter.d.ts.map +1 -0
- package/dist/src/nostr/filter.js +23 -0
- package/dist/src/nostr/filter.js.map +1 -0
- package/dist/src/nostr/ws_pool.d.ts +15 -0
- package/dist/src/nostr/ws_pool.d.ts.map +1 -0
- package/dist/src/nostr/ws_pool.js +291 -0
- package/dist/src/nostr/ws_pool.js.map +1 -0
- package/dist/src/relay/broadcaster.d.ts +8 -0
- package/dist/src/relay/broadcaster.d.ts.map +1 -0
- package/dist/src/relay/broadcaster.js +85 -0
- package/dist/src/relay/broadcaster.js.map +1 -0
- package/dist/src/relay/health.d.ts +5 -0
- package/dist/src/relay/health.d.ts.map +1 -0
- package/dist/src/relay/health.js +118 -0
- package/dist/src/relay/health.js.map +1 -0
- package/dist/src/relay/selector.d.ts +4 -0
- package/dist/src/relay/selector.d.ts.map +1 -0
- package/dist/src/relay/selector.js +45 -0
- package/dist/src/relay/selector.js.map +1 -0
- package/dist/src/storage/db.d.ts +4 -0
- package/dist/src/storage/db.d.ts.map +1 -0
- package/dist/src/storage/db.js +195 -0
- package/dist/src/storage/db.js.map +1 -0
- package/dist/src/storage/drifters.d.ts +18 -0
- package/dist/src/storage/drifters.d.ts.map +1 -0
- package/dist/src/storage/drifters.js +172 -0
- package/dist/src/storage/drifters.js.map +1 -0
- package/dist/src/storage/encounters.d.ts +2 -0
- package/dist/src/storage/encounters.d.ts.map +1 -0
- package/dist/src/storage/encounters.js +24 -0
- package/dist/src/storage/encounters.js.map +1 -0
- package/dist/src/storage/identity.d.ts +6 -0
- package/dist/src/storage/identity.d.ts.map +1 -0
- package/dist/src/storage/identity.js +42 -0
- package/dist/src/storage/identity.js.map +1 -0
- package/dist/src/tools/abandon_drifter.d.ts +2 -0
- package/dist/src/tools/abandon_drifter.d.ts.map +1 -0
- package/dist/src/tools/abandon_drifter.js +45 -0
- package/dist/src/tools/abandon_drifter.js.map +1 -0
- package/dist/src/tools/create_drifter.d.ts +2 -0
- package/dist/src/tools/create_drifter.d.ts.map +1 -0
- package/dist/src/tools/create_drifter.js +98 -0
- package/dist/src/tools/create_drifter.js.map +1 -0
- package/dist/src/tools/evolve_drifter.d.ts +2 -0
- package/dist/src/tools/evolve_drifter.d.ts.map +1 -0
- package/dist/src/tools/evolve_drifter.js +45 -0
- package/dist/src/tools/evolve_drifter.js.map +1 -0
- package/dist/src/tools/feed_drifter.d.ts +2 -0
- package/dist/src/tools/feed_drifter.d.ts.map +1 -0
- package/dist/src/tools/feed_drifter.js +86 -0
- package/dist/src/tools/feed_drifter.js.map +1 -0
- package/dist/src/tools/find_nearby_drifter.d.ts +2 -0
- package/dist/src/tools/find_nearby_drifter.d.ts.map +1 -0
- package/dist/src/tools/find_nearby_drifter.js +70 -0
- package/dist/src/tools/find_nearby_drifter.js.map +1 -0
- package/dist/src/tools/get_journey_log.d.ts +2 -0
- package/dist/src/tools/get_journey_log.d.ts.map +1 -0
- package/dist/src/tools/get_journey_log.js +61 -0
- package/dist/src/tools/get_journey_log.js.map +1 -0
- package/dist/src/tools/get_my_encounters.d.ts +2 -0
- package/dist/src/tools/get_my_encounters.d.ts.map +1 -0
- package/dist/src/tools/get_my_encounters.js +23 -0
- package/dist/src/tools/get_my_encounters.js.map +1 -0
- package/dist/src/tools/list_past_memories.d.ts +2 -0
- package/dist/src/tools/list_past_memories.d.ts.map +1 -0
- package/dist/src/tools/list_past_memories.js +41 -0
- package/dist/src/tools/list_past_memories.js.map +1 -0
- package/dist/src/tools/recover_drifter.d.ts +2 -0
- package/dist/src/tools/recover_drifter.d.ts.map +1 -0
- package/dist/src/tools/recover_drifter.js +82 -0
- package/dist/src/tools/recover_drifter.js.map +1 -0
- package/dist/src/tools/relay_tools.d.ts +2 -0
- package/dist/src/tools/relay_tools.d.ts.map +1 -0
- package/dist/src/tools/relay_tools.js +72 -0
- package/dist/src/tools/relay_tools.js.map +1 -0
- package/dist/src/tools/set_host_name.d.ts +2 -0
- package/dist/src/tools/set_host_name.d.ts.map +1 -0
- package/dist/src/tools/set_host_name.js +23 -0
- package/dist/src/tools/set_host_name.js.map +1 -0
- package/dist/src/utils/errors.d.ts +4 -0
- package/dist/src/utils/errors.js +28 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/redact.d.ts +1 -0
- package/dist/src/utils/redact.d.ts.map +1 -0
- package/dist/src/utils/redact.js +20 -0
- package/dist/src/utils/redact.js.map +1 -0
- package/dist/src/utils/text.d.ts +2 -0
- package/dist/src/utils/text.d.ts.map +1 -0
- package/dist/src/utils/text.js +15 -0
- package/dist/src/utils/text.js.map +1 -0
- package/dist/types/index.d.ts +97 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/docs/system_prompt.md +159 -0
- 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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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":"AAAA,sCAAsC;AACtC,2CAA2C;AAE3C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGhG,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AASvD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,UAAmB,EAAE,KAAqB;IAC9E,MAAM,QAAQ,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAE1C,MAAM,QAAQ,GAAG,iBAAiB,CAAC;QACjC,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,WAAW,EAAE,KAAK,CAAC,cAAc;QACjC,QAAQ,EAAE;YACR,KAAK,EAAE,KAAK,CAAC,QAAQ;YACrB,IAAI,EAAE,KAAK,CAAC,OAAO;SACpB;QACD,QAAQ;QACR,OAAO,EAAE,eAAe,KAAK,CAAC,eAAe,EAAE;KAChD,CAAC,CAAC;IAEH,qBAAqB;IACrB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IAEpD,4CAA4C;IAC5C,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpD,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAEzD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,0BAA0B,EAAE,CAAC;IACnF,CAAC;IAED,MAAM,UAAU,GAAY;QAC1B,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,WAAW,EAAE,KAAK,CAAC,cAAc;QACjC,KAAK,EAAE,KAAK,CAAC,QAAQ;QACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;aAChB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC;aAChE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACtD,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,MAAM,EAAE,SAAS;KAClB,CAAC;IAEF,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC;;;;KAI3B,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAqD,CAAC;QAC1E,IAAI,MAAM,EAAE,iBAAiB,KAAK,UAAU,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QAED,2CAA2C;QAC3C,MAAM,mBAAmB,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;QAErF,oCAAoC;QACpC,MAAM,aAAa,CAAC,UAAU,CAAC,CAAC;QAEhC,8CAA8C;QAC9C,MAAM,EAAE,CAAC,GAAG,CAAC;;KAEZ,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACjC,MAAM,kBAAkB,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,mBAAmB,CAAC,KAAK,CAAC,eAAe,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAEvH,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3C,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;AACrE,CAAC"}
|
|
@@ -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":"AAAA,kCAAkC;AAElC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,EAAE,CAAC;IAEf,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAEzD,yDAAyD;IACzD,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,yCAAyC,MAAM,IAAI,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC;IACpG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QACZ,OAAO,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,GAAG,CAAC,OAAO;KACrB,CAAC,CAAC;IAEH,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAClC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACjC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAE9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IAEjE,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,QAAQ,EAAE,CAAC;QACX,MAAM,OAAO,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -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"}
|