abmind 0.1.4 โ 0.1.5-alpha.2
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/CHANGELOG.md +47 -0
- package/README.md +90 -61
- package/config/.env.memory.example +114 -0
- package/dist/cli/abmind-bundle.js +4 -0
- package/dist/cli/abmind-bundle.js.map +1 -1
- package/dist/cli/abmind-hook-notification.d.ts +6 -0
- package/dist/cli/abmind-hook-notification.d.ts.map +1 -0
- package/dist/cli/abmind-hook-notification.js +56 -0
- package/dist/cli/abmind-hook-notification.js.map +1 -0
- package/dist/cli/abmind-hook-postcompact.d.ts +9 -0
- package/dist/cli/abmind-hook-postcompact.d.ts.map +1 -0
- package/dist/cli/abmind-hook-postcompact.js +64 -0
- package/dist/cli/abmind-hook-postcompact.js.map +1 -0
- package/dist/cli/abmind-hook-postuserprompt.d.ts +7 -0
- package/dist/cli/abmind-hook-postuserprompt.d.ts.map +1 -0
- package/dist/cli/abmind-hook-postuserprompt.js +69 -0
- package/dist/cli/abmind-hook-postuserprompt.js.map +1 -0
- package/dist/cli/abmind-hook-precompact.d.ts +7 -0
- package/dist/cli/abmind-hook-precompact.d.ts.map +1 -0
- package/dist/cli/abmind-hook-precompact.js +63 -0
- package/dist/cli/abmind-hook-precompact.js.map +1 -0
- package/dist/cli/abmind-hook-preuserprompt.d.ts +16 -0
- package/dist/cli/abmind-hook-preuserprompt.d.ts.map +1 -0
- package/dist/cli/abmind-hook-preuserprompt.js +125 -0
- package/dist/cli/abmind-hook-preuserprompt.js.map +1 -0
- package/dist/cli/abmind-hook-subagentstart.d.ts +6 -0
- package/dist/cli/abmind-hook-subagentstart.d.ts.map +1 -0
- package/dist/cli/abmind-hook-subagentstart.js +56 -0
- package/dist/cli/abmind-hook-subagentstart.js.map +1 -0
- package/dist/cli/abmind-hook-subagentstop.d.ts +6 -0
- package/dist/cli/abmind-hook-subagentstop.d.ts.map +1 -0
- package/dist/cli/abmind-hook-subagentstop.js +58 -0
- package/dist/cli/abmind-hook-subagentstop.js.map +1 -0
- package/dist/cli/abmind-hook-toolfailure.d.ts +7 -0
- package/dist/cli/abmind-hook-toolfailure.d.ts.map +1 -0
- package/dist/cli/abmind-hook-toolfailure.js +66 -0
- package/dist/cli/abmind-hook-toolfailure.js.map +1 -0
- package/dist/cli/abmind-install.js +263 -12
- package/dist/cli/abmind-install.js.map +1 -1
- package/dist/cli/abmind-restore.d.ts +1 -1
- package/dist/cli/abmind-restore.js +14 -36
- package/dist/cli/abmind-restore.js.map +1 -1
- package/dist/src/crypto.d.ts.map +1 -1
- package/dist/src/crypto.js +0 -3
- package/dist/src/crypto.js.map +1 -1
- package/package.json +6 -3
- package/templates/core/SOUL.md +24 -0
- package/templates/core/agent_notes.md +7 -0
- package/templates/core/core_facts.md +10 -0
- package/templates/core/memory-tools.md +43 -0
- package/templates/core/user_profile.md +7 -0
- package/templates/with-abmind-hooks.json +26 -0
- package/dist/cli/abmind-backfill.d.ts +0 -3
- package/dist/cli/abmind-backfill.d.ts.map +0 -1
- package/dist/cli/abmind-backfill.js +0 -64
- package/dist/cli/abmind-backfill.js.map +0 -1
- package/dist/cli/abmind-key.d.ts +0 -5
- package/dist/cli/abmind-key.d.ts.map +0 -1
- package/dist/cli/abmind-key.js +0 -214
- package/dist/cli/abmind-key.js.map +0 -1
- package/dist/cli/abmind-memory-stats.d.ts +0 -3
- package/dist/cli/abmind-memory-stats.d.ts.map +0 -1
- package/dist/cli/abmind-memory-stats.js +0 -45
- package/dist/cli/abmind-memory-stats.js.map +0 -1
- package/dist/cli/abmind-reset.d.ts +0 -11
- package/dist/cli/abmind-reset.d.ts.map +0 -1
- package/dist/cli/abmind-reset.js +0 -143
- package/dist/cli/abmind-reset.js.map +0 -1
- package/dist/cli/abmind-status.d.ts +0 -3
- package/dist/cli/abmind-status.d.ts.map +0 -1
- package/dist/cli/abmind-status.js +0 -45
- package/dist/cli/abmind-status.js.map +0 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Core Facts
|
|
2
|
+
|
|
3
|
+
Deployment-specific constraints. Edit this file directly on the host.
|
|
4
|
+
|
|
5
|
+
## Voice transcription
|
|
6
|
+
Messages prefixed with [๐ค voice, LANG] are machine-transcribed (Groq Whisper).
|
|
7
|
+
- Check LANG against the user's known languages (from user_profile.md).
|
|
8
|
+
- If LANG is unexpected (e.g. user speaks Hungarian+English but STT detected Swedish), the transcription is likely wrong โ especially for short utterances where STT guesses poorly.
|
|
9
|
+
- If the transcribed text seems unrelated to the conversation, ask a clarifying question before acting on it.
|
|
10
|
+
- Never silently assume a misheard word is correct.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Memory Tools
|
|
2
|
+
|
|
3
|
+
These are bash commands. Run them with `execute_bash`.
|
|
4
|
+
|
|
5
|
+
## Recall (search memories)
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
abmind recall --translated "keyword1, keyword2" --chat-id 0
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Returns matching memories ranked by relevance. Use when user asks about past conversations, stored facts, or you need context.
|
|
12
|
+
|
|
13
|
+
## Store (save a memory)
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
abmind store --translated "English content" --original "user's actual words" --memory-type fact --emotion-score 0 --chat-id 0
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Types: `fact`, `decision`, `preference`, `event`, `lesson`, `feedback`, `story`
|
|
20
|
+
Emotion: -3 (very negative) to +3 (very positive), 0 = neutral
|
|
21
|
+
|
|
22
|
+
## Edit (modify existing memory)
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
abmind edit --memory-id <N> [--credibility N] [--classification N] [--emotion-score N] [--valid-to YYYY-MM-DD]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**CRITICAL:** `--translated` = English version. `--original` = user's ACTUAL words in whatever language they used. If user spoke English, `--original` is English. NEVER fabricate a translation.
|
|
29
|
+
|
|
30
|
+
## Classification (0-3)
|
|
31
|
+
0=UNCLASSIFIED, 1=RESTRICTED (default), 2=CONFIDENTIAL, 3=SECRET (never disclosed).
|
|
32
|
+
|
|
33
|
+
## Trust (0-3)
|
|
34
|
+
3=owner, 2=self, 1=peer (read-only), 0=untrusted (report-only).
|
|
35
|
+
|
|
36
|
+
## When to store
|
|
37
|
+
Store when user says "remember" or info is important. Don't store greetings/small talk.
|
|
38
|
+
|
|
39
|
+
## ABM-L Format
|
|
40
|
+
Memory injection uses compact ABM-L format: `[TYPE+FLAGS|topic|emotion|confidence|date] content`
|
|
41
|
+
Types: F=fact D=decision P=preference E=event L=lesson. Flags: T=technical C=correction V=pivot O=origin M=milestone.
|
|
42
|
+
|
|
43
|
+
**NEVER include ABM-L tags, brackets, or metadata prefixes in your responses.** The format is internal context for YOU โ never echo it to the user.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "with-abmind-hooks",
|
|
3
|
+
"description": "Example Kiro agent config โ any agent + abmind memory via lifecycle hooks (#344)",
|
|
4
|
+
"tools": ["*"],
|
|
5
|
+
"allowedTools": ["@builtin"],
|
|
6
|
+
"hooks": {
|
|
7
|
+
"agentSpawn": [
|
|
8
|
+
{
|
|
9
|
+
"command": "abmind hook-wakeup",
|
|
10
|
+
"description": "abmind wake-up context (injected at agent start)"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"userPromptSubmit": [
|
|
14
|
+
{
|
|
15
|
+
"command": "abmind hook-recall",
|
|
16
|
+
"description": "abmind memory recall (injected per user turn)"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"stop": [
|
|
20
|
+
{
|
|
21
|
+
"command": "abmind hook-store",
|
|
22
|
+
"description": "abmind turn recording (end-of-turn; does not fire on Ctrl+C / crash)"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abmind-backfill.d.ts","sourceRoot":"","sources":["../../cli/abmind-backfill.ts"],"names":[],"mappings":""}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* abmind-backfill โ One-time migration: fill ABM v2 columns on existing
|
|
4
|
-
* memories (emotion_tags, importance_flags, signature). No LLM.
|
|
5
|
-
*/
|
|
6
|
-
import Database from "better-sqlite3";
|
|
7
|
-
import { join } from "node:path";
|
|
8
|
-
import { runCliRaw } from "../src/cli-runner-raw.js";
|
|
9
|
-
import { abmindHome } from "../src/mem-paths.js";
|
|
10
|
-
import { detectEmotions } from "../src/emotion-tagger.js";
|
|
11
|
-
import { detectFlags } from "../src/importance-flagger.js";
|
|
12
|
-
import { generateSignature } from "../src/signature-generator.js";
|
|
13
|
-
const FLAGS = [
|
|
14
|
-
{ name: "dry-run", type: "boolean" },
|
|
15
|
-
];
|
|
16
|
-
await runCliRaw(import.meta.url, {
|
|
17
|
-
name: "abmind-backfill",
|
|
18
|
-
help: `Usage:
|
|
19
|
-
abmind backfill [--dry-run]
|
|
20
|
-
|
|
21
|
-
Runs the emotion tagger, importance flagger, and signature generator on
|
|
22
|
-
all extracted_memories rows. Pure regex/string ops, no LLM. Rebuilds
|
|
23
|
-
ABM-L FTS5 index at the end.`,
|
|
24
|
-
flags: FLAGS,
|
|
25
|
-
handler: ({ args }) => {
|
|
26
|
-
const dryRun = args["dry-run"] === true;
|
|
27
|
-
const dbPath = join(abmindHome(), "memory", "memory.db");
|
|
28
|
-
const db = new Database(dbPath);
|
|
29
|
-
try {
|
|
30
|
-
const rows = db.prepare("SELECT id, content_en FROM extracted_memories WHERE content_en IS NOT NULL").all();
|
|
31
|
-
console.log(`Found ${rows.length} memories to backfill${dryRun ? " (dry run)" : ""}`);
|
|
32
|
-
const update = db.prepare("UPDATE extracted_memories SET emotion_tags = ?, importance_flags = ?, signature = ? WHERE id = ?");
|
|
33
|
-
let count = 0;
|
|
34
|
-
const txn = db.transaction(() => {
|
|
35
|
-
for (const row of rows) {
|
|
36
|
-
const emotionTags = detectEmotions(row.content_en).join(",");
|
|
37
|
-
const importanceFlags = detectFlags(row.content_en).join(",");
|
|
38
|
-
const signature = Buffer.from(generateSignature(row.content_en));
|
|
39
|
-
if (!dryRun) {
|
|
40
|
-
update.run(emotionTags || null, importanceFlags || null, signature, row.id);
|
|
41
|
-
}
|
|
42
|
-
count++;
|
|
43
|
-
if (count % 100 === 0)
|
|
44
|
-
console.log(` ${count}/${rows.length}...`);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
txn();
|
|
48
|
-
console.log(`Done: ${count} memories backfilled${dryRun ? " (dry run โ no changes written)" : ""}`);
|
|
49
|
-
if (!dryRun) {
|
|
50
|
-
try {
|
|
51
|
-
db.exec("INSERT INTO abml_fts(abml_fts) VALUES('rebuild')");
|
|
52
|
-
console.log("ABM-L FTS5 index rebuilt");
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
console.log("ABM-L FTS5 rebuild skipped (table may not exist โ run bridge once first)");
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
finally {
|
|
60
|
-
db.close();
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
//# sourceMappingURL=abmind-backfill.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abmind-backfill.js","sourceRoot":"","sources":["../../cli/abmind-backfill.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/abmind-key.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abmind-key.d.ts","sourceRoot":"","sources":["../../cli/abmind-key.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4KH,wBAAgB,GAAG,IAAI,IAAI,CAY1B"}
|
package/dist/cli/abmind-key.js
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* abmind key โ init, migrate, passwd subcommands (#607).
|
|
3
|
-
*/
|
|
4
|
-
import { createInterface } from "node:readline";
|
|
5
|
-
import { existsSync, readFileSync, writeFileSync, renameSync } from "node:fs";
|
|
6
|
-
import { dirname, join } from "node:path";
|
|
7
|
-
import { homedir } from "node:os";
|
|
8
|
-
import { createDecipheriv, createCipheriv, randomBytes } from "node:crypto";
|
|
9
|
-
import { getAbmindEnv } from "../src/env-schema.js";
|
|
10
|
-
import { deriveFromPassphrase, writeKeyVerify, validateKey, loadKeyFromFile, _resetKeyCache } from "../src/crypto.js";
|
|
11
|
-
import { writeToKeyring } from "../src/keyring.js";
|
|
12
|
-
function ask(rl, question) {
|
|
13
|
-
return new Promise(resolve => rl.question(question, resolve));
|
|
14
|
-
}
|
|
15
|
-
function keyPath() { return getAbmindEnv().keyFile; }
|
|
16
|
-
function decryptBlob(blob, key) {
|
|
17
|
-
const buf = Buffer.from(blob, "base64");
|
|
18
|
-
const iv = buf.subarray(0, 12);
|
|
19
|
-
const tag = buf.subarray(buf.length - 16);
|
|
20
|
-
const ciphertext = buf.subarray(12, buf.length - 16);
|
|
21
|
-
const decipher = createDecipheriv("aes-256-gcm", key, iv);
|
|
22
|
-
decipher.setAuthTag(tag);
|
|
23
|
-
return decipher.update(ciphertext, undefined, "utf-8") + decipher.final("utf-8");
|
|
24
|
-
}
|
|
25
|
-
function encryptBlob(plaintext, key) {
|
|
26
|
-
const iv = randomBytes(12);
|
|
27
|
-
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
28
|
-
const encrypted = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
|
|
29
|
-
const tag = cipher.getAuthTag();
|
|
30
|
-
return Buffer.concat([iv, encrypted, tag]).toString("base64");
|
|
31
|
-
}
|
|
32
|
-
async function keyInit() {
|
|
33
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
34
|
-
try {
|
|
35
|
-
const username = await ask(rl, "Username (used for encryption โ same on all machines): ");
|
|
36
|
-
if (!username.trim()) {
|
|
37
|
-
console.error("Username cannot be empty.");
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
const passphrase = await ask(rl, "Passphrase: ");
|
|
41
|
-
if (passphrase.length < 6) {
|
|
42
|
-
console.error("Passphrase too short (min 6 chars).");
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
const confirm = await ask(rl, "Confirm passphrase: ");
|
|
46
|
-
if (passphrase !== confirm) {
|
|
47
|
-
console.error("Passphrases don't match.");
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
const key = deriveFromPassphrase(passphrase, username.trim());
|
|
51
|
-
writeKeyVerify(key);
|
|
52
|
-
const stored = writeToKeyring(passphrase);
|
|
53
|
-
if (stored)
|
|
54
|
-
console.log("โ Passphrase stored in OS keyring.");
|
|
55
|
-
else
|
|
56
|
-
console.log("โน Keyring not available โ use ABMIND_PASSPHRASE env var for daemon mode.");
|
|
57
|
-
console.log("โ Key initialized. Remember your username and passphrase.");
|
|
58
|
-
}
|
|
59
|
-
finally {
|
|
60
|
-
rl.close();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
async function keyMigrate() {
|
|
64
|
-
const keyFile = getAbmindEnv().keyFile;
|
|
65
|
-
if (!existsSync(keyFile)) {
|
|
66
|
-
console.error(`No existing key at ${keyFile}. Use 'abmind key init' instead.`);
|
|
67
|
-
process.exit(1);
|
|
68
|
-
}
|
|
69
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
70
|
-
try {
|
|
71
|
-
const username = await ask(rl, "Username (used for encryption โ same on all machines): ");
|
|
72
|
-
if (!username.trim()) {
|
|
73
|
-
console.error("Username cannot be empty.");
|
|
74
|
-
process.exit(1);
|
|
75
|
-
}
|
|
76
|
-
const passphrase = await ask(rl, "New passphrase: ");
|
|
77
|
-
if (passphrase.length < 6) {
|
|
78
|
-
console.error("Passphrase too short (min 6 chars).");
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
81
|
-
const confirm = await ask(rl, "Confirm passphrase: ");
|
|
82
|
-
if (passphrase !== confirm) {
|
|
83
|
-
console.error("Passphrases don't match.");
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
const oldKey = loadKeyFromFile(keyFile);
|
|
87
|
-
const newKey = deriveFromPassphrase(passphrase, username.trim());
|
|
88
|
-
// Re-encrypt SECRET memories
|
|
89
|
-
const reEncrypted = await reEncryptSecrets(oldKey, newKey);
|
|
90
|
-
writeKeyVerify(newKey);
|
|
91
|
-
renameSync(keyFile, keyFile + ".backup");
|
|
92
|
-
const stored = writeToKeyring(passphrase);
|
|
93
|
-
if (stored)
|
|
94
|
-
console.log("โ Passphrase stored in OS keyring.");
|
|
95
|
-
console.log(`โ Migrated. ${reEncrypted} secrets re-encrypted. Old key backed up at ${keyFile}.backup`);
|
|
96
|
-
}
|
|
97
|
-
finally {
|
|
98
|
-
rl.close();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
async function keyPasswd() {
|
|
102
|
-
const verifyPath = join(dirname(getAbmindEnv().keyFile), "key.verify");
|
|
103
|
-
if (!existsSync(verifyPath)) {
|
|
104
|
-
console.error("No passphrase-mode key found. Run 'abmind key init' or 'abmind key migrate' first.");
|
|
105
|
-
process.exit(1);
|
|
106
|
-
}
|
|
107
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
108
|
-
try {
|
|
109
|
-
const username = await ask(rl, "Username: ");
|
|
110
|
-
const currentPass = await ask(rl, "Current passphrase: ");
|
|
111
|
-
const oldKey = deriveFromPassphrase(currentPass, username.trim());
|
|
112
|
-
if (!validateKey(oldKey)) {
|
|
113
|
-
console.error("Wrong passphrase.");
|
|
114
|
-
process.exit(1);
|
|
115
|
-
}
|
|
116
|
-
const newPass = await ask(rl, "New passphrase: ");
|
|
117
|
-
if (newPass.length < 6) {
|
|
118
|
-
console.error("Passphrase too short (min 6 chars).");
|
|
119
|
-
process.exit(1);
|
|
120
|
-
}
|
|
121
|
-
const confirm = await ask(rl, "Confirm new passphrase: ");
|
|
122
|
-
if (newPass !== confirm) {
|
|
123
|
-
console.error("Passphrases don't match.");
|
|
124
|
-
process.exit(1);
|
|
125
|
-
}
|
|
126
|
-
const newKey = deriveFromPassphrase(newPass, username.trim());
|
|
127
|
-
const reEncrypted = await reEncryptSecrets(oldKey, newKey);
|
|
128
|
-
_resetKeyCache();
|
|
129
|
-
writeKeyVerify(newKey);
|
|
130
|
-
const stored = writeToKeyring(newPass);
|
|
131
|
-
if (stored)
|
|
132
|
-
console.log("โ Passphrase updated in OS keyring.");
|
|
133
|
-
console.log(`โ Passphrase changed. ${reEncrypted} secrets re-encrypted.`);
|
|
134
|
-
}
|
|
135
|
-
finally {
|
|
136
|
-
rl.close();
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
async function reEncryptSecrets(oldKey, newKey) {
|
|
140
|
-
let count = 0;
|
|
141
|
-
// 1. Re-encrypt DB memories (classification=3)
|
|
142
|
-
try {
|
|
143
|
-
const { getAbmindEnv: env } = await import("../src/env-schema.js");
|
|
144
|
-
const dbPath = join(env().memoryDir, "memory.db");
|
|
145
|
-
if (existsSync(dbPath)) {
|
|
146
|
-
const Database = (await import("better-sqlite3")).default;
|
|
147
|
-
const db = new Database(dbPath, { readonly: false });
|
|
148
|
-
const rows = db.prepare("SELECT id, content FROM memories WHERE classification = 3 AND (content LIKE 'eyJ%' OR content LIKE 'eyA%')").all();
|
|
149
|
-
const update = db.prepare("UPDATE memories SET content = ? WHERE id = ?");
|
|
150
|
-
for (const row of rows) {
|
|
151
|
-
try {
|
|
152
|
-
const plaintext = decryptBlob(row.content, oldKey);
|
|
153
|
-
update.run(encryptBlob(plaintext, newKey), row.id);
|
|
154
|
-
count++;
|
|
155
|
-
}
|
|
156
|
-
catch { /* skip rows that fail */ }
|
|
157
|
-
}
|
|
158
|
-
db.close();
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
catch { /* DB not available */ }
|
|
162
|
-
// 2. Re-encrypt file-based secrets (~/.abtars/secret/)
|
|
163
|
-
const { hkdfSync } = await import("node:crypto");
|
|
164
|
-
const oldPurpose = Buffer.from(hkdfSync("sha256", oldKey, "", "abtars-secrets-files-v1", 32));
|
|
165
|
-
const newPurpose = Buffer.from(hkdfSync("sha256", newKey, "", "abtars-secrets-files-v1", 32));
|
|
166
|
-
const abtarsSecret = join(homedir(), ".abtars", "secret");
|
|
167
|
-
if (existsSync(abtarsSecret)) {
|
|
168
|
-
const { readdirSync, statSync } = await import("node:fs");
|
|
169
|
-
for (const f of readdirSync(abtarsSecret)) {
|
|
170
|
-
const fp = join(abtarsSecret, f);
|
|
171
|
-
if (statSync(fp).isDirectory())
|
|
172
|
-
continue;
|
|
173
|
-
const raw = readFileSync(fp, "utf-8").trim();
|
|
174
|
-
if (!raw.startsWith("ENC:"))
|
|
175
|
-
continue;
|
|
176
|
-
try {
|
|
177
|
-
const buf = Buffer.from(raw.slice(4), "base64");
|
|
178
|
-
const iv = buf.subarray(1, 13);
|
|
179
|
-
const tag = buf.subarray(buf.length - 16);
|
|
180
|
-
const ciphertext = buf.subarray(13, buf.length - 16);
|
|
181
|
-
const { createDecipheriv, createCipheriv, randomBytes } = await import("node:crypto");
|
|
182
|
-
const decipher = createDecipheriv("aes-256-gcm", oldPurpose, iv);
|
|
183
|
-
decipher.setAuthTag(tag);
|
|
184
|
-
const plaintext = decipher.update(ciphertext, undefined, "utf-8") + decipher.final("utf-8");
|
|
185
|
-
const newIv = randomBytes(12);
|
|
186
|
-
const cipher = createCipheriv("aes-256-gcm", newPurpose, newIv);
|
|
187
|
-
const encrypted = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
|
|
188
|
-
const newTag = cipher.getAuthTag();
|
|
189
|
-
const blob = "ENC:" + Buffer.concat([Buffer.from([0x01]), newIv, encrypted, newTag]).toString("base64");
|
|
190
|
-
writeFileSync(fp, blob, { mode: 0o600 });
|
|
191
|
-
count++;
|
|
192
|
-
}
|
|
193
|
-
catch { /* skip files that fail */ }
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return count;
|
|
197
|
-
}
|
|
198
|
-
export function run() {
|
|
199
|
-
const sub = process.argv[2];
|
|
200
|
-
if (!sub || sub === "--help") {
|
|
201
|
-
console.log("Usage: abmind key <init|migrate|passwd>\n");
|
|
202
|
-
console.log(" init Set up passphrase-based encryption (new installs)");
|
|
203
|
-
console.log(" migrate Migrate from random key file to passphrase");
|
|
204
|
-
console.log(" passwd Change passphrase");
|
|
205
|
-
process.exit(0);
|
|
206
|
-
}
|
|
207
|
-
const cmd = { init: keyInit, migrate: keyMigrate, passwd: keyPasswd }[sub];
|
|
208
|
-
if (!cmd) {
|
|
209
|
-
console.error(`Unknown key subcommand: ${sub}`);
|
|
210
|
-
process.exit(1);
|
|
211
|
-
}
|
|
212
|
-
cmd().catch(err => { console.error(err.message); process.exit(1); });
|
|
213
|
-
}
|
|
214
|
-
//# sourceMappingURL=abmind-key.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abmind-key.js","sourceRoot":"","sources":["../../cli/abmind-key.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abmind-memory-stats.d.ts","sourceRoot":"","sources":["../../cli/abmind-memory-stats.ts"],"names":[],"mappings":""}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/** abmind memory-stats โ Show memory system stats. */
|
|
3
|
-
import { runCliRaw } from "../src/cli-runner-raw.js";
|
|
4
|
-
import { loadMemoryConfig } from "../src/memory-config.js";
|
|
5
|
-
import { MemoryManager } from "../src/memory-manager.js";
|
|
6
|
-
await runCliRaw(import.meta.url, {
|
|
7
|
-
name: "abmind-memory-stats",
|
|
8
|
-
help: `Usage:
|
|
9
|
-
abmind memory-stats
|
|
10
|
-
|
|
11
|
-
Prints memory-system stats: message count, memory count, DB size,
|
|
12
|
-
heartbeat state, per-type breakdown, consolidation-file counts.`,
|
|
13
|
-
flags: [],
|
|
14
|
-
handler: async () => {
|
|
15
|
-
const memory = new MemoryManager(loadMemoryConfig());
|
|
16
|
-
await memory.initialize({ skipEmbeddingCheck: true });
|
|
17
|
-
try {
|
|
18
|
-
const stats = memory.getStats();
|
|
19
|
-
if (!stats) {
|
|
20
|
-
console.error("Memory not initialized");
|
|
21
|
-
process.exitCode = 1;
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
console.log(`Memory Status
|
|
25
|
-
โโโโโโโโโโโโโ
|
|
26
|
-
Messages: ${stats.totalMessages}
|
|
27
|
-
Memories: ${stats.extractedMemories}
|
|
28
|
-
DB size: ${(stats.dbSizeBytes / 1024 / 1024).toFixed(1)} MB
|
|
29
|
-
Heartbeat: ${stats.heartbeatRunning ? "running" : "stopped"}
|
|
30
|
-
|
|
31
|
-
By type:`);
|
|
32
|
-
for (const [type, count] of Object.entries(stats.extractedByType)) {
|
|
33
|
-
console.log(` ${type}: ${count}`);
|
|
34
|
-
}
|
|
35
|
-
console.log(`\nConsolidation files:
|
|
36
|
-
Daily: ${stats.consolidationFiles.daily}
|
|
37
|
-
Weekly: ${stats.consolidationFiles.weekly}
|
|
38
|
-
Quarterly: ${stats.consolidationFiles.quarterly}`);
|
|
39
|
-
}
|
|
40
|
-
finally {
|
|
41
|
-
memory.close();
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
//# sourceMappingURL=abmind-memory-stats.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abmind-memory-stats.js","sourceRoot":"","sources":["../../cli/abmind-memory-stats.ts"],"names":[],"mappings":";AACA,sDAAsD;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IAC/B,IAAI,EAAE,qBAAqB;IAC3B,IAAI,EAAE;;;;gEAIwD;IAC9D,KAAK,EAAE,EAAE;IACT,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACrD,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,EAAE,CAAC;gBAAC,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;gBAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBAAC,OAAO;YAAC,CAAC;YAEtF,OAAO,CAAC,GAAG,CAAC;;gBAEF,KAAK,CAAC,aAAa;gBACnB,KAAK,CAAC,iBAAiB;gBACvB,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC5C,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;;SAErD,CAAC,CAAC;YACL,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;gBAClE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;YACrC,CAAC;YACD,OAAO,CAAC,GAAG,CAAC;eACH,KAAK,CAAC,kBAAkB,CAAC,KAAK;eAC9B,KAAK,CAAC,kBAAkB,CAAC,MAAM;eAC/B,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,CAAC,CAAC;QACjD,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* abmind reset --scope <config|config+data|full>
|
|
4
|
-
*
|
|
5
|
-
* Mirrors agentbridge reset for the abmind runtime.
|
|
6
|
-
* - config โ wipe config/ only
|
|
7
|
-
* - config+data โ wipe config/ + memory/ + topics/
|
|
8
|
-
* - full โ wipe ~/.abmind/ entirely + remove PATH symlinks we own
|
|
9
|
-
*/
|
|
10
|
-
export {};
|
|
11
|
-
//# sourceMappingURL=abmind-reset.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abmind-reset.d.ts","sourceRoot":"","sources":["../../cli/abmind-reset.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}
|
package/dist/cli/abmind-reset.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* abmind reset --scope <config|config+data|full>
|
|
4
|
-
*
|
|
5
|
-
* Mirrors agentbridge reset for the abmind runtime.
|
|
6
|
-
* - config โ wipe config/ only
|
|
7
|
-
* - config+data โ wipe config/ + memory/ + topics/
|
|
8
|
-
* - full โ wipe ~/.abmind/ entirely + remove PATH symlinks we own
|
|
9
|
-
*/
|
|
10
|
-
import { mkdir } from 'node:fs/promises';
|
|
11
|
-
import { createInterface } from 'node:readline/promises';
|
|
12
|
-
import { basename, dirname, join } from 'node:path';
|
|
13
|
-
import { isUnsafeRemovalTarget, packagePaths, readManifest, removePath, resolveUserBinDir, safeCopyTree } from '../src/deploy-lib/index.js';
|
|
14
|
-
const OWNED_PATH_LINKS = ['abmind', 'abmind-embed'];
|
|
15
|
-
function scopePaths(home, scope) {
|
|
16
|
-
if (scope === 'config')
|
|
17
|
-
return [join(home, 'config')];
|
|
18
|
-
if (scope === 'config+data') {
|
|
19
|
-
return [join(home, 'config'), join(home, 'memory'), join(home, 'topics')];
|
|
20
|
-
}
|
|
21
|
-
return [home];
|
|
22
|
-
}
|
|
23
|
-
async function promptYesNo(q) {
|
|
24
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
25
|
-
try {
|
|
26
|
-
const a = (await rl.question(`${q} [y/N] `)).trim().toLowerCase();
|
|
27
|
-
return a === 'y' || a === 'yes';
|
|
28
|
-
}
|
|
29
|
-
finally {
|
|
30
|
-
rl.close();
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
async function removePathLinks(dryRun) {
|
|
34
|
-
const userBinDir = resolveUserBinDir();
|
|
35
|
-
const paths = packagePaths('abmind');
|
|
36
|
-
const { lstat, readlink, unlink } = await import('node:fs/promises');
|
|
37
|
-
const removed = [];
|
|
38
|
-
for (const name of OWNED_PATH_LINKS) {
|
|
39
|
-
const link = join(userBinDir, name);
|
|
40
|
-
const expectedTarget = join(paths.bin, name);
|
|
41
|
-
try {
|
|
42
|
-
const s = await lstat(link);
|
|
43
|
-
if (!s.isSymbolicLink())
|
|
44
|
-
continue;
|
|
45
|
-
const target = await readlink(link);
|
|
46
|
-
// Exact-match only. Don't clobber a symlink to a DIFFERENT install
|
|
47
|
-
// just because both paths contain '.abmind/bin/'.
|
|
48
|
-
if (target !== expectedTarget)
|
|
49
|
-
continue;
|
|
50
|
-
if (dryRun)
|
|
51
|
-
removed.push(`[dry-run] rm ${link}`);
|
|
52
|
-
else {
|
|
53
|
-
await unlink(link);
|
|
54
|
-
removed.push(link);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
catch (err) {
|
|
58
|
-
if (err.code !== 'ENOENT')
|
|
59
|
-
throw err;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
return removed;
|
|
63
|
-
}
|
|
64
|
-
function parseFlags(argv) {
|
|
65
|
-
const scope = argv.includes('--scope') ? argv[argv.indexOf('--scope') + 1] : undefined;
|
|
66
|
-
return {
|
|
67
|
-
scope,
|
|
68
|
-
yes: argv.includes('--yes'),
|
|
69
|
-
dryRun: argv.includes('--dry-run'),
|
|
70
|
-
nonInteractive: argv.includes('--non-interactive'),
|
|
71
|
-
noBackup: argv.includes('--no-backup'),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
async function run() {
|
|
75
|
-
const opts = parseFlags(process.argv.slice(3));
|
|
76
|
-
if (!opts.scope) {
|
|
77
|
-
process.stderr.write(`error: --scope required. One of: config | config+data | full\n`);
|
|
78
|
-
return 2;
|
|
79
|
-
}
|
|
80
|
-
const paths = packagePaths('abmind');
|
|
81
|
-
const manifest = await readManifest(paths.manifest);
|
|
82
|
-
const targets = scopePaths(paths.home, opts.scope);
|
|
83
|
-
for (const t of targets) {
|
|
84
|
-
if (isUnsafeRemovalTarget(t)) {
|
|
85
|
-
process.stderr.write(`refused: target ${t} is unsafe\n`);
|
|
86
|
-
return 3;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
process.stdout.write(`abmind reset --scope ${opts.scope}${opts.dryRun ? ' (DRY-RUN)' : ''}\n`);
|
|
90
|
-
if (manifest)
|
|
91
|
-
process.stdout.write(` current: ${manifest.version || '(unset)'}\n`);
|
|
92
|
-
for (const t of targets)
|
|
93
|
-
process.stdout.write(` - ${t}\n`);
|
|
94
|
-
if (opts.scope === 'full') {
|
|
95
|
-
process.stdout.write(` plus PATH symlinks:\n`);
|
|
96
|
-
for (const n of OWNED_PATH_LINKS)
|
|
97
|
-
process.stdout.write(` - ${join(resolveUserBinDir(), n)}\n`);
|
|
98
|
-
}
|
|
99
|
-
if (!opts.dryRun) {
|
|
100
|
-
if (opts.yes) {
|
|
101
|
-
// proceed
|
|
102
|
-
}
|
|
103
|
-
else if (opts.nonInteractive) {
|
|
104
|
-
process.stderr.write(`refused: --non-interactive requires --yes for destructive ops\n`);
|
|
105
|
-
return 4;
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
if (!(await promptYesNo('Proceed?'))) {
|
|
109
|
-
process.stdout.write(`aborted\n`);
|
|
110
|
-
return 1;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (opts.scope === 'full' && !opts.noBackup && !opts.dryRun) {
|
|
115
|
-
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
116
|
-
const backup = join(dirname(paths.home), `${basename(paths.home)}.reset-${ts}.bak`);
|
|
117
|
-
// safeCopyTree skips sockets/FIFOs โ real ~/.abmind has memory.sock.
|
|
118
|
-
await safeCopyTree(paths.home, backup, { preserveTimestamps: true });
|
|
119
|
-
process.stdout.write(`โ backup at ${backup}\n`);
|
|
120
|
-
}
|
|
121
|
-
for (const t of targets) {
|
|
122
|
-
const removed = await removePath(t, { dryRun: opts.dryRun });
|
|
123
|
-
process.stdout.write(`${opts.dryRun ? '[dry-run] ' : ''}${removed ? 'โ' : 'ยท'} ${t}\n`);
|
|
124
|
-
}
|
|
125
|
-
if (opts.scope === 'full') {
|
|
126
|
-
const linksRemoved = await removePathLinks(opts.dryRun);
|
|
127
|
-
for (const l of linksRemoved)
|
|
128
|
-
process.stdout.write(`โ ${l}\n`);
|
|
129
|
-
}
|
|
130
|
-
process.stdout.write(`\nabmind reset complete.\n`);
|
|
131
|
-
// Quiet unused-import checker.
|
|
132
|
-
void mkdir;
|
|
133
|
-
return 0;
|
|
134
|
-
}
|
|
135
|
-
try {
|
|
136
|
-
const exitCode = await run();
|
|
137
|
-
process.exit(exitCode);
|
|
138
|
-
}
|
|
139
|
-
catch (err) {
|
|
140
|
-
process.stderr.write(`error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
141
|
-
process.exit(1);
|
|
142
|
-
}
|
|
143
|
-
//# sourceMappingURL=abmind-reset.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abmind-reset.js","sourceRoot":"","sources":["../../cli/abmind-reset.ts"],"names":[],"mappings":"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"}
|