@hasna/brains 0.0.29 → 0.0.31
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/dist/cli/index.js +90 -26
- package/dist/index.js +61 -11
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/gatherers/mementos.d.ts.map +1 -1
- package/dist/lib/gatherers/tags.d.ts +2 -0
- package/dist/lib/gatherers/tags.d.ts.map +1 -0
- package/dist/lib/gatherers/todos.d.ts.map +1 -1
- package/dist/lib/gatherers/types.d.ts +1 -0
- package/dist/lib/gatherers/types.d.ts.map +1 -1
- package/dist/mcp/index.js +63 -14
- package/dist/server/index.js +22 -6
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -13151,6 +13151,20 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
|
|
|
13151
13151
|
init_adapter();
|
|
13152
13152
|
});
|
|
13153
13153
|
|
|
13154
|
+
// src/lib/gatherers/tags.ts
|
|
13155
|
+
function parseTagList(value) {
|
|
13156
|
+
if (!value?.trim())
|
|
13157
|
+
return [];
|
|
13158
|
+
try {
|
|
13159
|
+
const parsed = JSON.parse(value);
|
|
13160
|
+
if (!Array.isArray(parsed))
|
|
13161
|
+
return [];
|
|
13162
|
+
return parsed.filter((tag) => typeof tag === "string");
|
|
13163
|
+
} catch {
|
|
13164
|
+
return [];
|
|
13165
|
+
}
|
|
13166
|
+
}
|
|
13167
|
+
|
|
13154
13168
|
// src/lib/gatherers/todos.ts
|
|
13155
13169
|
var exports_todos = {};
|
|
13156
13170
|
__export(exports_todos, {
|
|
@@ -13169,7 +13183,7 @@ Description: ${task.description}` : ""}`;
|
|
|
13169
13183
|
description: task.description ?? "",
|
|
13170
13184
|
status: task.status,
|
|
13171
13185
|
priority: task.priority,
|
|
13172
|
-
tags:
|
|
13186
|
+
tags: parseTagList(task.tags),
|
|
13173
13187
|
created_at: task.created_at
|
|
13174
13188
|
};
|
|
13175
13189
|
return {
|
|
@@ -13208,7 +13222,7 @@ ${matched.map((t) => `- [${t.short_id ?? t.id}] ${t.title} (${t.status})`).join(
|
|
|
13208
13222
|
};
|
|
13209
13223
|
}
|
|
13210
13224
|
async function gatherFromTodos(options = {}) {
|
|
13211
|
-
const dbPath = join9(homedir8(), ".todos", "todos.db");
|
|
13225
|
+
const dbPath = join9(options.homeDir ?? homedir8(), ".todos", "todos.db");
|
|
13212
13226
|
const db = new Database3(dbPath, { readonly: true, create: false });
|
|
13213
13227
|
try {
|
|
13214
13228
|
let query = "SELECT * FROM tasks WHERE 1=1";
|
|
@@ -13270,7 +13284,7 @@ Summary: ${memory.summary}` : memory.value
|
|
|
13270
13284
|
};
|
|
13271
13285
|
}
|
|
13272
13286
|
function memoryToSaveExample(memory) {
|
|
13273
|
-
const tags =
|
|
13287
|
+
const tags = parseTagList(memory.tags);
|
|
13274
13288
|
return {
|
|
13275
13289
|
messages: [
|
|
13276
13290
|
{ role: "system", content: SYSTEM_PROMPT2 },
|
|
@@ -13301,7 +13315,7 @@ ${matched.map((m) => `- ${m.key}: ${m.value.slice(0, 120)}${m.value.length > 120
|
|
|
13301
13315
|
};
|
|
13302
13316
|
}
|
|
13303
13317
|
async function gatherFromMementos(options = {}) {
|
|
13304
|
-
const dbPath = join10(homedir9(), ".mementos", "mementos.db");
|
|
13318
|
+
const dbPath = join10(options.homeDir ?? homedir9(), ".mementos", "mementos.db");
|
|
13305
13319
|
const db = new Database4(dbPath, { readonly: true, create: false });
|
|
13306
13320
|
try {
|
|
13307
13321
|
let query = "SELECT * FROM memories WHERE status = 'active'";
|
|
@@ -13372,7 +13386,7 @@ function windowToExample(window2) {
|
|
|
13372
13386
|
return { messages };
|
|
13373
13387
|
}
|
|
13374
13388
|
async function gatherFromConversations(options = {}) {
|
|
13375
|
-
const dbPath = join11(homedir10(), ".conversations", "messages.db");
|
|
13389
|
+
const dbPath = join11(options.homeDir ?? homedir10(), ".conversations", "messages.db");
|
|
13376
13390
|
const db = new Database5(dbPath, { readonly: true, create: false });
|
|
13377
13391
|
try {
|
|
13378
13392
|
let query = "SELECT * FROM messages WHERE 1=1";
|
|
@@ -13433,7 +13447,7 @@ function extractText(content) {
|
|
|
13433
13447
|
async function gatherFromSessions(options = {}) {
|
|
13434
13448
|
const { limit: limit2 = 1000 } = options;
|
|
13435
13449
|
const examples = [];
|
|
13436
|
-
const claudeDir = join12(homedir11(), ".claude", "projects");
|
|
13450
|
+
const claudeDir = join12(options.homeDir ?? homedir11(), ".claude", "projects");
|
|
13437
13451
|
if (!existsSync10(claudeDir)) {
|
|
13438
13452
|
return { source: "sessions", examples: [], count: 0 };
|
|
13439
13453
|
}
|
|
@@ -18128,7 +18142,7 @@ function printInfo(message) {
|
|
|
18128
18142
|
}
|
|
18129
18143
|
|
|
18130
18144
|
// src/cli/commands/models.ts
|
|
18131
|
-
import { randomUUID as
|
|
18145
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
18132
18146
|
|
|
18133
18147
|
// node_modules/openai/internal/qs/formats.mjs
|
|
18134
18148
|
var default_format = "RFC3986";
|
|
@@ -23618,16 +23632,48 @@ var openai_default = OpenAI;
|
|
|
23618
23632
|
import { readFileSync as readFileSync5 } from "fs";
|
|
23619
23633
|
|
|
23620
23634
|
// src/lib/config.ts
|
|
23621
|
-
import {
|
|
23635
|
+
import {
|
|
23636
|
+
chmodSync,
|
|
23637
|
+
copyFileSync as copyFileSync2,
|
|
23638
|
+
existsSync as existsSync7,
|
|
23639
|
+
lstatSync,
|
|
23640
|
+
mkdirSync as mkdirSync4,
|
|
23641
|
+
readFileSync as readFileSync3,
|
|
23642
|
+
readdirSync as readdirSync4,
|
|
23643
|
+
renameSync,
|
|
23644
|
+
statSync,
|
|
23645
|
+
unlinkSync as unlinkSync2,
|
|
23646
|
+
writeFileSync as writeFileSync3
|
|
23647
|
+
} from "fs";
|
|
23648
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
23622
23649
|
import { join as join7, dirname as dirname2 } from "path";
|
|
23623
23650
|
import { homedir as homedir6 } from "os";
|
|
23624
23651
|
var CONFIG_KEYS = ["OPENAI_API_KEY", "THINKER_LABS_API_KEY", "THINKER_LABS_BASE_URL"];
|
|
23652
|
+
var CONFIG_FILE_NAME = "config.json";
|
|
23653
|
+
function restrictConfigFilePermissions(configPath) {
|
|
23654
|
+
try {
|
|
23655
|
+
if (!lstatSync(configPath).isFile())
|
|
23656
|
+
return;
|
|
23657
|
+
chmodSync(configPath, 384);
|
|
23658
|
+
} catch {}
|
|
23659
|
+
}
|
|
23660
|
+
function ensureConfigDirectory(dirPath) {
|
|
23661
|
+
mkdirSync4(dirPath, { recursive: true, mode: 448 });
|
|
23662
|
+
try {
|
|
23663
|
+
if (!statSync(dirPath).isDirectory())
|
|
23664
|
+
return;
|
|
23665
|
+
chmodSync(dirPath, 448);
|
|
23666
|
+
} catch {}
|
|
23667
|
+
}
|
|
23625
23668
|
function resolveConfigPath() {
|
|
23626
23669
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir6();
|
|
23627
|
-
const
|
|
23670
|
+
const hasnaDir = join7(home, ".hasna");
|
|
23671
|
+
const newDir = join7(hasnaDir, "brains");
|
|
23628
23672
|
const oldDir = join7(home, ".brains");
|
|
23673
|
+
const configPath = join7(newDir, CONFIG_FILE_NAME);
|
|
23674
|
+
ensureConfigDirectory(hasnaDir);
|
|
23629
23675
|
if (existsSync7(oldDir) && !existsSync7(newDir)) {
|
|
23630
|
-
|
|
23676
|
+
ensureConfigDirectory(newDir);
|
|
23631
23677
|
try {
|
|
23632
23678
|
for (const file of readdirSync4(oldDir)) {
|
|
23633
23679
|
const oldPath = join7(oldDir, file);
|
|
@@ -23635,28 +23681,46 @@ function resolveConfigPath() {
|
|
|
23635
23681
|
try {
|
|
23636
23682
|
if (statSync(oldPath).isFile()) {
|
|
23637
23683
|
copyFileSync2(oldPath, newPath);
|
|
23684
|
+
if (file === CONFIG_FILE_NAME)
|
|
23685
|
+
restrictConfigFilePermissions(newPath);
|
|
23638
23686
|
}
|
|
23639
23687
|
} catch {}
|
|
23640
23688
|
}
|
|
23641
23689
|
} catch {}
|
|
23642
23690
|
}
|
|
23643
|
-
|
|
23644
|
-
return
|
|
23691
|
+
ensureConfigDirectory(newDir);
|
|
23692
|
+
return configPath;
|
|
23645
23693
|
}
|
|
23646
|
-
var CONFIG_PATH2 = resolveConfigPath();
|
|
23647
23694
|
function readConfigFile() {
|
|
23648
|
-
|
|
23695
|
+
const configPath = resolveConfigPath();
|
|
23696
|
+
if (!existsSync7(configPath))
|
|
23649
23697
|
return {};
|
|
23650
23698
|
try {
|
|
23651
|
-
return JSON.parse(readFileSync3(
|
|
23699
|
+
return JSON.parse(readFileSync3(configPath, "utf-8"));
|
|
23652
23700
|
} catch {
|
|
23653
23701
|
return {};
|
|
23654
23702
|
}
|
|
23655
23703
|
}
|
|
23656
23704
|
function writeConfigFile(data) {
|
|
23657
|
-
|
|
23658
|
-
|
|
23659
|
-
|
|
23705
|
+
const configPath = resolveConfigPath();
|
|
23706
|
+
const configDir = dirname2(configPath);
|
|
23707
|
+
const tempPath = join7(configDir, `.config.json.${randomUUID3()}.tmp`);
|
|
23708
|
+
ensureConfigDirectory(configDir);
|
|
23709
|
+
if (existsSync7(configPath))
|
|
23710
|
+
restrictConfigFilePermissions(configPath);
|
|
23711
|
+
try {
|
|
23712
|
+
writeFileSync3(tempPath, JSON.stringify(data, null, 2) + `
|
|
23713
|
+
`, { encoding: "utf-8", mode: 384, flag: "wx" });
|
|
23714
|
+
restrictConfigFilePermissions(tempPath);
|
|
23715
|
+
renameSync(tempPath, configPath);
|
|
23716
|
+
restrictConfigFilePermissions(configPath);
|
|
23717
|
+
} catch (err) {
|
|
23718
|
+
try {
|
|
23719
|
+
if (existsSync7(tempPath))
|
|
23720
|
+
unlinkSync2(tempPath);
|
|
23721
|
+
} catch {}
|
|
23722
|
+
throw err;
|
|
23723
|
+
}
|
|
23660
23724
|
}
|
|
23661
23725
|
function getConfigValue(key) {
|
|
23662
23726
|
if (process.env[key])
|
|
@@ -24068,7 +24132,7 @@ function registerModelsCommands(program2) {
|
|
|
24068
24132
|
printInfo(`Model already tracked as: ${existing.id}`);
|
|
24069
24133
|
return;
|
|
24070
24134
|
}
|
|
24071
|
-
const modelId =
|
|
24135
|
+
const modelId = randomUUID5();
|
|
24072
24136
|
const now2 = Date.now();
|
|
24073
24137
|
const name = opts.name ?? result.fineTunedModel ?? `imported-${jobId}`;
|
|
24074
24138
|
await db.insert(fineTunedModels).values({
|
|
@@ -24082,7 +24146,7 @@ function registerModelsCommands(program2) {
|
|
|
24082
24146
|
updatedAt: now2
|
|
24083
24147
|
});
|
|
24084
24148
|
await db.insert(trainingJobs).values({
|
|
24085
|
-
id:
|
|
24149
|
+
id: randomUUID5(),
|
|
24086
24150
|
modelId,
|
|
24087
24151
|
provider: opts.provider,
|
|
24088
24152
|
status: result.status,
|
|
@@ -24105,7 +24169,7 @@ function registerModelsCommands(program2) {
|
|
|
24105
24169
|
}
|
|
24106
24170
|
|
|
24107
24171
|
// src/cli/commands/finetune.ts
|
|
24108
|
-
import { randomUUID as
|
|
24172
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
24109
24173
|
import { existsSync as existsSync9 } from "fs";
|
|
24110
24174
|
function registerFinetuneCommands(program2) {
|
|
24111
24175
|
const finetuneCmd = program2.command("finetune").description("Manage fine-tuning jobs");
|
|
@@ -24147,7 +24211,7 @@ function registerFinetuneCommands(program2) {
|
|
|
24147
24211
|
({ jobId, status: jobStatus } = await tl.createFineTuneJob(fileId, opts.baseModel, opts.name));
|
|
24148
24212
|
}
|
|
24149
24213
|
const db = getDb();
|
|
24150
|
-
const modelId =
|
|
24214
|
+
const modelId = randomUUID6();
|
|
24151
24215
|
const now2 = Date.now();
|
|
24152
24216
|
await db.insert(fineTunedModels).values({
|
|
24153
24217
|
id: modelId,
|
|
@@ -24159,7 +24223,7 @@ function registerFinetuneCommands(program2) {
|
|
|
24159
24223
|
createdAt: now2,
|
|
24160
24224
|
updatedAt: now2
|
|
24161
24225
|
});
|
|
24162
|
-
const trainingJobId =
|
|
24226
|
+
const trainingJobId = randomUUID6();
|
|
24163
24227
|
await db.insert(trainingJobs).values({
|
|
24164
24228
|
id: trainingJobId,
|
|
24165
24229
|
modelId,
|
|
@@ -24299,7 +24363,7 @@ function registerFinetuneCommands(program2) {
|
|
|
24299
24363
|
}
|
|
24300
24364
|
|
|
24301
24365
|
// src/cli/commands/data.ts
|
|
24302
|
-
import { randomUUID as
|
|
24366
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
24303
24367
|
import { readFileSync as readFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
24304
24368
|
import { dirname as dirname3, join as join13 } from "path";
|
|
24305
24369
|
import { homedir as homedir12 } from "os";
|
|
@@ -24349,7 +24413,7 @@ function registerDataCommands(program2) {
|
|
|
24349
24413
|
`) + `
|
|
24350
24414
|
`, "utf8");
|
|
24351
24415
|
await db.insert(trainingDatasets).values({
|
|
24352
|
-
id:
|
|
24416
|
+
id: randomUUID7(),
|
|
24353
24417
|
source,
|
|
24354
24418
|
filePath,
|
|
24355
24419
|
exampleCount: count,
|
|
@@ -24439,7 +24503,7 @@ function registerDataCommands(program2) {
|
|
|
24439
24503
|
`, "utf8");
|
|
24440
24504
|
const db = getDb();
|
|
24441
24505
|
await db.insert(trainingDatasets).values({
|
|
24442
|
-
id:
|
|
24506
|
+
id: randomUUID7(),
|
|
24443
24507
|
source: "mixed",
|
|
24444
24508
|
filePath: opts.output,
|
|
24445
24509
|
exampleCount: finalLines.length,
|
package/dist/index.js
CHANGED
|
@@ -18984,16 +18984,48 @@ var openai_default = OpenAI;
|
|
|
18984
18984
|
import { readFileSync as readFileSync3 } from "fs";
|
|
18985
18985
|
|
|
18986
18986
|
// src/lib/config.ts
|
|
18987
|
-
import {
|
|
18987
|
+
import {
|
|
18988
|
+
chmodSync,
|
|
18989
|
+
copyFileSync as copyFileSync2,
|
|
18990
|
+
existsSync as existsSync3,
|
|
18991
|
+
lstatSync,
|
|
18992
|
+
mkdirSync as mkdirSync3,
|
|
18993
|
+
readFileSync as readFileSync2,
|
|
18994
|
+
readdirSync as readdirSync2,
|
|
18995
|
+
renameSync,
|
|
18996
|
+
statSync,
|
|
18997
|
+
unlinkSync,
|
|
18998
|
+
writeFileSync as writeFileSync2
|
|
18999
|
+
} from "fs";
|
|
19000
|
+
import { randomUUID } from "crypto";
|
|
18988
19001
|
import { join as join4, dirname as dirname2 } from "path";
|
|
18989
19002
|
import { homedir as homedir6 } from "os";
|
|
18990
19003
|
var CONFIG_KEYS = ["OPENAI_API_KEY", "THINKER_LABS_API_KEY", "THINKER_LABS_BASE_URL"];
|
|
19004
|
+
var CONFIG_FILE_NAME = "config.json";
|
|
19005
|
+
function restrictConfigFilePermissions(configPath) {
|
|
19006
|
+
try {
|
|
19007
|
+
if (!lstatSync(configPath).isFile())
|
|
19008
|
+
return;
|
|
19009
|
+
chmodSync(configPath, 384);
|
|
19010
|
+
} catch {}
|
|
19011
|
+
}
|
|
19012
|
+
function ensureConfigDirectory(dirPath) {
|
|
19013
|
+
mkdirSync3(dirPath, { recursive: true, mode: 448 });
|
|
19014
|
+
try {
|
|
19015
|
+
if (!statSync(dirPath).isDirectory())
|
|
19016
|
+
return;
|
|
19017
|
+
chmodSync(dirPath, 448);
|
|
19018
|
+
} catch {}
|
|
19019
|
+
}
|
|
18991
19020
|
function resolveConfigPath() {
|
|
18992
19021
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir6();
|
|
18993
|
-
const
|
|
19022
|
+
const hasnaDir = join4(home, ".hasna");
|
|
19023
|
+
const newDir = join4(hasnaDir, "brains");
|
|
18994
19024
|
const oldDir = join4(home, ".brains");
|
|
19025
|
+
const configPath = join4(newDir, CONFIG_FILE_NAME);
|
|
19026
|
+
ensureConfigDirectory(hasnaDir);
|
|
18995
19027
|
if (existsSync3(oldDir) && !existsSync3(newDir)) {
|
|
18996
|
-
|
|
19028
|
+
ensureConfigDirectory(newDir);
|
|
18997
19029
|
try {
|
|
18998
19030
|
for (const file of readdirSync2(oldDir)) {
|
|
18999
19031
|
const oldPath = join4(oldDir, file);
|
|
@@ -19001,28 +19033,46 @@ function resolveConfigPath() {
|
|
|
19001
19033
|
try {
|
|
19002
19034
|
if (statSync(oldPath).isFile()) {
|
|
19003
19035
|
copyFileSync2(oldPath, newPath);
|
|
19036
|
+
if (file === CONFIG_FILE_NAME)
|
|
19037
|
+
restrictConfigFilePermissions(newPath);
|
|
19004
19038
|
}
|
|
19005
19039
|
} catch {}
|
|
19006
19040
|
}
|
|
19007
19041
|
} catch {}
|
|
19008
19042
|
}
|
|
19009
|
-
|
|
19010
|
-
return
|
|
19043
|
+
ensureConfigDirectory(newDir);
|
|
19044
|
+
return configPath;
|
|
19011
19045
|
}
|
|
19012
|
-
var CONFIG_PATH2 = resolveConfigPath();
|
|
19013
19046
|
function readConfigFile() {
|
|
19014
|
-
|
|
19047
|
+
const configPath = resolveConfigPath();
|
|
19048
|
+
if (!existsSync3(configPath))
|
|
19015
19049
|
return {};
|
|
19016
19050
|
try {
|
|
19017
|
-
return JSON.parse(readFileSync2(
|
|
19051
|
+
return JSON.parse(readFileSync2(configPath, "utf-8"));
|
|
19018
19052
|
} catch {
|
|
19019
19053
|
return {};
|
|
19020
19054
|
}
|
|
19021
19055
|
}
|
|
19022
19056
|
function writeConfigFile(data) {
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
|
|
19057
|
+
const configPath = resolveConfigPath();
|
|
19058
|
+
const configDir = dirname2(configPath);
|
|
19059
|
+
const tempPath = join4(configDir, `.config.json.${randomUUID()}.tmp`);
|
|
19060
|
+
ensureConfigDirectory(configDir);
|
|
19061
|
+
if (existsSync3(configPath))
|
|
19062
|
+
restrictConfigFilePermissions(configPath);
|
|
19063
|
+
try {
|
|
19064
|
+
writeFileSync2(tempPath, JSON.stringify(data, null, 2) + `
|
|
19065
|
+
`, { encoding: "utf-8", mode: 384, flag: "wx" });
|
|
19066
|
+
restrictConfigFilePermissions(tempPath);
|
|
19067
|
+
renameSync(tempPath, configPath);
|
|
19068
|
+
restrictConfigFilePermissions(configPath);
|
|
19069
|
+
} catch (err) {
|
|
19070
|
+
try {
|
|
19071
|
+
if (existsSync3(tempPath))
|
|
19072
|
+
unlinkSync(tempPath);
|
|
19073
|
+
} catch {}
|
|
19074
|
+
throw err;
|
|
19075
|
+
}
|
|
19026
19076
|
}
|
|
19027
19077
|
function getConfigValue(key) {
|
|
19028
19078
|
if (process.env[key])
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,WAAW,8EAA+E,CAAC;AACxG,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAuFrD,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAIjE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAIlE;AAED,wBAAgB,UAAU,IAAI,KAAK,CAAC;IAAE,GAAG,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC,CAOvG;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAItD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mementos.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/mementos.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"mementos.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/mementos.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAA;AAsEhF,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CA4C7F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/tags.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,CAUvE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"todos.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/todos.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"todos.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/todos.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAA;AAsEhF,wBAAsB,eAAe,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CA+C1F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAA;QACrC,OAAO,EAAE,MAAM,CAAA;KAChB,CAAC,CAAA;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAA;QACrC,OAAO,EAAE,MAAM,CAAA;KAChB,CAAC,CAAA;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -19495,15 +19495,46 @@ var openai_default = OpenAI;
|
|
|
19495
19495
|
import { readFileSync as readFileSync3 } from "fs";
|
|
19496
19496
|
|
|
19497
19497
|
// src/lib/config.ts
|
|
19498
|
-
import {
|
|
19498
|
+
import {
|
|
19499
|
+
chmodSync,
|
|
19500
|
+
copyFileSync as copyFileSync2,
|
|
19501
|
+
existsSync as existsSync3,
|
|
19502
|
+
lstatSync,
|
|
19503
|
+
mkdirSync as mkdirSync3,
|
|
19504
|
+
readFileSync as readFileSync2,
|
|
19505
|
+
readdirSync as readdirSync2,
|
|
19506
|
+
renameSync,
|
|
19507
|
+
statSync,
|
|
19508
|
+
unlinkSync,
|
|
19509
|
+
writeFileSync as writeFileSync2
|
|
19510
|
+
} from "fs";
|
|
19499
19511
|
import { join as join4, dirname as dirname2 } from "path";
|
|
19500
19512
|
import { homedir as homedir6 } from "os";
|
|
19513
|
+
var CONFIG_FILE_NAME = "config.json";
|
|
19514
|
+
function restrictConfigFilePermissions(configPath) {
|
|
19515
|
+
try {
|
|
19516
|
+
if (!lstatSync(configPath).isFile())
|
|
19517
|
+
return;
|
|
19518
|
+
chmodSync(configPath, 384);
|
|
19519
|
+
} catch {}
|
|
19520
|
+
}
|
|
19521
|
+
function ensureConfigDirectory(dirPath) {
|
|
19522
|
+
mkdirSync3(dirPath, { recursive: true, mode: 448 });
|
|
19523
|
+
try {
|
|
19524
|
+
if (!statSync(dirPath).isDirectory())
|
|
19525
|
+
return;
|
|
19526
|
+
chmodSync(dirPath, 448);
|
|
19527
|
+
} catch {}
|
|
19528
|
+
}
|
|
19501
19529
|
function resolveConfigPath() {
|
|
19502
19530
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir6();
|
|
19503
|
-
const
|
|
19531
|
+
const hasnaDir = join4(home, ".hasna");
|
|
19532
|
+
const newDir = join4(hasnaDir, "brains");
|
|
19504
19533
|
const oldDir = join4(home, ".brains");
|
|
19534
|
+
const configPath = join4(newDir, CONFIG_FILE_NAME);
|
|
19535
|
+
ensureConfigDirectory(hasnaDir);
|
|
19505
19536
|
if (existsSync3(oldDir) && !existsSync3(newDir)) {
|
|
19506
|
-
|
|
19537
|
+
ensureConfigDirectory(newDir);
|
|
19507
19538
|
try {
|
|
19508
19539
|
for (const file of readdirSync2(oldDir)) {
|
|
19509
19540
|
const oldPath = join4(oldDir, file);
|
|
@@ -19511,20 +19542,22 @@ function resolveConfigPath() {
|
|
|
19511
19542
|
try {
|
|
19512
19543
|
if (statSync(oldPath).isFile()) {
|
|
19513
19544
|
copyFileSync2(oldPath, newPath);
|
|
19545
|
+
if (file === CONFIG_FILE_NAME)
|
|
19546
|
+
restrictConfigFilePermissions(newPath);
|
|
19514
19547
|
}
|
|
19515
19548
|
} catch {}
|
|
19516
19549
|
}
|
|
19517
19550
|
} catch {}
|
|
19518
19551
|
}
|
|
19519
|
-
|
|
19520
|
-
return
|
|
19552
|
+
ensureConfigDirectory(newDir);
|
|
19553
|
+
return configPath;
|
|
19521
19554
|
}
|
|
19522
|
-
var CONFIG_PATH2 = resolveConfigPath();
|
|
19523
19555
|
function readConfigFile() {
|
|
19524
|
-
|
|
19556
|
+
const configPath = resolveConfigPath();
|
|
19557
|
+
if (!existsSync3(configPath))
|
|
19525
19558
|
return {};
|
|
19526
19559
|
try {
|
|
19527
|
-
return JSON.parse(readFileSync2(
|
|
19560
|
+
return JSON.parse(readFileSync2(configPath, "utf-8"));
|
|
19528
19561
|
} catch {
|
|
19529
19562
|
return {};
|
|
19530
19563
|
}
|
|
@@ -19756,6 +19789,22 @@ class ThinkerLabsProvider {
|
|
|
19756
19789
|
import { Database as Database3 } from "bun:sqlite";
|
|
19757
19790
|
import { homedir as homedir8 } from "os";
|
|
19758
19791
|
import { join as join7 } from "path";
|
|
19792
|
+
|
|
19793
|
+
// src/lib/gatherers/tags.ts
|
|
19794
|
+
function parseTagList(value) {
|
|
19795
|
+
if (!value?.trim())
|
|
19796
|
+
return [];
|
|
19797
|
+
try {
|
|
19798
|
+
const parsed = JSON.parse(value);
|
|
19799
|
+
if (!Array.isArray(parsed))
|
|
19800
|
+
return [];
|
|
19801
|
+
return parsed.filter((tag) => typeof tag === "string");
|
|
19802
|
+
} catch {
|
|
19803
|
+
return [];
|
|
19804
|
+
}
|
|
19805
|
+
}
|
|
19806
|
+
|
|
19807
|
+
// src/lib/gatherers/todos.ts
|
|
19759
19808
|
var SYSTEM_PROMPT = "You are a task management assistant that helps users create, update, search, and manage tasks and projects.";
|
|
19760
19809
|
function taskToCreateExample(task) {
|
|
19761
19810
|
const userMsg = `Create a task: ${task.title}${task.description ? `
|
|
@@ -19767,7 +19816,7 @@ Description: ${task.description}` : ""}`;
|
|
|
19767
19816
|
description: task.description ?? "",
|
|
19768
19817
|
status: task.status,
|
|
19769
19818
|
priority: task.priority,
|
|
19770
|
-
tags:
|
|
19819
|
+
tags: parseTagList(task.tags),
|
|
19771
19820
|
created_at: task.created_at
|
|
19772
19821
|
};
|
|
19773
19822
|
return {
|
|
@@ -19806,7 +19855,7 @@ ${matched.map((t) => `- [${t.short_id ?? t.id}] ${t.title} (${t.status})`).join(
|
|
|
19806
19855
|
};
|
|
19807
19856
|
}
|
|
19808
19857
|
async function gatherFromTodos(options = {}) {
|
|
19809
|
-
const dbPath = join7(homedir8(), ".todos", "todos.db");
|
|
19858
|
+
const dbPath = join7(options.homeDir ?? homedir8(), ".todos", "todos.db");
|
|
19810
19859
|
const db = new Database3(dbPath, { readonly: true, create: false });
|
|
19811
19860
|
try {
|
|
19812
19861
|
let query = "SELECT * FROM tasks WHERE 1=1";
|
|
@@ -19863,7 +19912,7 @@ Summary: ${memory.summary}` : memory.value
|
|
|
19863
19912
|
};
|
|
19864
19913
|
}
|
|
19865
19914
|
function memoryToSaveExample(memory) {
|
|
19866
|
-
const tags =
|
|
19915
|
+
const tags = parseTagList(memory.tags);
|
|
19867
19916
|
return {
|
|
19868
19917
|
messages: [
|
|
19869
19918
|
{ role: "system", content: SYSTEM_PROMPT2 },
|
|
@@ -19894,7 +19943,7 @@ ${matched.map((m) => `- ${m.key}: ${m.value.slice(0, 120)}${m.value.length > 120
|
|
|
19894
19943
|
};
|
|
19895
19944
|
}
|
|
19896
19945
|
async function gatherFromMementos(options = {}) {
|
|
19897
|
-
const dbPath = join9(homedir9(), ".mementos", "mementos.db");
|
|
19946
|
+
const dbPath = join9(options.homeDir ?? homedir9(), ".mementos", "mementos.db");
|
|
19898
19947
|
const db = new Database4(dbPath, { readonly: true, create: false });
|
|
19899
19948
|
try {
|
|
19900
19949
|
let query = "SELECT * FROM memories WHERE status = 'active'";
|
|
@@ -19960,7 +20009,7 @@ function windowToExample(window2) {
|
|
|
19960
20009
|
return { messages };
|
|
19961
20010
|
}
|
|
19962
20011
|
async function gatherFromConversations(options = {}) {
|
|
19963
|
-
const dbPath = join10(homedir10(), ".conversations", "messages.db");
|
|
20012
|
+
const dbPath = join10(options.homeDir ?? homedir10(), ".conversations", "messages.db");
|
|
19964
20013
|
const db = new Database5(dbPath, { readonly: true, create: false });
|
|
19965
20014
|
try {
|
|
19966
20015
|
let query = "SELECT * FROM messages WHERE 1=1";
|
|
@@ -20016,7 +20065,7 @@ function extractText(content) {
|
|
|
20016
20065
|
async function gatherFromSessions(options = {}) {
|
|
20017
20066
|
const { limit: limit2 = 1000 } = options;
|
|
20018
20067
|
const examples = [];
|
|
20019
|
-
const claudeDir = join11(homedir11(), ".claude", "projects");
|
|
20068
|
+
const claudeDir = join11(options.homeDir ?? homedir11(), ".claude", "projects");
|
|
20020
20069
|
if (!existsSync5(claudeDir)) {
|
|
20021
20070
|
return { source: "sessions", examples: [], count: 0 };
|
|
20022
20071
|
}
|
package/dist/server/index.js
CHANGED
|
@@ -13392,6 +13392,22 @@ function getPackageVersion() {
|
|
|
13392
13392
|
import { Database as Database3 } from "bun:sqlite";
|
|
13393
13393
|
import { homedir as homedir6 } from "os";
|
|
13394
13394
|
import { join as join4 } from "path";
|
|
13395
|
+
|
|
13396
|
+
// src/lib/gatherers/tags.ts
|
|
13397
|
+
function parseTagList(value) {
|
|
13398
|
+
if (!value?.trim())
|
|
13399
|
+
return [];
|
|
13400
|
+
try {
|
|
13401
|
+
const parsed = JSON.parse(value);
|
|
13402
|
+
if (!Array.isArray(parsed))
|
|
13403
|
+
return [];
|
|
13404
|
+
return parsed.filter((tag) => typeof tag === "string");
|
|
13405
|
+
} catch {
|
|
13406
|
+
return [];
|
|
13407
|
+
}
|
|
13408
|
+
}
|
|
13409
|
+
|
|
13410
|
+
// src/lib/gatherers/todos.ts
|
|
13395
13411
|
var SYSTEM_PROMPT = "You are a task management assistant that helps users create, update, search, and manage tasks and projects.";
|
|
13396
13412
|
function taskToCreateExample(task) {
|
|
13397
13413
|
const userMsg = `Create a task: ${task.title}${task.description ? `
|
|
@@ -13403,7 +13419,7 @@ Description: ${task.description}` : ""}`;
|
|
|
13403
13419
|
description: task.description ?? "",
|
|
13404
13420
|
status: task.status,
|
|
13405
13421
|
priority: task.priority,
|
|
13406
|
-
tags:
|
|
13422
|
+
tags: parseTagList(task.tags),
|
|
13407
13423
|
created_at: task.created_at
|
|
13408
13424
|
};
|
|
13409
13425
|
return {
|
|
@@ -13442,7 +13458,7 @@ ${matched.map((t) => `- [${t.short_id ?? t.id}] ${t.title} (${t.status})`).join(
|
|
|
13442
13458
|
};
|
|
13443
13459
|
}
|
|
13444
13460
|
async function gatherFromTodos(options = {}) {
|
|
13445
|
-
const dbPath = join4(homedir6(), ".todos", "todos.db");
|
|
13461
|
+
const dbPath = join4(options.homeDir ?? homedir6(), ".todos", "todos.db");
|
|
13446
13462
|
const db = new Database3(dbPath, { readonly: true, create: false });
|
|
13447
13463
|
try {
|
|
13448
13464
|
let query = "SELECT * FROM tasks WHERE 1=1";
|
|
@@ -13499,7 +13515,7 @@ Summary: ${memory.summary}` : memory.value
|
|
|
13499
13515
|
};
|
|
13500
13516
|
}
|
|
13501
13517
|
function memoryToSaveExample(memory) {
|
|
13502
|
-
const tags =
|
|
13518
|
+
const tags = parseTagList(memory.tags);
|
|
13503
13519
|
return {
|
|
13504
13520
|
messages: [
|
|
13505
13521
|
{ role: "system", content: SYSTEM_PROMPT2 },
|
|
@@ -13530,7 +13546,7 @@ ${matched.map((m) => `- ${m.key}: ${m.value.slice(0, 120)}${m.value.length > 120
|
|
|
13530
13546
|
};
|
|
13531
13547
|
}
|
|
13532
13548
|
async function gatherFromMementos(options = {}) {
|
|
13533
|
-
const dbPath = join7(homedir8(), ".mementos", "mementos.db");
|
|
13549
|
+
const dbPath = join7(options.homeDir ?? homedir8(), ".mementos", "mementos.db");
|
|
13534
13550
|
const db = new Database4(dbPath, { readonly: true, create: false });
|
|
13535
13551
|
try {
|
|
13536
13552
|
let query = "SELECT * FROM memories WHERE status = 'active'";
|
|
@@ -13596,7 +13612,7 @@ function windowToExample(window) {
|
|
|
13596
13612
|
return { messages };
|
|
13597
13613
|
}
|
|
13598
13614
|
async function gatherFromConversations(options = {}) {
|
|
13599
|
-
const dbPath = join9(homedir9(), ".conversations", "messages.db");
|
|
13615
|
+
const dbPath = join9(options.homeDir ?? homedir9(), ".conversations", "messages.db");
|
|
13600
13616
|
const db = new Database5(dbPath, { readonly: true, create: false });
|
|
13601
13617
|
try {
|
|
13602
13618
|
let query = "SELECT * FROM messages WHERE 1=1";
|
|
@@ -13652,7 +13668,7 @@ function extractText(content) {
|
|
|
13652
13668
|
async function gatherFromSessions(options = {}) {
|
|
13653
13669
|
const { limit = 1000 } = options;
|
|
13654
13670
|
const examples = [];
|
|
13655
|
-
const claudeDir = join10(homedir10(), ".claude", "projects");
|
|
13671
|
+
const claudeDir = join10(options.homeDir ?? homedir10(), ".claude", "projects");
|
|
13656
13672
|
if (!existsSync5(claudeDir)) {
|
|
13657
13673
|
return { source: "sessions", examples: [], count: 0 };
|
|
13658
13674
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/brains",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
4
4
|
"description": "Fine-tuned model tracker and trainer — wraps OpenAI + Thinker Labs, gathers training data from todos/mementos/conversations/sessions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|