brainjar 0.3.691 → 0.3.694
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/brainjar.js +158 -97
- package/package.json +1 -1
package/brainjar.js
CHANGED
|
@@ -107,7 +107,7 @@ var CLI_VERSION, CACHE, DAY;
|
|
|
107
107
|
var init_version_check = __esm({
|
|
108
108
|
"packages/cli/src/version-check.ts"() {
|
|
109
109
|
"use strict";
|
|
110
|
-
CLI_VERSION = "0.3.
|
|
110
|
+
CLI_VERSION = "0.3.694";
|
|
111
111
|
CACHE = path.join(os.homedir(), ".brainjar", "version-check.json");
|
|
112
112
|
DAY = 864e5;
|
|
113
113
|
}
|
|
@@ -5665,6 +5665,30 @@ function findEnvFile(startDir = process.cwd()) {
|
|
|
5665
5665
|
dir = parent;
|
|
5666
5666
|
}
|
|
5667
5667
|
}
|
|
5668
|
+
function projectsPath() {
|
|
5669
|
+
return path2.join(os2.homedir(), ".brainjar", "projects.json");
|
|
5670
|
+
}
|
|
5671
|
+
function projectKey(root) {
|
|
5672
|
+
return root.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
5673
|
+
}
|
|
5674
|
+
function readProjects(filePath = projectsPath()) {
|
|
5675
|
+
try {
|
|
5676
|
+
const parsed = JSON.parse(readFileSync2(filePath, "utf8"));
|
|
5677
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
5678
|
+
} catch {
|
|
5679
|
+
return {};
|
|
5680
|
+
}
|
|
5681
|
+
}
|
|
5682
|
+
function projectLink(root, filePath = projectsPath()) {
|
|
5683
|
+
const link = readProjects(filePath)[projectKey(root)];
|
|
5684
|
+
return link && typeof link.brainId === "string" ? link : null;
|
|
5685
|
+
}
|
|
5686
|
+
function writeProjectLink(root, link, filePath = projectsPath()) {
|
|
5687
|
+
const all = readProjects(filePath);
|
|
5688
|
+
all[projectKey(root)] = link;
|
|
5689
|
+
mkdirSync2(path2.dirname(filePath), { recursive: true });
|
|
5690
|
+
writeFileSync2(filePath, JSON.stringify(all, null, 2) + "\n", "utf8");
|
|
5691
|
+
}
|
|
5668
5692
|
function userConfigPath() {
|
|
5669
5693
|
return path2.join(os2.homedir(), ".brainjar", "config");
|
|
5670
5694
|
}
|
|
@@ -5995,17 +6019,6 @@ var init_vector = __esm({
|
|
|
5995
6019
|
});
|
|
5996
6020
|
|
|
5997
6021
|
// packages/db/src/repository.ts
|
|
5998
|
-
async function brainForProject(root, pool2 = getPool()) {
|
|
5999
|
-
const normalized = root.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
6000
|
-
const r = await pool2.query(
|
|
6001
|
-
`SELECT brain_id FROM source
|
|
6002
|
-
WHERE kind = 'git_local'
|
|
6003
|
-
AND lower(regexp_replace(replace(config->>'cwd', '\\', '/'), '/+$', '')) = $1
|
|
6004
|
-
ORDER BY created_at DESC LIMIT 1`,
|
|
6005
|
-
[normalized]
|
|
6006
|
-
);
|
|
6007
|
-
return r.rows[0]?.brain_id ?? null;
|
|
6008
|
-
}
|
|
6009
6022
|
async function getBrain(id, pool2 = getPool()) {
|
|
6010
6023
|
return (await pool2.query("SELECT * FROM brain WHERE id = $1", [id])).rows[0] ?? null;
|
|
6011
6024
|
}
|
|
@@ -6102,17 +6115,6 @@ var init_repository = __esm({
|
|
|
6102
6115
|
const existing = (await this.listSources()).find((s) => s.kind === kind);
|
|
6103
6116
|
return existing ?? await this.createSource(kind, name);
|
|
6104
6117
|
}
|
|
6105
|
-
/**
|
|
6106
|
-
* The git_local source for THIS root (normalized like brainForProject), or null. One
|
|
6107
|
-
* Brain can hold many checkouts; matching "any git_local" silently swallowed every root
|
|
6108
|
-
* after the first (found 2026-08-21 via the benchmark's silent push).
|
|
6109
|
-
*/
|
|
6110
|
-
async gitLocalSource(root) {
|
|
6111
|
-
const normalized = root.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
6112
|
-
return (await this.listSources()).find(
|
|
6113
|
-
(s) => s.kind === "git_local" && String(s.config.cwd ?? "").replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase() === normalized
|
|
6114
|
-
) ?? null;
|
|
6115
|
-
}
|
|
6116
6118
|
async listSources() {
|
|
6117
6119
|
return (await this.pool.query(
|
|
6118
6120
|
"SELECT * FROM source WHERE brain_id = $1 ORDER BY created_at",
|
|
@@ -12602,12 +12604,25 @@ async function repoRoot(cwd = process.cwd()) {
|
|
|
12602
12604
|
function repoName(root) {
|
|
12603
12605
|
return path5.basename(root) || "project";
|
|
12604
12606
|
}
|
|
12605
|
-
async function
|
|
12607
|
+
async function mainRepoRoot(root) {
|
|
12606
12608
|
try {
|
|
12607
|
-
|
|
12609
|
+
const { stdout } = await run2(
|
|
12610
|
+
"git",
|
|
12611
|
+
["rev-parse", "--path-format=absolute", "--git-common-dir"],
|
|
12612
|
+
{ cwd: root, windowsHide: true }
|
|
12613
|
+
);
|
|
12614
|
+
const common = path5.resolve(root, stdout.trim());
|
|
12615
|
+
if (path5.basename(common) === ".git") return path5.dirname(common);
|
|
12608
12616
|
} catch {
|
|
12609
|
-
return null;
|
|
12610
12617
|
}
|
|
12618
|
+
return root;
|
|
12619
|
+
}
|
|
12620
|
+
async function captureProject(root, filePath) {
|
|
12621
|
+
const top = await repoRoot(root);
|
|
12622
|
+
return projectLink(top, filePath) ?? projectLink(await mainRepoRoot(top), filePath);
|
|
12623
|
+
}
|
|
12624
|
+
async function resolveCaptureBrain(root, filePath) {
|
|
12625
|
+
return (await captureProject(root, filePath))?.brainId ?? null;
|
|
12611
12626
|
}
|
|
12612
12627
|
async function transcriptFiles(root) {
|
|
12613
12628
|
const encoded = root.replace(/[:\\/]/g, "-");
|
|
@@ -12790,6 +12805,7 @@ var init_bootstrap = __esm({
|
|
|
12790
12805
|
"packages/ingest/src/bootstrap.ts"() {
|
|
12791
12806
|
"use strict";
|
|
12792
12807
|
init_src2();
|
|
12808
|
+
init_src();
|
|
12793
12809
|
init_sync();
|
|
12794
12810
|
init_extraction();
|
|
12795
12811
|
init_structure();
|
|
@@ -15082,11 +15098,14 @@ function serverUrl() {
|
|
|
15082
15098
|
""
|
|
15083
15099
|
);
|
|
15084
15100
|
}
|
|
15101
|
+
function notConnected(root) {
|
|
15102
|
+
return `brainjar: no Brain is connected to ${root} on this machine. Run \`npx brainjar init --brain <id>\` there (the id is under Settings > Connect).`;
|
|
15103
|
+
}
|
|
15085
15104
|
async function captureApi(pathAndQuery, init2 = {}) {
|
|
15086
15105
|
const token = loadEnv().BRAINJAR_TOKEN?.trim();
|
|
15087
15106
|
if (!token) {
|
|
15088
|
-
throw new
|
|
15089
|
-
"BRAINJAR_TOKEN is not set
|
|
15107
|
+
throw new TokenError(
|
|
15108
|
+
"BRAINJAR_TOKEN is not set. Create a token in the web app (setup wizard or Settings > Connect) and run `npx brainjar init --brain <id> --token <token>` once on this machine."
|
|
15090
15109
|
);
|
|
15091
15110
|
}
|
|
15092
15111
|
const res = await fetch(serverUrl() + pathAndQuery, {
|
|
@@ -15098,6 +15117,7 @@ async function captureApi(pathAndQuery, init2 = {}) {
|
|
|
15098
15117
|
...init2.body !== void 0 ? { body: JSON.stringify(init2.body) } : {}
|
|
15099
15118
|
});
|
|
15100
15119
|
const body = await res.json().catch(() => null);
|
|
15120
|
+
if (res.status === 401) throw new TokenError(TOKEN_HELP);
|
|
15101
15121
|
if (!res.ok) {
|
|
15102
15122
|
throw new Error(
|
|
15103
15123
|
body?.error ?? `BrainJar server responded ${res.status} (${serverUrl()})`
|
|
@@ -15105,10 +15125,14 @@ async function captureApi(pathAndQuery, init2 = {}) {
|
|
|
15105
15125
|
}
|
|
15106
15126
|
return body;
|
|
15107
15127
|
}
|
|
15128
|
+
var TokenError, TOKEN_HELP;
|
|
15108
15129
|
var init_api_client = __esm({
|
|
15109
15130
|
"packages/cli/src/api-client.ts"() {
|
|
15110
15131
|
"use strict";
|
|
15111
15132
|
init_src();
|
|
15133
|
+
TokenError = class extends Error {
|
|
15134
|
+
};
|
|
15135
|
+
TOKEN_HELP = "BrainJar token revoked or invalid. Create a new token under Account in the web app, then run `npx brainjar init --brain <id> --token <token>` once in any project on this machine.";
|
|
15112
15136
|
}
|
|
15113
15137
|
});
|
|
15114
15138
|
|
|
@@ -15171,12 +15195,10 @@ ${BRIEF_END}
|
|
|
15171
15195
|
async function refreshBrief(cwd) {
|
|
15172
15196
|
if (loadEnv().BRAINJAR_NO_BRIEF === "1") return "skipped";
|
|
15173
15197
|
const root = await repoRoot(cwd);
|
|
15174
|
-
const
|
|
15175
|
-
|
|
15176
|
-
);
|
|
15177
|
-
if (!project.brainId) return "skipped";
|
|
15198
|
+
const link = await captureProject(root);
|
|
15199
|
+
if (!link) return "skipped";
|
|
15178
15200
|
const { text } = await captureApi(
|
|
15179
|
-
`/capture/brief?brain=${
|
|
15201
|
+
`/capture/brief?brain=${link.brainId}`
|
|
15180
15202
|
);
|
|
15181
15203
|
if (!text) return "skipped";
|
|
15182
15204
|
const file = path15.join(root, BRIEF_FILE);
|
|
@@ -15243,14 +15265,13 @@ async function scanDebtInRepo(root) {
|
|
|
15243
15265
|
}
|
|
15244
15266
|
async function debtMain() {
|
|
15245
15267
|
const root = await repoRoot(process.cwd());
|
|
15246
|
-
const
|
|
15247
|
-
if (!
|
|
15248
|
-
console.error(
|
|
15249
|
-
`brainjar: no Brain is connected to ${root} \u2014 run \`npx brainjar init\``
|
|
15250
|
-
);
|
|
15268
|
+
const link = await captureProject(root);
|
|
15269
|
+
if (!link) {
|
|
15270
|
+
console.error(notConnected(root));
|
|
15251
15271
|
process.exitCode = 1;
|
|
15252
15272
|
return;
|
|
15253
15273
|
}
|
|
15274
|
+
const r = await captureApi(`/capture/debt?brain=${link.brainId}`);
|
|
15254
15275
|
if (r.entries.length === 0) {
|
|
15255
15276
|
console.log(
|
|
15256
15277
|
"No ponytail debt on record. Either disciplined or undocumented."
|
|
@@ -16382,7 +16403,8 @@ __export(hook_exports, {
|
|
|
16382
16403
|
hookMain: () => hookMain,
|
|
16383
16404
|
parseHookArgs: () => parseHookArgs,
|
|
16384
16405
|
readSpool: () => readSpool,
|
|
16385
|
-
spoolPath: () => spoolPath
|
|
16406
|
+
spoolPath: () => spoolPath,
|
|
16407
|
+
staleSpools: () => staleSpools
|
|
16386
16408
|
});
|
|
16387
16409
|
import {
|
|
16388
16410
|
appendFileSync,
|
|
@@ -16426,6 +16448,34 @@ function pruneSpool(dir, keep, maxAgeMs = 7 * 864e5) {
|
|
|
16426
16448
|
} catch {
|
|
16427
16449
|
}
|
|
16428
16450
|
}
|
|
16451
|
+
function staleSpools(dir, keep, minAgeMs = 36e5) {
|
|
16452
|
+
try {
|
|
16453
|
+
return readdirSync(dir).map((f) => path17.join(dir, f)).filter(
|
|
16454
|
+
(file) => file !== keep && Date.now() - statSync2(file).mtimeMs > minAgeMs
|
|
16455
|
+
).sort();
|
|
16456
|
+
} catch {
|
|
16457
|
+
return [];
|
|
16458
|
+
}
|
|
16459
|
+
}
|
|
16460
|
+
async function linkForSpool(file) {
|
|
16461
|
+
const cwd = readSpool(file).find((e) => e.cwd)?.cwd;
|
|
16462
|
+
return cwd ? captureProject(await repoRoot(cwd)) : null;
|
|
16463
|
+
}
|
|
16464
|
+
async function shipSpool(file, link) {
|
|
16465
|
+
const events = readSpool(file);
|
|
16466
|
+
if (!events.length) return;
|
|
16467
|
+
const r = await captureApi("/capture/events", {
|
|
16468
|
+
method: "POST",
|
|
16469
|
+
body: {
|
|
16470
|
+
brain: link.brainId,
|
|
16471
|
+
events,
|
|
16472
|
+
author: loadEnv().BRAINJAR_AUTHOR?.trim() || null
|
|
16473
|
+
}
|
|
16474
|
+
});
|
|
16475
|
+
console.error(
|
|
16476
|
+
`brainjar: session captured \u2014 ${r.prompts ?? 0} intents, ${r.failures ?? 0} failures, ${(r.skippedNoise ?? 0) + (r.skippedFailures ?? 0)} noise skipped` + (r.consolidated ? `, ${r.consolidated} product facts` : "")
|
|
16477
|
+
);
|
|
16478
|
+
}
|
|
16429
16479
|
function parseHookArgs(argv) {
|
|
16430
16480
|
const eventFlag = argv.indexOf("--event");
|
|
16431
16481
|
const eventIndex = eventFlag >= 0 ? eventFlag + 1 : -1;
|
|
@@ -16462,28 +16512,22 @@ async function hookMain(argv) {
|
|
|
16462
16512
|
}
|
|
16463
16513
|
if (!out.flush) return;
|
|
16464
16514
|
const root = await repoRoot(out.cwd ?? process.cwd());
|
|
16465
|
-
const
|
|
16466
|
-
if (
|
|
16467
|
-
|
|
16468
|
-
|
|
16469
|
-
|
|
16470
|
-
root,
|
|
16471
|
-
events,
|
|
16472
|
-
author: loadEnv().BRAINJAR_AUTHOR?.trim() || null
|
|
16473
|
-
}
|
|
16474
|
-
});
|
|
16475
|
-
if (!r.brainId) {
|
|
16476
|
-
console.error(
|
|
16477
|
-
`brainjar: no Brain is connected to ${root} \u2014 run \`npx brainjar init\` (skipping capture)`
|
|
16478
|
-
);
|
|
16479
|
-
} else {
|
|
16480
|
-
console.error(
|
|
16481
|
-
`brainjar: session captured \u2014 ${r.prompts ?? 0} intents, ${r.failures ?? 0} failures, ${(r.skippedNoise ?? 0) + (r.skippedFailures ?? 0)} noise skipped` + (r.consolidated ? `, ${r.consolidated} product facts` : "")
|
|
16482
|
-
);
|
|
16483
|
-
}
|
|
16515
|
+
const link = await captureProject(root);
|
|
16516
|
+
if (!link) {
|
|
16517
|
+
console.error(notConnected(root));
|
|
16518
|
+
if (out.end) rmSync(file, { force: true });
|
|
16519
|
+
return;
|
|
16484
16520
|
}
|
|
16521
|
+
if (existsSync12(file)) await shipSpool(file, link);
|
|
16485
16522
|
if (out.end) rmSync(file, { force: true });
|
|
16486
|
-
|
|
16523
|
+
const dir = path17.dirname(file);
|
|
16524
|
+
for (const other of staleSpools(dir, file)) {
|
|
16525
|
+
const otherLink = await linkForSpool(other);
|
|
16526
|
+
if (!otherLink) continue;
|
|
16527
|
+
await shipSpool(other, otherLink);
|
|
16528
|
+
rmSync(other, { force: true });
|
|
16529
|
+
}
|
|
16530
|
+
pruneSpool(dir, file);
|
|
16487
16531
|
await syncRepo(root);
|
|
16488
16532
|
} catch (e) {
|
|
16489
16533
|
console.error("brainjar hook:", e instanceof Error ? e.message : e);
|
|
@@ -16518,13 +16562,12 @@ function capTranscript(text) {
|
|
|
16518
16562
|
}
|
|
16519
16563
|
async function syncRepo(root) {
|
|
16520
16564
|
try {
|
|
16521
|
-
const
|
|
16522
|
-
if (!
|
|
16523
|
-
console.error(
|
|
16524
|
-
`brainjar: no Brain is connected to ${root} \u2014 run \`npx brainjar init\` (skipping capture)`
|
|
16525
|
-
);
|
|
16565
|
+
const link = await captureProject(root);
|
|
16566
|
+
if (!link) {
|
|
16567
|
+
console.error(notConnected(root));
|
|
16526
16568
|
return;
|
|
16527
16569
|
}
|
|
16570
|
+
const project = await captureApi(`/capture/project?brain=${link.brainId}&source=${link.sourceId}`);
|
|
16528
16571
|
if (project.sourceId) {
|
|
16529
16572
|
const connector = createConnector("git_local", { cwd: root }, {});
|
|
16530
16573
|
const artifacts = await connector.sync(project.cursor ?? void 0);
|
|
@@ -16534,7 +16577,7 @@ async function syncRepo(root) {
|
|
|
16534
16577
|
{
|
|
16535
16578
|
method: "POST",
|
|
16536
16579
|
body: {
|
|
16537
|
-
|
|
16580
|
+
brain: link.brainId,
|
|
16538
16581
|
sourceId: project.sourceId,
|
|
16539
16582
|
artifacts,
|
|
16540
16583
|
cursor: maxUpdatedAt(artifacts) ?? project.cursor
|
|
@@ -16549,7 +16592,7 @@ async function syncRepo(root) {
|
|
|
16549
16592
|
const graph = await scanStructure(root);
|
|
16550
16593
|
await captureApi("/capture/structure", {
|
|
16551
16594
|
method: "POST",
|
|
16552
|
-
body: {
|
|
16595
|
+
body: { brain: link.brainId, graph }
|
|
16553
16596
|
});
|
|
16554
16597
|
}
|
|
16555
16598
|
}
|
|
@@ -16559,7 +16602,10 @@ async function syncRepo(root) {
|
|
|
16559
16602
|
const entries = await scanDebtInRepo2(root);
|
|
16560
16603
|
const r = await captureApi(
|
|
16561
16604
|
"/capture/debt",
|
|
16562
|
-
{
|
|
16605
|
+
{
|
|
16606
|
+
method: "POST",
|
|
16607
|
+
body: { brain: link.brainId, source: link.sourceId, entries }
|
|
16608
|
+
}
|
|
16563
16609
|
);
|
|
16564
16610
|
if (r.added || r.resolved)
|
|
16565
16611
|
console.error(
|
|
@@ -16635,13 +16681,23 @@ async function init(argv) {
|
|
|
16635
16681
|
return 1;
|
|
16636
16682
|
}
|
|
16637
16683
|
step(2, "Connecting the project Brain\u2026");
|
|
16684
|
+
const known = await captureProject(root);
|
|
16685
|
+
const reuse = known && (!brainFlag || known.brainId === brainFlag) ? known : null;
|
|
16638
16686
|
const conn = await captureApi("/capture/connect", {
|
|
16639
16687
|
method: "POST",
|
|
16640
|
-
body: {
|
|
16688
|
+
body: {
|
|
16689
|
+
name,
|
|
16690
|
+
...brainFlag ? { brainId: brainFlag } : reuse ? { brainId: reuse.brainId } : {},
|
|
16691
|
+
...reuse ? { sourceId: reuse.sourceId } : {}
|
|
16692
|
+
}
|
|
16641
16693
|
});
|
|
16642
16694
|
ok(
|
|
16643
16695
|
conn.createdBrain ? `created Brain "${name}" (${conn.brainId})` : `reusing Brain "${name}" (${conn.brainId})`
|
|
16644
16696
|
);
|
|
16697
|
+
writeProjectLink(root, { brainId: conn.brainId, sourceId: conn.sourceId });
|
|
16698
|
+
ok(
|
|
16699
|
+
`folder linked to the Brain in ${projectsPath()} (the path stays on this machine)`
|
|
16700
|
+
);
|
|
16645
16701
|
if (serverFlag || tokenFlag) {
|
|
16646
16702
|
writeUserConfig({
|
|
16647
16703
|
...serverFlag ? { BRAINJAR_SERVER: serverFlag } : {},
|
|
@@ -16653,7 +16709,7 @@ async function init(argv) {
|
|
|
16653
16709
|
const graph = await scanStructure(root);
|
|
16654
16710
|
const structure = await captureApi(
|
|
16655
16711
|
"/capture/structure",
|
|
16656
|
-
{ method: "POST", body: {
|
|
16712
|
+
{ method: "POST", body: { brain: conn.brainId, graph } }
|
|
16657
16713
|
);
|
|
16658
16714
|
const connector = createConnector("git_local", { cwd: root }, {});
|
|
16659
16715
|
const artifacts = await connector.sync(conn.cursor ?? void 0);
|
|
@@ -16665,7 +16721,7 @@ async function init(argv) {
|
|
|
16665
16721
|
{
|
|
16666
16722
|
method: "POST",
|
|
16667
16723
|
body: {
|
|
16668
|
-
|
|
16724
|
+
brain: conn.brainId,
|
|
16669
16725
|
sourceId: conn.sourceId,
|
|
16670
16726
|
artifacts,
|
|
16671
16727
|
cursor: maxUpdatedAt(artifacts) ?? conn.cursor
|
|
@@ -16695,7 +16751,7 @@ async function init(argv) {
|
|
|
16695
16751
|
if (truncated) truncatedCount++;
|
|
16696
16752
|
const r = await captureApi("/capture/transcript", {
|
|
16697
16753
|
method: "POST",
|
|
16698
|
-
body: {
|
|
16754
|
+
body: { brain: conn.brainId, text, author, backfill: true }
|
|
16699
16755
|
});
|
|
16700
16756
|
prompts += r.prompts;
|
|
16701
16757
|
failures += r.failures;
|
|
@@ -16738,7 +16794,7 @@ async function init(argv) {
|
|
|
16738
16794
|
ok("skipped (server unreachable) \u2014 the sync hook will add it");
|
|
16739
16795
|
}
|
|
16740
16796
|
const final = await captureApi(
|
|
16741
|
-
`/capture/project?
|
|
16797
|
+
`/capture/project?brain=${conn.brainId}&source=${conn.sourceId}`
|
|
16742
16798
|
);
|
|
16743
16799
|
console.log(
|
|
16744
16800
|
`
|
|
@@ -16794,6 +16850,7 @@ async function constraintsMain(argv) {
|
|
|
16794
16850
|
const hook = argv.includes("--hook");
|
|
16795
16851
|
const brainFlag = argv[argv.indexOf("--brain") + 1];
|
|
16796
16852
|
const brainOverride = argv.includes("--brain") ? brainFlag ?? null : null;
|
|
16853
|
+
const envelope = argv.includes("--copilot") ? copilotContextEnvelope : argv.includes("--cline") ? clineContextEnvelope : argv.includes("--plain") ? (text) => text : sessionStartEnvelope;
|
|
16797
16854
|
try {
|
|
16798
16855
|
let root;
|
|
16799
16856
|
if (hook) {
|
|
@@ -16807,21 +16864,17 @@ async function constraintsMain(argv) {
|
|
|
16807
16864
|
} else {
|
|
16808
16865
|
root = await repoRoot();
|
|
16809
16866
|
}
|
|
16810
|
-
const
|
|
16811
|
-
if (
|
|
16812
|
-
const r = await captureApi(
|
|
16813
|
-
`/capture/constraints?${q}`
|
|
16814
|
-
);
|
|
16815
|
-
if (!r.brainId) {
|
|
16867
|
+
const brainId = brainOverride ?? (await captureProject(root))?.brainId;
|
|
16868
|
+
if (!brainId) {
|
|
16816
16869
|
if (!hook) {
|
|
16817
|
-
console.error(
|
|
16818
|
-
`brainjar: no Brain is connected to ${root}. Pass --brain <id> or run \`npx brainjar init\` first.`
|
|
16819
|
-
);
|
|
16870
|
+
console.error(notConnected(root));
|
|
16820
16871
|
process.exitCode = 1;
|
|
16821
16872
|
}
|
|
16822
16873
|
return;
|
|
16823
16874
|
}
|
|
16824
|
-
const
|
|
16875
|
+
const r = await captureApi(
|
|
16876
|
+
`/capture/constraints?brain=${encodeURIComponent(brainId)}&limit=5`
|
|
16877
|
+
);
|
|
16825
16878
|
if (r.text) console.log(hook ? envelope(r.text) : r.text);
|
|
16826
16879
|
else if (hook && argv.includes("--cline")) console.log(CLINE_REPLY);
|
|
16827
16880
|
else if (!hook)
|
|
@@ -16834,7 +16887,12 @@ async function constraintsMain(argv) {
|
|
|
16834
16887
|
}
|
|
16835
16888
|
}
|
|
16836
16889
|
} catch (e) {
|
|
16837
|
-
|
|
16890
|
+
if (hook && e instanceof TokenError) console.log(envelope(e.message));
|
|
16891
|
+
else
|
|
16892
|
+
console.error(
|
|
16893
|
+
"brainjar constraints:",
|
|
16894
|
+
e instanceof Error ? e.message : e
|
|
16895
|
+
);
|
|
16838
16896
|
if (!hook) process.exitCode = 1;
|
|
16839
16897
|
}
|
|
16840
16898
|
}
|
|
@@ -16896,22 +16954,27 @@ async function runDoctor(root, opts = {}) {
|
|
|
16896
16954
|
`${serverUrl()} unreachable (${String(e).slice(0, 120)})`
|
|
16897
16955
|
);
|
|
16898
16956
|
}
|
|
16957
|
+
const link = await captureProject(root);
|
|
16899
16958
|
if (serverOk) {
|
|
16900
16959
|
try {
|
|
16901
|
-
const project = await captureApi(
|
|
16960
|
+
const project = await captureApi(
|
|
16961
|
+
link ? `/capture/project?brain=${link.brainId}&source=${link.sourceId}` : "/capture/project"
|
|
16962
|
+
);
|
|
16902
16963
|
add("token", true, "accepted");
|
|
16903
16964
|
add(
|
|
16904
16965
|
"brain",
|
|
16905
16966
|
project.brainId !== null,
|
|
16906
|
-
project.brainId !== null ? `${project.brainId} (${project.objects ?? 0} memory objects)` : "
|
|
16967
|
+
project.brainId !== null ? `${project.brainId} (${project.objects ?? 0} memory objects)` : "not connected on this machine. Run npx brainjar init --brain <id>"
|
|
16907
16968
|
);
|
|
16908
16969
|
} catch (e) {
|
|
16909
|
-
|
|
16910
|
-
|
|
16911
|
-
false,
|
|
16912
|
-
|
|
16913
|
-
|
|
16914
|
-
|
|
16970
|
+
const msg = String(e instanceof Error ? e.message : e).slice(0, 200);
|
|
16971
|
+
if (e instanceof TokenError) {
|
|
16972
|
+
add("token", false, msg);
|
|
16973
|
+
add("brain", false, "skipped (token rejected)");
|
|
16974
|
+
} else {
|
|
16975
|
+
add("token", true, "accepted");
|
|
16976
|
+
add("brain", false, msg);
|
|
16977
|
+
}
|
|
16915
16978
|
}
|
|
16916
16979
|
} else {
|
|
16917
16980
|
add("token", false, "skipped (server unreachable)");
|
|
@@ -17042,11 +17105,9 @@ async function walkCandidates(root) {
|
|
|
17042
17105
|
}
|
|
17043
17106
|
async function deepscanMain() {
|
|
17044
17107
|
const root = await repoRoot();
|
|
17045
|
-
const project = await
|
|
17046
|
-
if (!project
|
|
17047
|
-
console.error(
|
|
17048
|
-
`brainjar: no Brain is connected to ${root} \u2014 run \`npx brainjar init\` first`
|
|
17049
|
-
);
|
|
17108
|
+
const project = await captureProject(root);
|
|
17109
|
+
if (!project) {
|
|
17110
|
+
console.error(notConnected(root));
|
|
17050
17111
|
process.exitCode = 1;
|
|
17051
17112
|
return;
|
|
17052
17113
|
}
|
|
@@ -17090,7 +17151,7 @@ async function deepscanMain() {
|
|
|
17090
17151
|
{
|
|
17091
17152
|
method: "POST",
|
|
17092
17153
|
body: {
|
|
17093
|
-
|
|
17154
|
+
brain: project.brainId,
|
|
17094
17155
|
sourceId: project.sourceId,
|
|
17095
17156
|
artifacts: chunk,
|
|
17096
17157
|
// Only the final chunk kicks the server-side synthesis: one scan per run.
|