@hasna/brains 0.0.28 → 0.0.30
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 +70 -20
- package/dist/index.js +61 -11
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/mcp/index.js +41 -8
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -18128,7 +18128,7 @@ function printInfo(message) {
|
|
|
18128
18128
|
}
|
|
18129
18129
|
|
|
18130
18130
|
// src/cli/commands/models.ts
|
|
18131
|
-
import { randomUUID as
|
|
18131
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
18132
18132
|
|
|
18133
18133
|
// node_modules/openai/internal/qs/formats.mjs
|
|
18134
18134
|
var default_format = "RFC3986";
|
|
@@ -23618,16 +23618,48 @@ var openai_default = OpenAI;
|
|
|
23618
23618
|
import { readFileSync as readFileSync5 } from "fs";
|
|
23619
23619
|
|
|
23620
23620
|
// src/lib/config.ts
|
|
23621
|
-
import {
|
|
23621
|
+
import {
|
|
23622
|
+
chmodSync,
|
|
23623
|
+
copyFileSync as copyFileSync2,
|
|
23624
|
+
existsSync as existsSync7,
|
|
23625
|
+
lstatSync,
|
|
23626
|
+
mkdirSync as mkdirSync4,
|
|
23627
|
+
readFileSync as readFileSync3,
|
|
23628
|
+
readdirSync as readdirSync4,
|
|
23629
|
+
renameSync,
|
|
23630
|
+
statSync,
|
|
23631
|
+
unlinkSync as unlinkSync2,
|
|
23632
|
+
writeFileSync as writeFileSync3
|
|
23633
|
+
} from "fs";
|
|
23634
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
23622
23635
|
import { join as join7, dirname as dirname2 } from "path";
|
|
23623
23636
|
import { homedir as homedir6 } from "os";
|
|
23624
23637
|
var CONFIG_KEYS = ["OPENAI_API_KEY", "THINKER_LABS_API_KEY", "THINKER_LABS_BASE_URL"];
|
|
23638
|
+
var CONFIG_FILE_NAME = "config.json";
|
|
23639
|
+
function restrictConfigFilePermissions(configPath) {
|
|
23640
|
+
try {
|
|
23641
|
+
if (!lstatSync(configPath).isFile())
|
|
23642
|
+
return;
|
|
23643
|
+
chmodSync(configPath, 384);
|
|
23644
|
+
} catch {}
|
|
23645
|
+
}
|
|
23646
|
+
function ensureConfigDirectory(dirPath) {
|
|
23647
|
+
mkdirSync4(dirPath, { recursive: true, mode: 448 });
|
|
23648
|
+
try {
|
|
23649
|
+
if (!statSync(dirPath).isDirectory())
|
|
23650
|
+
return;
|
|
23651
|
+
chmodSync(dirPath, 448);
|
|
23652
|
+
} catch {}
|
|
23653
|
+
}
|
|
23625
23654
|
function resolveConfigPath() {
|
|
23626
23655
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir6();
|
|
23627
|
-
const
|
|
23656
|
+
const hasnaDir = join7(home, ".hasna");
|
|
23657
|
+
const newDir = join7(hasnaDir, "brains");
|
|
23628
23658
|
const oldDir = join7(home, ".brains");
|
|
23659
|
+
const configPath = join7(newDir, CONFIG_FILE_NAME);
|
|
23660
|
+
ensureConfigDirectory(hasnaDir);
|
|
23629
23661
|
if (existsSync7(oldDir) && !existsSync7(newDir)) {
|
|
23630
|
-
|
|
23662
|
+
ensureConfigDirectory(newDir);
|
|
23631
23663
|
try {
|
|
23632
23664
|
for (const file of readdirSync4(oldDir)) {
|
|
23633
23665
|
const oldPath = join7(oldDir, file);
|
|
@@ -23635,28 +23667,46 @@ function resolveConfigPath() {
|
|
|
23635
23667
|
try {
|
|
23636
23668
|
if (statSync(oldPath).isFile()) {
|
|
23637
23669
|
copyFileSync2(oldPath, newPath);
|
|
23670
|
+
if (file === CONFIG_FILE_NAME)
|
|
23671
|
+
restrictConfigFilePermissions(newPath);
|
|
23638
23672
|
}
|
|
23639
23673
|
} catch {}
|
|
23640
23674
|
}
|
|
23641
23675
|
} catch {}
|
|
23642
23676
|
}
|
|
23643
|
-
|
|
23644
|
-
return
|
|
23677
|
+
ensureConfigDirectory(newDir);
|
|
23678
|
+
return configPath;
|
|
23645
23679
|
}
|
|
23646
|
-
var CONFIG_PATH2 = resolveConfigPath();
|
|
23647
23680
|
function readConfigFile() {
|
|
23648
|
-
|
|
23681
|
+
const configPath = resolveConfigPath();
|
|
23682
|
+
if (!existsSync7(configPath))
|
|
23649
23683
|
return {};
|
|
23650
23684
|
try {
|
|
23651
|
-
return JSON.parse(readFileSync3(
|
|
23685
|
+
return JSON.parse(readFileSync3(configPath, "utf-8"));
|
|
23652
23686
|
} catch {
|
|
23653
23687
|
return {};
|
|
23654
23688
|
}
|
|
23655
23689
|
}
|
|
23656
23690
|
function writeConfigFile(data) {
|
|
23657
|
-
|
|
23658
|
-
|
|
23659
|
-
|
|
23691
|
+
const configPath = resolveConfigPath();
|
|
23692
|
+
const configDir = dirname2(configPath);
|
|
23693
|
+
const tempPath = join7(configDir, `.config.json.${randomUUID3()}.tmp`);
|
|
23694
|
+
ensureConfigDirectory(configDir);
|
|
23695
|
+
if (existsSync7(configPath))
|
|
23696
|
+
restrictConfigFilePermissions(configPath);
|
|
23697
|
+
try {
|
|
23698
|
+
writeFileSync3(tempPath, JSON.stringify(data, null, 2) + `
|
|
23699
|
+
`, { encoding: "utf-8", mode: 384, flag: "wx" });
|
|
23700
|
+
restrictConfigFilePermissions(tempPath);
|
|
23701
|
+
renameSync(tempPath, configPath);
|
|
23702
|
+
restrictConfigFilePermissions(configPath);
|
|
23703
|
+
} catch (err) {
|
|
23704
|
+
try {
|
|
23705
|
+
if (existsSync7(tempPath))
|
|
23706
|
+
unlinkSync2(tempPath);
|
|
23707
|
+
} catch {}
|
|
23708
|
+
throw err;
|
|
23709
|
+
}
|
|
23660
23710
|
}
|
|
23661
23711
|
function getConfigValue(key) {
|
|
23662
23712
|
if (process.env[key])
|
|
@@ -24068,7 +24118,7 @@ function registerModelsCommands(program2) {
|
|
|
24068
24118
|
printInfo(`Model already tracked as: ${existing.id}`);
|
|
24069
24119
|
return;
|
|
24070
24120
|
}
|
|
24071
|
-
const modelId =
|
|
24121
|
+
const modelId = randomUUID5();
|
|
24072
24122
|
const now2 = Date.now();
|
|
24073
24123
|
const name = opts.name ?? result.fineTunedModel ?? `imported-${jobId}`;
|
|
24074
24124
|
await db.insert(fineTunedModels).values({
|
|
@@ -24082,7 +24132,7 @@ function registerModelsCommands(program2) {
|
|
|
24082
24132
|
updatedAt: now2
|
|
24083
24133
|
});
|
|
24084
24134
|
await db.insert(trainingJobs).values({
|
|
24085
|
-
id:
|
|
24135
|
+
id: randomUUID5(),
|
|
24086
24136
|
modelId,
|
|
24087
24137
|
provider: opts.provider,
|
|
24088
24138
|
status: result.status,
|
|
@@ -24105,7 +24155,7 @@ function registerModelsCommands(program2) {
|
|
|
24105
24155
|
}
|
|
24106
24156
|
|
|
24107
24157
|
// src/cli/commands/finetune.ts
|
|
24108
|
-
import { randomUUID as
|
|
24158
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
24109
24159
|
import { existsSync as existsSync9 } from "fs";
|
|
24110
24160
|
function registerFinetuneCommands(program2) {
|
|
24111
24161
|
const finetuneCmd = program2.command("finetune").description("Manage fine-tuning jobs");
|
|
@@ -24147,7 +24197,7 @@ function registerFinetuneCommands(program2) {
|
|
|
24147
24197
|
({ jobId, status: jobStatus } = await tl.createFineTuneJob(fileId, opts.baseModel, opts.name));
|
|
24148
24198
|
}
|
|
24149
24199
|
const db = getDb();
|
|
24150
|
-
const modelId =
|
|
24200
|
+
const modelId = randomUUID6();
|
|
24151
24201
|
const now2 = Date.now();
|
|
24152
24202
|
await db.insert(fineTunedModels).values({
|
|
24153
24203
|
id: modelId,
|
|
@@ -24159,7 +24209,7 @@ function registerFinetuneCommands(program2) {
|
|
|
24159
24209
|
createdAt: now2,
|
|
24160
24210
|
updatedAt: now2
|
|
24161
24211
|
});
|
|
24162
|
-
const trainingJobId =
|
|
24212
|
+
const trainingJobId = randomUUID6();
|
|
24163
24213
|
await db.insert(trainingJobs).values({
|
|
24164
24214
|
id: trainingJobId,
|
|
24165
24215
|
modelId,
|
|
@@ -24299,7 +24349,7 @@ function registerFinetuneCommands(program2) {
|
|
|
24299
24349
|
}
|
|
24300
24350
|
|
|
24301
24351
|
// src/cli/commands/data.ts
|
|
24302
|
-
import { randomUUID as
|
|
24352
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
24303
24353
|
import { readFileSync as readFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
24304
24354
|
import { dirname as dirname3, join as join13 } from "path";
|
|
24305
24355
|
import { homedir as homedir12 } from "os";
|
|
@@ -24349,7 +24399,7 @@ function registerDataCommands(program2) {
|
|
|
24349
24399
|
`) + `
|
|
24350
24400
|
`, "utf8");
|
|
24351
24401
|
await db.insert(trainingDatasets).values({
|
|
24352
|
-
id:
|
|
24402
|
+
id: randomUUID7(),
|
|
24353
24403
|
source,
|
|
24354
24404
|
filePath,
|
|
24355
24405
|
exampleCount: count,
|
|
@@ -24439,7 +24489,7 @@ function registerDataCommands(program2) {
|
|
|
24439
24489
|
`, "utf8");
|
|
24440
24490
|
const db = getDb();
|
|
24441
24491
|
await db.insert(trainingDatasets).values({
|
|
24442
|
-
id:
|
|
24492
|
+
id: randomUUID7(),
|
|
24443
24493
|
source: "mixed",
|
|
24444
24494
|
filePath: opts.output,
|
|
24445
24495
|
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"}
|
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
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/brains",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.30",
|
|
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",
|