@onebrain-ai/cli 2.1.10 → 2.1.12
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/README.md +6 -6
- package/dist/onebrain +238 -84
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,20 +111,20 @@ The agent reaches outward FROM the vault to every surface where the work actuall
|
|
|
111
111
|
|
|
112
112
|
---
|
|
113
113
|
|
|
114
|
-
##
|
|
114
|
+
## Every Session Sharpens Both
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
OneBrain runs as a tight 3-step loop. Each cycle, both sides sharpen.
|
|
117
117
|
|
|
118
118
|
<p align="center">
|
|
119
119
|
<picture>
|
|
120
120
|
<source media="(prefers-color-scheme: dark)" srcset="assets/diagrams/coevo-loop-dark.svg">
|
|
121
|
-
<img alt="Co-Evolution loop — three nodes (01
|
|
121
|
+
<img alt="Co-Evolution loop — three nodes (01 CAPTURE at top, 02 EVOLVE at bottom-right, 03 WRAPUP at bottom-left) connected by curved arrows flowing clockwise" src="assets/diagrams/coevo-loop-light.svg" width="540">
|
|
122
122
|
</picture>
|
|
123
123
|
</p>
|
|
124
124
|
|
|
125
|
-
1. **
|
|
126
|
-
2. **
|
|
127
|
-
3. **
|
|
125
|
+
1. **Capture** — Talk to the agent in natural language. It writes, classifies, and links your thoughts in real time. → `/braindump` · `/capture` · `/bookmark`
|
|
126
|
+
2. **Evolve** — `/research` and `/distill` expand your knowledge. `/learn` deepens the agent. The loop tightens. → `/research` · `/distill` · `/learn`
|
|
127
|
+
3. **Wrapup** — `/wrapup` consolidates the session log. `/recap` promotes lessons to memory. → `/wrapup` · `/recap`
|
|
128
128
|
|
|
129
129
|
### Behind the loop
|
|
130
130
|
|
package/dist/onebrain
CHANGED
|
@@ -9268,6 +9268,10 @@ async function checkVaultYmlKeys(vaultRoot) {
|
|
|
9268
9268
|
if (raw[key] === undefined)
|
|
9269
9269
|
errors.push(`missing key: ${key}`);
|
|
9270
9270
|
}
|
|
9271
|
+
for (const key of SOFT_REQUIRED_VAULT_YML_KEYS) {
|
|
9272
|
+
if (raw[key] === undefined)
|
|
9273
|
+
warnings.push(`missing key: ${key}`);
|
|
9274
|
+
}
|
|
9271
9275
|
const folders = raw["folders"] ?? {};
|
|
9272
9276
|
for (const key of REQUIRED_FOLDER_KEYS) {
|
|
9273
9277
|
if (folders[key] === undefined)
|
|
@@ -9305,8 +9309,16 @@ async function checkVaultYmlKeys(vaultRoot) {
|
|
|
9305
9309
|
};
|
|
9306
9310
|
}
|
|
9307
9311
|
if (warnings.length > 0) {
|
|
9308
|
-
const
|
|
9309
|
-
const
|
|
9312
|
+
const hasDeprecated = warnings.some((w) => w.includes("onebrain_version") || w.includes("method") || w.includes("runtime.harness"));
|
|
9313
|
+
const hasMissingSoftKey = warnings.some((w) => w.startsWith("missing key:"));
|
|
9314
|
+
let hint;
|
|
9315
|
+
if (hasMissingSoftKey && hasDeprecated) {
|
|
9316
|
+
hint = "Run onebrain doctor --fix to repair vault.yml";
|
|
9317
|
+
} else if (hasMissingSoftKey) {
|
|
9318
|
+
hint = "Run onebrain doctor --fix to backfill defaults";
|
|
9319
|
+
} else if (hasDeprecated) {
|
|
9320
|
+
hint = "Run onebrain doctor --fix to remove deprecated keys";
|
|
9321
|
+
}
|
|
9310
9322
|
return {
|
|
9311
9323
|
check: "vault.yml-keys",
|
|
9312
9324
|
status: "warn",
|
|
@@ -9321,6 +9333,39 @@ async function checkVaultYmlKeys(vaultRoot) {
|
|
|
9321
9333
|
message: "schema ok"
|
|
9322
9334
|
};
|
|
9323
9335
|
}
|
|
9336
|
+
async function checkClaudeSettings(vaultRoot) {
|
|
9337
|
+
const settingsPath = join2(vaultRoot, ".claude", "settings.json");
|
|
9338
|
+
const file = Bun.file(settingsPath);
|
|
9339
|
+
if (!await file.exists()) {
|
|
9340
|
+
return { check: "claude-settings", status: "ok", message: "no vault settings.json" };
|
|
9341
|
+
}
|
|
9342
|
+
let raw;
|
|
9343
|
+
try {
|
|
9344
|
+
raw = JSON.parse(await file.text());
|
|
9345
|
+
} catch {
|
|
9346
|
+
return {
|
|
9347
|
+
check: "claude-settings",
|
|
9348
|
+
status: "warn",
|
|
9349
|
+
message: "settings.json contains invalid JSON"
|
|
9350
|
+
};
|
|
9351
|
+
}
|
|
9352
|
+
const marketplaces = raw["extraKnownMarketplaces"];
|
|
9353
|
+
const onebrain = marketplaces?.["onebrain"];
|
|
9354
|
+
const source = onebrain?.["source"];
|
|
9355
|
+
const repo = source?.["repo"];
|
|
9356
|
+
if (repo === STALE_MARKETPLACE_REPO) {
|
|
9357
|
+
return {
|
|
9358
|
+
check: "claude-settings",
|
|
9359
|
+
status: "warn",
|
|
9360
|
+
message: "stale marketplace repo",
|
|
9361
|
+
hint: "Run onebrain doctor --fix to rewrite to onebrain-ai/onebrain",
|
|
9362
|
+
details: [
|
|
9363
|
+
`stale extraKnownMarketplaces.onebrain.source.repo: ${STALE_MARKETPLACE_REPO} \u2192 ${CANONICAL_MARKETPLACE_REPO}`
|
|
9364
|
+
]
|
|
9365
|
+
};
|
|
9366
|
+
}
|
|
9367
|
+
return { check: "claude-settings", status: "ok", message: "ok" };
|
|
9368
|
+
}
|
|
9324
9369
|
function hookPresent(settings, event, cmdSubstring) {
|
|
9325
9370
|
const groups = settings.hooks?.[event] ?? [];
|
|
9326
9371
|
return groups.some((g) => g.hooks?.some((h) => (h.command ?? "").includes(cmdSubstring)));
|
|
@@ -9407,7 +9452,7 @@ async function checkSettingsHooks(vaultRoot, config) {
|
|
|
9407
9452
|
...okDetails.length > 0 ? { details: okDetails } : {}
|
|
9408
9453
|
};
|
|
9409
9454
|
}
|
|
9410
|
-
var import_yaml2, STANDARD_FOLDER_KEYS, REQUIRED_PLUGIN_FILES, REQUIRED_PLUGIN_DIRS, STALE_BASH_FILES, REQUIRED_VAULT_YML_KEYS, REQUIRED_FOLDER_KEYS, REQUIRED_HOOKS, ALLOWED_HOOK_EVENTS, QMD_HOOK_SUBSTRING = "onebrain qmd-reindex", ONEBRAIN_COMMAND_SUBSTRING = "onebrain", REQUIRED_PERMISSION = "Bash(onebrain *)", STALE_HOOK_SUBSTRINGS;
|
|
9455
|
+
var import_yaml2, STANDARD_FOLDER_KEYS, REQUIRED_PLUGIN_FILES, REQUIRED_PLUGIN_DIRS, STALE_BASH_FILES, REQUIRED_VAULT_YML_KEYS, SOFT_REQUIRED_VAULT_YML_KEYS, REQUIRED_FOLDER_KEYS, STALE_MARKETPLACE_REPO = "kengio/onebrain", CANONICAL_MARKETPLACE_REPO = "onebrain-ai/onebrain", REQUIRED_HOOKS, ALLOWED_HOOK_EVENTS, QMD_HOOK_SUBSTRING = "onebrain qmd-reindex", ONEBRAIN_COMMAND_SUBSTRING = "onebrain", REQUIRED_PERMISSION = "Bash(onebrain *)", STALE_HOOK_SUBSTRINGS;
|
|
9411
9456
|
var init_validator = __esm(() => {
|
|
9412
9457
|
import_yaml2 = __toESM(require_dist(), 1);
|
|
9413
9458
|
STANDARD_FOLDER_KEYS = [
|
|
@@ -9431,7 +9476,8 @@ var init_validator = __esm(() => {
|
|
|
9431
9476
|
"qmd-reindex.sh",
|
|
9432
9477
|
"backfill-recapped.sh"
|
|
9433
9478
|
];
|
|
9434
|
-
REQUIRED_VAULT_YML_KEYS = ["
|
|
9479
|
+
REQUIRED_VAULT_YML_KEYS = ["folders"];
|
|
9480
|
+
SOFT_REQUIRED_VAULT_YML_KEYS = ["update_channel"];
|
|
9435
9481
|
REQUIRED_FOLDER_KEYS = [
|
|
9436
9482
|
"inbox",
|
|
9437
9483
|
"projects",
|
|
@@ -9449,17 +9495,33 @@ var init_validator = __esm(() => {
|
|
|
9449
9495
|
STALE_HOOK_SUBSTRINGS = ["checkpoint-hook.sh", "session-init.sh"];
|
|
9450
9496
|
});
|
|
9451
9497
|
|
|
9498
|
+
// src/lib/fs-atomic.ts
|
|
9499
|
+
import { rename, unlink, writeFile } from "fs/promises";
|
|
9500
|
+
async function atomicWrite(dest, contents, label) {
|
|
9501
|
+
const tmpPath = `${dest}.tmp`;
|
|
9502
|
+
await writeFile(tmpPath, contents, "utf8");
|
|
9503
|
+
try {
|
|
9504
|
+
await rename(tmpPath, dest);
|
|
9505
|
+
} catch (err) {
|
|
9506
|
+
await unlink(tmpPath).catch(() => {});
|
|
9507
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
9508
|
+
throw new Error(`rename failed for ${label ?? dest}; tmp cleaned up: ${msg}`, { cause: err });
|
|
9509
|
+
}
|
|
9510
|
+
}
|
|
9511
|
+
var init_fs_atomic = () => {};
|
|
9512
|
+
|
|
9452
9513
|
// src/lib/index.ts
|
|
9453
9514
|
var init_lib = __esm(() => {
|
|
9454
9515
|
init_parser();
|
|
9455
9516
|
init_validator();
|
|
9517
|
+
init_fs_atomic();
|
|
9456
9518
|
});
|
|
9457
9519
|
|
|
9458
9520
|
// package.json
|
|
9459
9521
|
var require_package = __commonJS((exports, module) => {
|
|
9460
9522
|
module.exports = {
|
|
9461
9523
|
name: "@onebrain-ai/cli",
|
|
9462
|
-
version: "2.1.
|
|
9524
|
+
version: "2.1.12",
|
|
9463
9525
|
description: "CLI for OneBrain \u2014 personal AI OS for Obsidian with persistent memory, 24+ skills, and Claude Code integration",
|
|
9464
9526
|
keywords: [
|
|
9465
9527
|
"onebrain",
|
|
@@ -9940,7 +10002,7 @@ __export(exports_register_hooks, {
|
|
|
9940
10002
|
runRegisterHooks: () => runRegisterHooks,
|
|
9941
10003
|
registerHooksCommand: () => registerHooksCommand
|
|
9942
10004
|
});
|
|
9943
|
-
import { mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
10005
|
+
import { mkdir, readFile, rename as rename2, writeFile as writeFile2 } from "fs/promises";
|
|
9944
10006
|
import { homedir } from "os";
|
|
9945
10007
|
import { dirname, join as join4 } from "path";
|
|
9946
10008
|
async function readSettings(settingsPath) {
|
|
@@ -9956,8 +10018,8 @@ async function readSettings(settingsPath) {
|
|
|
9956
10018
|
async function writeSettings(settingsPath, settings) {
|
|
9957
10019
|
await mkdir(dirname(settingsPath), { recursive: true });
|
|
9958
10020
|
const tmpPath = `${settingsPath}.tmp`;
|
|
9959
|
-
await
|
|
9960
|
-
await
|
|
10021
|
+
await writeFile2(tmpPath, JSON.stringify(settings, null, 4), "utf8");
|
|
10022
|
+
await rename2(tmpPath, settingsPath);
|
|
9961
10023
|
}
|
|
9962
10024
|
function checkHookPresence(groups, targetCmd) {
|
|
9963
10025
|
let foundMigrate = false;
|
|
@@ -10086,8 +10148,8 @@ ${ONEBRAIN_MARKER}
|
|
|
10086
10148
|
${PATH_EXPORT}
|
|
10087
10149
|
`;
|
|
10088
10150
|
const tmpPath = `${profilePath}.tmp`;
|
|
10089
|
-
await
|
|
10090
|
-
await
|
|
10151
|
+
await writeFile2(tmpPath, updated, "utf8");
|
|
10152
|
+
await rename2(tmpPath, profilePath);
|
|
10091
10153
|
}
|
|
10092
10154
|
async function runRegisterHooks(opts = {}) {
|
|
10093
10155
|
const vaultRoot = opts.vaultDir ?? process.cwd();
|
|
@@ -10216,19 +10278,13 @@ __export(exports_vault_sync, {
|
|
|
10216
10278
|
vaultSyncCommand: () => vaultSyncCommand,
|
|
10217
10279
|
runVaultSync: () => runVaultSync
|
|
10218
10280
|
});
|
|
10219
|
-
import {
|
|
10220
|
-
mkdir as mkdir2,
|
|
10221
|
-
mkdtemp,
|
|
10222
|
-
readFile as readFile2,
|
|
10223
|
-
readdir,
|
|
10224
|
-
rename as rename2,
|
|
10225
|
-
rm,
|
|
10226
|
-
stat as stat3,
|
|
10227
|
-
unlink,
|
|
10228
|
-
writeFile as writeFile2
|
|
10229
|
-
} from "fs/promises";
|
|
10281
|
+
import { mkdir as mkdir2, mkdtemp, readFile as readFile2, readdir, rm, stat as stat3, unlink as unlink2, writeFile as writeFile3 } from "fs/promises";
|
|
10230
10282
|
import { homedir as homedir2, tmpdir } from "os";
|
|
10231
|
-
import { dirname as dirname2, join as join5, relative } from "path";
|
|
10283
|
+
import { dirname as dirname2, join as join5, sep as pathSep, relative, resolve as resolvePath } from "path";
|
|
10284
|
+
function normalizePath(p2) {
|
|
10285
|
+
const resolved = resolvePath(p2);
|
|
10286
|
+
return resolved.endsWith(pathSep) && resolved.length > pathSep.length ? resolved.slice(0, -pathSep.length) : resolved;
|
|
10287
|
+
}
|
|
10232
10288
|
function resolveBranch(updateChannel) {
|
|
10233
10289
|
return updateChannel === "stable" ? "main" : "next";
|
|
10234
10290
|
}
|
|
@@ -10250,7 +10306,7 @@ async function downloadTarball(branch, fetchFn) {
|
|
|
10250
10306
|
}
|
|
10251
10307
|
async function extractTarball(tarball, destDir) {
|
|
10252
10308
|
const tarPath = join5(destDir, "bundle.tar.gz");
|
|
10253
|
-
await
|
|
10309
|
+
await writeFile3(tarPath, Buffer.from(tarball));
|
|
10254
10310
|
const proc = Bun.spawn(["tar", "-xzf", tarPath, "-C", destDir], {
|
|
10255
10311
|
stdout: "pipe",
|
|
10256
10312
|
stderr: "pipe"
|
|
@@ -10260,7 +10316,7 @@ async function extractTarball(tarball, destDir) {
|
|
|
10260
10316
|
const errText = await new Response(proc.stderr).text();
|
|
10261
10317
|
throw new Error(`tar extraction failed (exit ${exitCode}): ${errText.trim()}`);
|
|
10262
10318
|
}
|
|
10263
|
-
await
|
|
10319
|
+
await unlink2(tarPath);
|
|
10264
10320
|
const entries = await readdir(destDir);
|
|
10265
10321
|
const topLevel = entries.find((e2) => e2 !== "bundle.tar.gz");
|
|
10266
10322
|
if (!topLevel) {
|
|
@@ -10296,7 +10352,7 @@ async function listFilesRecursive(dir) {
|
|
|
10296
10352
|
}
|
|
10297
10353
|
return results;
|
|
10298
10354
|
}
|
|
10299
|
-
async function syncPluginFiles(extractedDir, vaultRoot, unlinkFn =
|
|
10355
|
+
async function syncPluginFiles(extractedDir, vaultRoot, unlinkFn = unlink2) {
|
|
10300
10356
|
const sourcePlugin = join5(extractedDir, ".claude", "plugins", "onebrain");
|
|
10301
10357
|
const destPlugin = join5(vaultRoot, ".claude", "plugins", "onebrain");
|
|
10302
10358
|
await mkdir2(destPlugin, { recursive: true });
|
|
@@ -10316,7 +10372,7 @@ async function syncPluginFiles(extractedDir, vaultRoot, unlinkFn = unlink) {
|
|
|
10316
10372
|
const destPath = join5(destPlugin, rel);
|
|
10317
10373
|
await mkdir2(dirname2(destPath), { recursive: true });
|
|
10318
10374
|
const content = await readFile2(srcPath);
|
|
10319
|
-
await
|
|
10375
|
+
await writeFile3(destPath, content);
|
|
10320
10376
|
filesAdded++;
|
|
10321
10377
|
}
|
|
10322
10378
|
let filesRemoved = 0;
|
|
@@ -10336,7 +10392,7 @@ async function copyRootDocs(extractedDir, vaultRoot) {
|
|
|
10336
10392
|
const destPath = join5(vaultRoot, doc);
|
|
10337
10393
|
try {
|
|
10338
10394
|
const content = await readFile2(srcPath);
|
|
10339
|
-
await
|
|
10395
|
+
await writeFile3(destPath, content);
|
|
10340
10396
|
} catch {}
|
|
10341
10397
|
}
|
|
10342
10398
|
}
|
|
@@ -10353,7 +10409,7 @@ async function mergeHarnessFile(extractedDir, vaultRoot, filename) {
|
|
|
10353
10409
|
try {
|
|
10354
10410
|
vaultText = await readFile2(destPath, "utf8");
|
|
10355
10411
|
} catch {
|
|
10356
|
-
await
|
|
10412
|
+
await writeFile3(destPath, repoText, "utf8");
|
|
10357
10413
|
return repoText.split(`
|
|
10358
10414
|
`).filter((l2) => l2.startsWith("@")).length;
|
|
10359
10415
|
}
|
|
@@ -10374,7 +10430,7 @@ async function mergeHarnessFile(extractedDir, vaultRoot, filename) {
|
|
|
10374
10430
|
}
|
|
10375
10431
|
const merged = vaultLines.join(`
|
|
10376
10432
|
`);
|
|
10377
|
-
await
|
|
10433
|
+
await writeFile3(destPath, merged, "utf8");
|
|
10378
10434
|
return newImports.length;
|
|
10379
10435
|
}
|
|
10380
10436
|
async function mergeHarnessFiles(extractedDir, vaultRoot) {
|
|
@@ -10396,22 +10452,21 @@ async function updateVaultYml(vaultRoot, updateChannel) {
|
|
|
10396
10452
|
}
|
|
10397
10453
|
const raw = import_yaml3.parse(text) ?? {};
|
|
10398
10454
|
raw["update_channel"] = updateChannel;
|
|
10399
|
-
|
|
10400
|
-
const tmpPath = `${vaultYmlPath}.tmp`;
|
|
10401
|
-
await writeFile2(tmpPath, updated, "utf8");
|
|
10402
|
-
await rename2(tmpPath, vaultYmlPath);
|
|
10455
|
+
await atomicWrite(vaultYmlPath, import_yaml3.stringify(raw, { lineWidth: 0 }), "vault.yml");
|
|
10403
10456
|
}
|
|
10404
|
-
async function
|
|
10457
|
+
async function readPluginMetadata(vaultRoot) {
|
|
10405
10458
|
const pluginJsonPath = join5(vaultRoot, ".claude", "plugins", "onebrain", ".claude-plugin", "plugin.json");
|
|
10406
10459
|
try {
|
|
10407
10460
|
const text = await readFile2(pluginJsonPath, "utf8");
|
|
10408
10461
|
const parsed = JSON.parse(text);
|
|
10409
|
-
|
|
10462
|
+
const version = typeof parsed["version"] === "string" ? parsed["version"] : "unknown";
|
|
10463
|
+
const lastUpdated = typeof parsed["lastUpdated"] === "string" ? parsed["lastUpdated"] : undefined;
|
|
10464
|
+
return { version, lastUpdated };
|
|
10410
10465
|
} catch {
|
|
10411
|
-
return "unknown";
|
|
10466
|
+
return { version: "unknown", lastUpdated: undefined };
|
|
10412
10467
|
}
|
|
10413
10468
|
}
|
|
10414
|
-
async function pinToVault(vaultRoot, installedPluginsPath, installedPluginsCacheDir) {
|
|
10469
|
+
async function pinToVault(vaultRoot, installedPluginsPath, installedPluginsCacheDir, now = () => new Date) {
|
|
10415
10470
|
let text;
|
|
10416
10471
|
try {
|
|
10417
10472
|
text = await readFile2(installedPluginsPath, "utf8");
|
|
@@ -10433,8 +10488,12 @@ async function pinToVault(vaultRoot, installedPluginsPath, installedPluginsCache
|
|
|
10433
10488
|
return { skipped: true };
|
|
10434
10489
|
}
|
|
10435
10490
|
const vaultPluginDir = join5(vaultRoot, ".claude", "plugins", "onebrain");
|
|
10436
|
-
const
|
|
10491
|
+
const normalizedVaultRoot = normalizePath(vaultRoot);
|
|
10492
|
+
const normalizedVaultPluginDir = normalizePath(vaultPluginDir);
|
|
10493
|
+
const { version: pluginVersion, lastUpdated: pluginLastUpdated } = await readPluginMetadata(vaultRoot);
|
|
10494
|
+
const updatedAt = pluginLastUpdated ?? now().toISOString();
|
|
10437
10495
|
const cacheDir = installedPluginsCacheDir ?? join5(dirname2(installedPluginsPath), "cache");
|
|
10496
|
+
const normalizedCacheDir = normalizePath(cacheDir);
|
|
10438
10497
|
const hasMarketplace = onebrainKeys.some((k2) => {
|
|
10439
10498
|
const entries = plugins[k2];
|
|
10440
10499
|
return entries.some((e2) => e2["source"] === "marketplace");
|
|
@@ -10443,33 +10502,70 @@ async function pinToVault(vaultRoot, installedPluginsPath, installedPluginsCache
|
|
|
10443
10502
|
return { skipped: true };
|
|
10444
10503
|
}
|
|
10445
10504
|
let changed = false;
|
|
10505
|
+
const ONEBRAIN_KEY = "onebrain@onebrain";
|
|
10506
|
+
if (Array.isArray(plugins[ONEBRAIN_KEY])) {
|
|
10507
|
+
const before = plugins[ONEBRAIN_KEY];
|
|
10508
|
+
const keep = [];
|
|
10509
|
+
for (const entry of before) {
|
|
10510
|
+
const projectPath = entry["projectPath"];
|
|
10511
|
+
if (typeof projectPath !== "string") {
|
|
10512
|
+
keep.push(entry);
|
|
10513
|
+
continue;
|
|
10514
|
+
}
|
|
10515
|
+
try {
|
|
10516
|
+
await stat3(projectPath);
|
|
10517
|
+
keep.push(entry);
|
|
10518
|
+
} catch (err) {
|
|
10519
|
+
const code = err?.code;
|
|
10520
|
+
if (code === "ENOENT")
|
|
10521
|
+
continue;
|
|
10522
|
+
process.stderr.write(`vault-sync: pin warning: stat ${projectPath}: ${code ?? "unknown"}
|
|
10523
|
+
`);
|
|
10524
|
+
keep.push(entry);
|
|
10525
|
+
}
|
|
10526
|
+
}
|
|
10527
|
+
if (keep.length !== before.length) {
|
|
10528
|
+
plugins[ONEBRAIN_KEY] = keep;
|
|
10529
|
+
changed = true;
|
|
10530
|
+
}
|
|
10531
|
+
}
|
|
10446
10532
|
for (const key of onebrainKeys) {
|
|
10447
10533
|
const entries = plugins[key];
|
|
10448
10534
|
for (const entry of entries) {
|
|
10449
|
-
const
|
|
10450
|
-
|
|
10535
|
+
const installPathRaw = entry["installPath"];
|
|
10536
|
+
const projectPathRaw = entry["projectPath"];
|
|
10537
|
+
const installPathBad = installPathRaw !== undefined && typeof installPathRaw !== "string";
|
|
10538
|
+
const projectPathBad = projectPathRaw !== undefined && typeof projectPathRaw !== "string";
|
|
10539
|
+
if (installPathBad || projectPathBad) {
|
|
10540
|
+
process.stderr.write(`vault-sync: pin warning: malformed entry \u2014 non-string installPath/projectPath in installed_plugins.json[${key}]
|
|
10541
|
+
`);
|
|
10451
10542
|
continue;
|
|
10452
10543
|
}
|
|
10453
|
-
|
|
10454
|
-
|
|
10455
|
-
|
|
10456
|
-
|
|
10457
|
-
|
|
10458
|
-
|
|
10459
|
-
|
|
10544
|
+
const installPath = typeof installPathRaw === "string" ? installPathRaw : undefined;
|
|
10545
|
+
const projectPath = typeof projectPathRaw === "string" ? projectPathRaw : undefined;
|
|
10546
|
+
const normalizedInstallPath = installPath !== undefined ? normalizePath(installPath) : undefined;
|
|
10547
|
+
const normalizedProjectPath = projectPath !== undefined ? normalizePath(projectPath) : undefined;
|
|
10548
|
+
const inCache = normalizedInstallPath !== undefined && (normalizedInstallPath === normalizedCacheDir || normalizedInstallPath.startsWith(`${normalizedCacheDir}${pathSep}`));
|
|
10549
|
+
const isThisVault = normalizedInstallPath === normalizedVaultPluginDir;
|
|
10550
|
+
const isThisProject = normalizedProjectPath === normalizedVaultRoot;
|
|
10551
|
+
if (!isThisVault && !inCache && !isThisProject) {
|
|
10460
10552
|
continue;
|
|
10461
10553
|
}
|
|
10462
|
-
|
|
10463
|
-
|
|
10464
|
-
|
|
10554
|
+
if (normalizedInstallPath !== normalizedVaultPluginDir) {
|
|
10555
|
+
entry["installPath"] = vaultPluginDir;
|
|
10556
|
+
changed = true;
|
|
10557
|
+
}
|
|
10558
|
+
if (entry["version"] !== pluginVersion) {
|
|
10559
|
+
entry["version"] = pluginVersion;
|
|
10560
|
+
entry["lastUpdated"] = updatedAt;
|
|
10561
|
+
changed = true;
|
|
10562
|
+
}
|
|
10465
10563
|
}
|
|
10466
10564
|
}
|
|
10467
10565
|
if (!changed) {
|
|
10468
10566
|
return { skipped: false };
|
|
10469
10567
|
}
|
|
10470
|
-
|
|
10471
|
-
await writeFile2(tmpPath, JSON.stringify(data, null, 4), "utf8");
|
|
10472
|
-
await rename2(tmpPath, installedPluginsPath);
|
|
10568
|
+
await atomicWrite(installedPluginsPath, JSON.stringify(data, null, 4), "installed_plugins.json");
|
|
10473
10569
|
return { skipped: false };
|
|
10474
10570
|
}
|
|
10475
10571
|
async function cleanPluginCache(installedPluginsPath, installedPluginsCacheDir) {
|
|
@@ -10535,7 +10631,7 @@ async function cleanPluginCache(installedPluginsPath, installedPluginsCacheDir)
|
|
|
10535
10631
|
async function runVaultSync(vaultRoot, opts = {}) {
|
|
10536
10632
|
const fetchFn = opts.fetchFn ?? globalThis.fetch;
|
|
10537
10633
|
const isTTY = opts.isTTY ?? process.stdout.isTTY;
|
|
10538
|
-
const unlinkFn = opts.unlinkFn ??
|
|
10634
|
+
const unlinkFn = opts.unlinkFn ?? unlink2;
|
|
10539
10635
|
let updateChannel = "stable";
|
|
10540
10636
|
try {
|
|
10541
10637
|
const vaultYmlText = await readFile2(join5(vaultRoot, "vault.yml"), "utf8");
|
|
@@ -10637,7 +10733,7 @@ async function runVaultSync(vaultRoot, opts = {}) {
|
|
|
10637
10733
|
const destPath = join5(destObsidian, rel);
|
|
10638
10734
|
await mkdir2(dirname2(destPath), { recursive: true });
|
|
10639
10735
|
const content = await readFile2(srcPath);
|
|
10640
|
-
await
|
|
10736
|
+
await writeFile3(destPath, content);
|
|
10641
10737
|
}
|
|
10642
10738
|
} catch {}
|
|
10643
10739
|
}
|
|
@@ -10672,7 +10768,7 @@ async function runVaultSync(vaultRoot, opts = {}) {
|
|
|
10672
10768
|
if (harness === "claude") {
|
|
10673
10769
|
startSpinner("\uD83D\uDCCC", "Pinning to vault");
|
|
10674
10770
|
try {
|
|
10675
|
-
const pinResult = await pinToVault(vaultRoot, installedPluginsPath, installedPluginsCacheDir);
|
|
10771
|
+
const pinResult = await pinToVault(vaultRoot, installedPluginsPath, installedPluginsCacheDir, opts.now);
|
|
10676
10772
|
result.pinSkipped = pinResult.skipped;
|
|
10677
10773
|
if (pinResult.skipped) {
|
|
10678
10774
|
stopSpinner("pin skipped (not found or marketplace)");
|
|
@@ -10727,6 +10823,7 @@ async function vaultSyncCommand(vaultRoot, opts = {}) {
|
|
|
10727
10823
|
var import_picocolors6, import_yaml3;
|
|
10728
10824
|
var init_vault_sync = __esm(() => {
|
|
10729
10825
|
init_dist2();
|
|
10826
|
+
init_lib();
|
|
10730
10827
|
init_cli_ui();
|
|
10731
10828
|
init_harness();
|
|
10732
10829
|
import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
@@ -10761,7 +10858,7 @@ var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
|
10761
10858
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
10762
10859
|
function resolveBinaryVersion() {
|
|
10763
10860
|
if (true)
|
|
10764
|
-
return "2.1.
|
|
10861
|
+
return "2.1.12";
|
|
10765
10862
|
try {
|
|
10766
10863
|
const pkg = require_package();
|
|
10767
10864
|
return pkg.version ?? "dev";
|
|
@@ -11229,6 +11326,7 @@ async function runDoctor(opts = {}) {
|
|
|
11229
11326
|
const checkPluginFilesFn = opts.checkPluginFilesFn ?? checkPluginFiles;
|
|
11230
11327
|
const checkVaultYmlKeysFn = opts.checkVaultYmlKeysFn ?? checkVaultYmlKeys;
|
|
11231
11328
|
const checkSettingsHooksFn = opts.checkSettingsHooksFn ?? checkSettingsHooks;
|
|
11329
|
+
const checkClaudeSettingsFn = opts.checkClaudeSettingsFn ?? checkClaudeSettings;
|
|
11232
11330
|
if (isTTY) {
|
|
11233
11331
|
await printBanner();
|
|
11234
11332
|
}
|
|
@@ -11259,7 +11357,14 @@ async function runDoctor(opts = {}) {
|
|
|
11259
11357
|
if (vaultYmlResult.status === "ok") {
|
|
11260
11358
|
try {
|
|
11261
11359
|
config = await loadVaultConfigFn(vaultDir);
|
|
11262
|
-
} catch {
|
|
11360
|
+
} catch (err) {
|
|
11361
|
+
const code = err?.code;
|
|
11362
|
+
if (code !== "ENOENT") {
|
|
11363
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
11364
|
+
process.stderr.write(`doctor: vault.yml load warning: ${msg}
|
|
11365
|
+
`);
|
|
11366
|
+
}
|
|
11367
|
+
}
|
|
11263
11368
|
}
|
|
11264
11369
|
await randDelay();
|
|
11265
11370
|
sp1?.stop(fmtResult(vaultYmlResult), vaultYmlResult.details);
|
|
@@ -11269,6 +11374,7 @@ async function runDoctor(opts = {}) {
|
|
|
11269
11374
|
let pluginFilesResult;
|
|
11270
11375
|
let vaultYmlKeysResult;
|
|
11271
11376
|
let settingsHooksResult;
|
|
11377
|
+
let claudeSettingsResult;
|
|
11272
11378
|
if (isTTY) {
|
|
11273
11379
|
const sp2 = createStep("\u2699\uFE0F", "Config schema");
|
|
11274
11380
|
vaultYmlKeysResult = await checkVaultYmlKeysFn(vaultDir);
|
|
@@ -11294,6 +11400,10 @@ async function runDoctor(opts = {}) {
|
|
|
11294
11400
|
qmdResult = await checkQmdEmbeddingsFn(config);
|
|
11295
11401
|
await randDelay();
|
|
11296
11402
|
sp7.stop(fmtResult(qmdResult), qmdResult.details);
|
|
11403
|
+
const sp8 = createStep("\uD83D\uDED2", "Marketplace config");
|
|
11404
|
+
claudeSettingsResult = await checkClaudeSettingsFn(vaultDir);
|
|
11405
|
+
await randDelay();
|
|
11406
|
+
sp8.stop(fmtResult(claudeSettingsResult), claudeSettingsResult.details);
|
|
11297
11407
|
} else {
|
|
11298
11408
|
[
|
|
11299
11409
|
foldersResult,
|
|
@@ -11301,14 +11411,16 @@ async function runDoctor(opts = {}) {
|
|
|
11301
11411
|
orphanResult,
|
|
11302
11412
|
pluginFilesResult,
|
|
11303
11413
|
vaultYmlKeysResult,
|
|
11304
|
-
settingsHooksResult
|
|
11414
|
+
settingsHooksResult,
|
|
11415
|
+
claudeSettingsResult
|
|
11305
11416
|
] = await Promise.all([
|
|
11306
11417
|
checkFoldersFn(vaultDir, config),
|
|
11307
11418
|
checkQmdEmbeddingsFn(config),
|
|
11308
11419
|
checkOrphanCheckpointsFn(vaultDir, config),
|
|
11309
11420
|
checkPluginFilesFn(vaultDir),
|
|
11310
11421
|
checkVaultYmlKeysFn(vaultDir),
|
|
11311
|
-
checkSettingsHooksFn(vaultDir, config)
|
|
11422
|
+
checkSettingsHooksFn(vaultDir, config),
|
|
11423
|
+
checkClaudeSettingsFn(vaultDir)
|
|
11312
11424
|
]);
|
|
11313
11425
|
}
|
|
11314
11426
|
const results = [
|
|
@@ -11318,7 +11430,8 @@ async function runDoctor(opts = {}) {
|
|
|
11318
11430
|
pluginFilesResult,
|
|
11319
11431
|
settingsHooksResult,
|
|
11320
11432
|
orphanResult,
|
|
11321
|
-
qmdResult
|
|
11433
|
+
qmdResult,
|
|
11434
|
+
claudeSettingsResult
|
|
11322
11435
|
];
|
|
11323
11436
|
const totalChecks = results.length;
|
|
11324
11437
|
const errorCount = results.filter((r2) => r2.status === "error").length;
|
|
@@ -11351,14 +11464,17 @@ async function runDoctor(opts = {}) {
|
|
|
11351
11464
|
`);
|
|
11352
11465
|
}
|
|
11353
11466
|
}
|
|
11467
|
+
let fixFailedCount = 0;
|
|
11354
11468
|
if (opts.fix) {
|
|
11355
|
-
await applyFixes(vaultDir, results, isTTY, opts.registerHooksFn);
|
|
11469
|
+
fixFailedCount = await applyFixes(vaultDir, results, isTTY, opts.registerHooksFn);
|
|
11356
11470
|
}
|
|
11471
|
+
const ok = errorCount === 0 && fixFailedCount === 0;
|
|
11357
11472
|
return {
|
|
11358
|
-
ok
|
|
11359
|
-
exitCode:
|
|
11473
|
+
ok,
|
|
11474
|
+
exitCode: ok ? 0 : 1,
|
|
11360
11475
|
errorCount,
|
|
11361
|
-
warningCount
|
|
11476
|
+
warningCount,
|
|
11477
|
+
fixFailedCount
|
|
11362
11478
|
};
|
|
11363
11479
|
}
|
|
11364
11480
|
async function doctorCommand(opts = {}) {
|
|
@@ -11406,12 +11522,18 @@ function getFix(r2) {
|
|
|
11406
11522
|
};
|
|
11407
11523
|
}
|
|
11408
11524
|
const hasDeprecatedKeys = r2.details?.some((d) => d.includes("deprecated key: onebrain_version") || d.includes("deprecated key: method") || d.includes("deprecated key: runtime.harness"));
|
|
11409
|
-
|
|
11525
|
+
const hasMissingUpdateChannel = r2.details?.some((d) => d === "missing key: update_channel");
|
|
11526
|
+
if (r2.check === "vault.yml-keys" && r2.status === "warn" && (hasDeprecatedKeys || hasMissingUpdateChannel)) {
|
|
11410
11527
|
const deprecated = (r2.details ?? []).filter((d) => d.startsWith("deprecated key:")).map((d) => d.slice("deprecated key: ".length).split(" ")[0] ?? d);
|
|
11411
|
-
const
|
|
11528
|
+
const fixParts = [];
|
|
11529
|
+
if (hasMissingUpdateChannel)
|
|
11530
|
+
fixParts.push("add update_channel: stable");
|
|
11531
|
+
if (deprecated.length > 0)
|
|
11532
|
+
fixParts.push(`remove deprecated: ${deprecated.join(", ")}`);
|
|
11533
|
+
const description = fixParts.length > 0 ? `Fix vault.yml: ${fixParts.join("; ")}` : "Fix vault.yml";
|
|
11412
11534
|
return {
|
|
11413
11535
|
fn: async (vaultDir) => {
|
|
11414
|
-
const { readFile: readFile2
|
|
11536
|
+
const { readFile: readFile2 } = await import("fs/promises");
|
|
11415
11537
|
const { join: join5 } = await import("path");
|
|
11416
11538
|
const { parse: parse3, stringify } = await Promise.resolve().then(() => __toESM(require_dist(), 1));
|
|
11417
11539
|
const vaultYmlPath = join5(vaultDir, "vault.yml");
|
|
@@ -11431,10 +11553,10 @@ function getFix(r2) {
|
|
|
11431
11553
|
}
|
|
11432
11554
|
}
|
|
11433
11555
|
}
|
|
11434
|
-
|
|
11435
|
-
|
|
11436
|
-
|
|
11437
|
-
await
|
|
11556
|
+
if (details.some((d) => d === "missing key: update_channel")) {
|
|
11557
|
+
raw["update_channel"] = "stable";
|
|
11558
|
+
}
|
|
11559
|
+
await atomicWrite(vaultYmlPath, stringify(raw, { lineWidth: 0 }), "vault.yml");
|
|
11438
11560
|
},
|
|
11439
11561
|
description
|
|
11440
11562
|
};
|
|
@@ -11469,6 +11591,29 @@ function getFix(r2) {
|
|
|
11469
11591
|
description: `Embed ${count} unembedded document(s) (qmd update + embed)`
|
|
11470
11592
|
};
|
|
11471
11593
|
}
|
|
11594
|
+
if (r2.check === "claude-settings" && r2.status === "warn" && r2.details?.some((d) => d.startsWith("stale extraKnownMarketplaces.onebrain.source.repo:"))) {
|
|
11595
|
+
return {
|
|
11596
|
+
fn: async (vaultDir) => {
|
|
11597
|
+
const { readFile: readFile2 } = await import("fs/promises");
|
|
11598
|
+
const { join: join5 } = await import("path");
|
|
11599
|
+
const settingsPath = join5(vaultDir, ".claude", "settings.json");
|
|
11600
|
+
const text = await readFile2(settingsPath, "utf8");
|
|
11601
|
+
const raw = JSON.parse(text);
|
|
11602
|
+
const marketplaces = raw["extraKnownMarketplaces"];
|
|
11603
|
+
const onebrain = marketplaces?.["onebrain"];
|
|
11604
|
+
const source = onebrain?.["source"];
|
|
11605
|
+
if (!source || source["repo"] !== "kengio/onebrain")
|
|
11606
|
+
return;
|
|
11607
|
+
source["repo"] = "onebrain-ai/onebrain";
|
|
11608
|
+
const trailingNewline = text.endsWith(`
|
|
11609
|
+
`) ? `
|
|
11610
|
+
` : "";
|
|
11611
|
+
const updated = `${JSON.stringify(raw, null, 2)}${trailingNewline}`;
|
|
11612
|
+
await atomicWrite(settingsPath, updated, ".claude/settings.json");
|
|
11613
|
+
},
|
|
11614
|
+
description: "Rewrite stale marketplace repo: kengio/onebrain \u2192 onebrain-ai/onebrain"
|
|
11615
|
+
};
|
|
11616
|
+
}
|
|
11472
11617
|
if (r2.check === "folders" && r2.status === "error" && r2.hint) {
|
|
11473
11618
|
const missingStr = r2.hint.replace("Missing: ", "");
|
|
11474
11619
|
return {
|
|
@@ -11492,7 +11637,7 @@ async function applyFixes(vaultDir, results, isTTY, registerHooksFn) {
|
|
|
11492
11637
|
writeLine(`${import_picocolors5.default.green("\u25C6")} Nothing to fix`);
|
|
11493
11638
|
else
|
|
11494
11639
|
writeLine("nothing to fix");
|
|
11495
|
-
return;
|
|
11640
|
+
return 0;
|
|
11496
11641
|
}
|
|
11497
11642
|
if (isTTY) {
|
|
11498
11643
|
writeLine("");
|
|
@@ -11507,12 +11652,13 @@ async function applyFixes(vaultDir, results, isTTY, registerHooksFn) {
|
|
|
11507
11652
|
barLine(import_picocolors5.default.dim("No"));
|
|
11508
11653
|
barBlank();
|
|
11509
11654
|
close(`No changes made \u2014 run ${import_picocolors5.default.cyan("onebrain doctor --fix")} to apply`);
|
|
11510
|
-
return;
|
|
11655
|
+
return 0;
|
|
11511
11656
|
}
|
|
11512
11657
|
barLine("Yes");
|
|
11513
11658
|
barBlank();
|
|
11514
11659
|
}
|
|
11515
11660
|
let fixed = 0;
|
|
11661
|
+
let fixFailed = 0;
|
|
11516
11662
|
const unfixable = [];
|
|
11517
11663
|
for (const r2 of results) {
|
|
11518
11664
|
if (r2.status === "ok")
|
|
@@ -11528,6 +11674,7 @@ async function applyFixes(vaultDir, results, isTTY, registerHooksFn) {
|
|
|
11528
11674
|
if (isTTY)
|
|
11529
11675
|
barLine(`${import_picocolors5.default.green("\u25C6")} ${fix.description}`);
|
|
11530
11676
|
} catch (err) {
|
|
11677
|
+
fixFailed++;
|
|
11531
11678
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
11532
11679
|
if (isTTY) {
|
|
11533
11680
|
barLine(`${import_picocolors5.default.yellow("\u25B2")} Could not fix ${r2.check}: ${errMsg}`);
|
|
@@ -11541,6 +11688,9 @@ async function applyFixes(vaultDir, results, isTTY, registerHooksFn) {
|
|
|
11541
11688
|
barBlank();
|
|
11542
11689
|
if (fixed > 0)
|
|
11543
11690
|
barLine(`${import_picocolors5.default.green("\u25C6")} Fixed ${fixed} issue(s)`);
|
|
11691
|
+
if (fixFailed > 0) {
|
|
11692
|
+
barLine(`${import_picocolors5.default.yellow("\u25B2")} ${fixFailed} fix(es) failed \u2014 see warnings above`);
|
|
11693
|
+
}
|
|
11544
11694
|
if (unfixable.length > 0) {
|
|
11545
11695
|
barLine(`${import_picocolors5.default.yellow("\u25B2")} ${unfixable.length} issue(s) require manual action:`);
|
|
11546
11696
|
for (const r2 of unfixable) {
|
|
@@ -11551,18 +11701,22 @@ async function applyFixes(vaultDir, results, isTTY, registerHooksFn) {
|
|
|
11551
11701
|
close("Done");
|
|
11552
11702
|
} else {
|
|
11553
11703
|
process.stdout.write(`fixed: ${fixed}
|
|
11704
|
+
`);
|
|
11705
|
+
if (fixFailed > 0)
|
|
11706
|
+
process.stdout.write(`fix-failed: ${fixFailed}
|
|
11554
11707
|
`);
|
|
11555
11708
|
if (unfixable.length > 0) {
|
|
11556
11709
|
process.stdout.write(`manual: ${unfixable.map((r2) => r2.check).join(", ")}
|
|
11557
11710
|
`);
|
|
11558
11711
|
}
|
|
11559
11712
|
}
|
|
11713
|
+
return fixFailed;
|
|
11560
11714
|
}
|
|
11561
11715
|
|
|
11562
11716
|
// src/commands/init.ts
|
|
11563
11717
|
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
11564
11718
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
11565
|
-
import { mkdir as mkdir3, readFile as readFile3, readdir as readdir2, rename as rename3, stat as stat4, writeFile as
|
|
11719
|
+
import { mkdir as mkdir3, readFile as readFile3, readdir as readdir2, rename as rename3, stat as stat4, writeFile as writeFile4 } from "fs/promises";
|
|
11566
11720
|
import { homedir as homedir3 } from "os";
|
|
11567
11721
|
import { dirname as dirname3, join as join6 } from "path";
|
|
11568
11722
|
init_cli_ui();
|
|
@@ -11617,7 +11771,7 @@ var VAULT_YML_DEFAULTS = {
|
|
|
11617
11771
|
};
|
|
11618
11772
|
async function writeVaultYml(vaultDir) {
|
|
11619
11773
|
const content = import_yaml4.stringify(VAULT_YML_DEFAULTS, { lineWidth: 0 });
|
|
11620
|
-
await
|
|
11774
|
+
await writeFile4(join6(vaultDir, "vault.yml"), content, "utf8");
|
|
11621
11775
|
}
|
|
11622
11776
|
async function downloadPluginFiles(vaultDir, vaultSyncFn) {
|
|
11623
11777
|
const pluginJsonPath = join6(vaultDir, ".claude", "plugins", "onebrain", ".claude-plugin", "plugin.json");
|
|
@@ -11706,7 +11860,7 @@ async function registerPlugin(vaultDir, installedPluginsPath) {
|
|
|
11706
11860
|
const tmpPath = `${installedPluginsPath}.tmp`;
|
|
11707
11861
|
try {
|
|
11708
11862
|
await mkdir3(dirname3(installedPluginsPath), { recursive: true });
|
|
11709
|
-
await
|
|
11863
|
+
await writeFile4(tmpPath, JSON.stringify(data, null, 4), "utf8");
|
|
11710
11864
|
await rename3(tmpPath, installedPluginsPath);
|
|
11711
11865
|
} catch (err) {
|
|
11712
11866
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -11817,7 +11971,7 @@ async function installObsidianPlugins(vaultDir, opts) {
|
|
|
11817
11971
|
throw new Error(`HTTP ${resp.status}`);
|
|
11818
11972
|
}
|
|
11819
11973
|
const buf = await resp.arrayBuffer();
|
|
11820
|
-
await
|
|
11974
|
+
await writeFile4(join6(pluginDir, assetName), Buffer.from(buf));
|
|
11821
11975
|
} catch (err) {
|
|
11822
11976
|
if (assetName === "styles.css")
|
|
11823
11977
|
continue;
|
|
@@ -12201,7 +12355,7 @@ async function checkpointCommand(mode, token, vaultRoot) {
|
|
|
12201
12355
|
// src/commands/internal/migrate.ts
|
|
12202
12356
|
init_lib();
|
|
12203
12357
|
var import_yaml5 = __toESM(require_dist(), 1);
|
|
12204
|
-
import { readFile as readFile4, readdir as readdir3, writeFile as
|
|
12358
|
+
import { readFile as readFile4, readdir as readdir3, writeFile as writeFile5 } from "fs/promises";
|
|
12205
12359
|
import { join as join8 } from "path";
|
|
12206
12360
|
function parseFrontmatterWithRest(rawText) {
|
|
12207
12361
|
const text = rawText.replace(/\r\n/g, `
|
|
@@ -12285,7 +12439,7 @@ async function runBackfillRecapped(logsFolder, cutoffDate) {
|
|
|
12285
12439
|
const updatedContent = `---
|
|
12286
12440
|
${updatedFm}---
|
|
12287
12441
|
${rest}`;
|
|
12288
|
-
await
|
|
12442
|
+
await writeFile5(fpath, updatedContent, "utf8");
|
|
12289
12443
|
backfilled++;
|
|
12290
12444
|
} catch (error) {
|
|
12291
12445
|
process.stderr.write(`migrate: error processing ${fname}: ${error}
|
|
@@ -12451,7 +12605,7 @@ init_register_hooks();
|
|
|
12451
12605
|
|
|
12452
12606
|
// src/commands/internal/session-init.ts
|
|
12453
12607
|
init_lib();
|
|
12454
|
-
import { unlink as
|
|
12608
|
+
import { unlink as unlink3 } from "fs/promises";
|
|
12455
12609
|
import { tmpdir as osTmpdir2 } from "os";
|
|
12456
12610
|
import { join as join10 } from "path";
|
|
12457
12611
|
var DAY_NAMES = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
@@ -12564,7 +12718,7 @@ async function cleanStaleStateFile(token, tmpDir) {
|
|
|
12564
12718
|
const mtimeMs = mtime instanceof Date ? mtime.getTime() : Number(mtime) * 1000;
|
|
12565
12719
|
if (mtimeMs < processStartMs) {
|
|
12566
12720
|
try {
|
|
12567
|
-
await
|
|
12721
|
+
await unlink3(stateFile);
|
|
12568
12722
|
} catch {}
|
|
12569
12723
|
}
|
|
12570
12724
|
} catch {}
|
|
@@ -12848,8 +13002,8 @@ function patchUtf8(stream) {
|
|
|
12848
13002
|
}
|
|
12849
13003
|
|
|
12850
13004
|
// src/index.ts
|
|
12851
|
-
var VERSION = "2.1.
|
|
12852
|
-
var RELEASE_DATE = "2026-05-
|
|
13005
|
+
var VERSION = "2.1.12";
|
|
13006
|
+
var RELEASE_DATE = "2026-05-06";
|
|
12853
13007
|
patchUtf8(process.stdout);
|
|
12854
13008
|
patchUtf8(process.stderr);
|
|
12855
13009
|
var VERSION_STRING = `OneBrain v${VERSION} \u2014 released ${RELEASE_DATE}`;
|