@onebrain-ai/cli 2.1.4 → 2.1.6
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/onebrain +387 -202
- package/package.json +1 -1
package/dist/onebrain
CHANGED
|
@@ -9105,10 +9105,10 @@ async function checkQmdEmbeddings(config) {
|
|
|
9105
9105
|
check: "qmd-embeddings",
|
|
9106
9106
|
status: "warn",
|
|
9107
9107
|
message: summary,
|
|
9108
|
-
hint: "
|
|
9108
|
+
hint: "Advisory: run /qmd embed when ready (or onebrain doctor --fix)",
|
|
9109
9109
|
details: [
|
|
9110
9110
|
`collection: ${config.qmd_collection}`,
|
|
9111
|
-
"
|
|
9111
|
+
"Advisory: run /qmd embed when ready (or onebrain doctor --fix)"
|
|
9112
9112
|
]
|
|
9113
9113
|
};
|
|
9114
9114
|
}
|
|
@@ -9140,20 +9140,7 @@ async function checkOrphanCheckpoints(vaultRoot, config) {
|
|
|
9140
9140
|
message: "0 orphans"
|
|
9141
9141
|
};
|
|
9142
9142
|
}
|
|
9143
|
-
|
|
9144
|
-
return {
|
|
9145
|
-
check: "orphan-checkpoints",
|
|
9146
|
-
status: "ok",
|
|
9147
|
-
message: "0 orphans"
|
|
9148
|
-
};
|
|
9149
|
-
}
|
|
9150
|
-
let orphanCount = 0;
|
|
9151
|
-
for (const filePath of checkpointFiles) {
|
|
9152
|
-
const merged = await readMergedField(filePath);
|
|
9153
|
-
if (merged !== true) {
|
|
9154
|
-
orphanCount++;
|
|
9155
|
-
}
|
|
9156
|
-
}
|
|
9143
|
+
const orphanCount = checkpointFiles.length;
|
|
9157
9144
|
if (orphanCount === 0) {
|
|
9158
9145
|
return {
|
|
9159
9146
|
check: "orphan-checkpoints",
|
|
@@ -9169,30 +9156,6 @@ async function checkOrphanCheckpoints(vaultRoot, config) {
|
|
|
9169
9156
|
details: ["Run /wrapup to synthesize and merge them"]
|
|
9170
9157
|
};
|
|
9171
9158
|
}
|
|
9172
|
-
async function readMergedField(filePath) {
|
|
9173
|
-
try {
|
|
9174
|
-
const file = Bun.file(filePath);
|
|
9175
|
-
const text = await file.text();
|
|
9176
|
-
if (!text.startsWith("---"))
|
|
9177
|
-
return;
|
|
9178
|
-
const endIdx = text.indexOf(`
|
|
9179
|
-
---`, 3);
|
|
9180
|
-
if (endIdx === -1)
|
|
9181
|
-
return;
|
|
9182
|
-
const frontmatter = text.slice(3, endIdx).trim();
|
|
9183
|
-
const parsed = import_yaml2.parse(frontmatter);
|
|
9184
|
-
if (!parsed)
|
|
9185
|
-
return;
|
|
9186
|
-
const merged = parsed["merged"];
|
|
9187
|
-
if (merged === true || merged === "true")
|
|
9188
|
-
return true;
|
|
9189
|
-
if (merged === false || merged === "false")
|
|
9190
|
-
return false;
|
|
9191
|
-
return;
|
|
9192
|
-
} catch {
|
|
9193
|
-
return;
|
|
9194
|
-
}
|
|
9195
|
-
}
|
|
9196
9159
|
async function checkPluginFiles(vaultRoot) {
|
|
9197
9160
|
const pluginBase = join2(vaultRoot, ".claude", "plugins", "onebrain");
|
|
9198
9161
|
const missingFiles = [];
|
|
@@ -9401,17 +9364,16 @@ async function checkSettingsHooks(vaultRoot, config) {
|
|
|
9401
9364
|
confirmedHooks.push("PostToolUse \u2713");
|
|
9402
9365
|
}
|
|
9403
9366
|
}
|
|
9404
|
-
const precompactGroups = settings.hooks?.["PreCompact"] ?? [];
|
|
9405
|
-
const hasStalePreCompact = precompactGroups.some((g) => g.hooks?.some((h) => (h.command ?? "").includes(PRECOMPACT_ONEBRAIN_SUBSTRING)));
|
|
9406
|
-
if (hasStalePreCompact) {
|
|
9407
|
-
warnings.push("stale PreCompact hook found");
|
|
9408
|
-
}
|
|
9409
9367
|
for (const event of Object.keys(settings.hooks ?? {})) {
|
|
9410
9368
|
const groups = settings.hooks?.[event] ?? [];
|
|
9411
9369
|
for (const g of groups) {
|
|
9412
9370
|
for (const h of g.hooks ?? []) {
|
|
9371
|
+
const cmd = h.command ?? "";
|
|
9372
|
+
if (!ALLOWED_HOOK_EVENTS.has(event) && cmd.includes(ONEBRAIN_COMMAND_SUBSTRING)) {
|
|
9373
|
+
warnings.push(`stale ${event} hook found (onebrain CLI only registers Stop + PostToolUse)`);
|
|
9374
|
+
}
|
|
9413
9375
|
for (const sub of STALE_HOOK_SUBSTRINGS) {
|
|
9414
|
-
if (
|
|
9376
|
+
if (cmd.includes(sub)) {
|
|
9415
9377
|
warnings.push(`stale bash hook reference: ${sub}`);
|
|
9416
9378
|
}
|
|
9417
9379
|
}
|
|
@@ -9445,7 +9407,7 @@ async function checkSettingsHooks(vaultRoot, config) {
|
|
|
9445
9407
|
...okDetails.length > 0 ? { details: okDetails } : {}
|
|
9446
9408
|
};
|
|
9447
9409
|
}
|
|
9448
|
-
var import_yaml2, STANDARD_FOLDER_KEYS, REQUIRED_PLUGIN_FILES, REQUIRED_PLUGIN_DIRS, STALE_BASH_FILES, REQUIRED_VAULT_YML_KEYS, REQUIRED_FOLDER_KEYS, REQUIRED_HOOKS, QMD_HOOK_SUBSTRING = "onebrain qmd-reindex",
|
|
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;
|
|
9449
9411
|
var init_validator = __esm(() => {
|
|
9450
9412
|
import_yaml2 = __toESM(require_dist(), 1);
|
|
9451
9413
|
STANDARD_FOLDER_KEYS = [
|
|
@@ -9481,9 +9443,9 @@ var init_validator = __esm(() => {
|
|
|
9481
9443
|
"logs"
|
|
9482
9444
|
];
|
|
9483
9445
|
REQUIRED_HOOKS = [
|
|
9484
|
-
{ event: "Stop", cmdSubstring: "onebrain checkpoint stop" }
|
|
9485
|
-
{ event: "PostCompact", cmdSubstring: "onebrain checkpoint postcompact" }
|
|
9446
|
+
{ event: "Stop", cmdSubstring: "onebrain checkpoint stop" }
|
|
9486
9447
|
];
|
|
9448
|
+
ALLOWED_HOOK_EVENTS = new Set(["Stop", "PostToolUse"]);
|
|
9487
9449
|
STALE_HOOK_SUBSTRINGS = ["checkpoint-hook.sh", "session-init.sh"];
|
|
9488
9450
|
});
|
|
9489
9451
|
|
|
@@ -9497,7 +9459,7 @@ var init_lib = __esm(() => {
|
|
|
9497
9459
|
var require_package = __commonJS((exports, module) => {
|
|
9498
9460
|
module.exports = {
|
|
9499
9461
|
name: "@onebrain-ai/cli",
|
|
9500
|
-
version: "2.1.
|
|
9462
|
+
version: "2.1.6",
|
|
9501
9463
|
description: "CLI for OneBrain \u2014 personal AI OS for Obsidian with persistent memory, 24+ skills, and Claude Code integration",
|
|
9502
9464
|
keywords: [
|
|
9503
9465
|
"onebrain",
|
|
@@ -9562,6 +9524,10 @@ function barBlank() {
|
|
|
9562
9524
|
out(`${bar}
|
|
9563
9525
|
`);
|
|
9564
9526
|
}
|
|
9527
|
+
function barOpen(msg) {
|
|
9528
|
+
out(`${import_picocolors2.default.cyan("\u250C")} ${msg}
|
|
9529
|
+
`);
|
|
9530
|
+
}
|
|
9565
9531
|
function close(msg, isError = false, isWarning = false) {
|
|
9566
9532
|
if (isError) {
|
|
9567
9533
|
out(`${import_picocolors2.default.cyan("\u2514")} ${import_picocolors2.default.bold(import_picocolors2.default.red(msg))}
|
|
@@ -10011,12 +9977,22 @@ function applyHooks(settings) {
|
|
|
10011
9977
|
settings.hooks = {};
|
|
10012
9978
|
const hooks = settings.hooks;
|
|
10013
9979
|
const result = {};
|
|
10014
|
-
for (const
|
|
10015
|
-
if (
|
|
9980
|
+
for (const event of Object.keys(hooks)) {
|
|
9981
|
+
if (ALLOWED_HOOK_EVENTS2.has(event))
|
|
10016
9982
|
continue;
|
|
10017
|
-
|
|
10018
|
-
|
|
9983
|
+
const groups = hooks[event] ?? [];
|
|
9984
|
+
const filtered = groups.map((group) => ({
|
|
9985
|
+
...group,
|
|
9986
|
+
hooks: (group.hooks ?? []).filter((entry) => {
|
|
9987
|
+
const cmd = entry.command ?? "";
|
|
9988
|
+
return !cmd.includes("onebrain");
|
|
9989
|
+
})
|
|
9990
|
+
})).filter((group) => (group.hooks?.length ?? 0) > 0);
|
|
9991
|
+
if (filtered.length === 0) {
|
|
10019
9992
|
delete hooks[event];
|
|
9993
|
+
} else {
|
|
9994
|
+
hooks[event] = filtered;
|
|
9995
|
+
}
|
|
10020
9996
|
}
|
|
10021
9997
|
for (const event of HOOK_EVENTS) {
|
|
10022
9998
|
const cmd = HOOK_COMMANDS[event];
|
|
@@ -10205,20 +10181,16 @@ async function registerHooksCommand(vaultDir) {
|
|
|
10205
10181
|
process.exit(1);
|
|
10206
10182
|
}
|
|
10207
10183
|
}
|
|
10208
|
-
var import_picocolors4, HOOK_COMMANDS, HOOK_EVENTS,
|
|
10184
|
+
var import_picocolors4, HOOK_COMMANDS, HOOK_EVENTS, PERMISSIONS_TO_ADD, ONEBRAIN_MARKER = "# onebrain", PATH_EXPORT = 'export PATH="$HOME/.bun/bin:$HOME/.npm-global/bin:$PATH"', ALLOWED_HOOK_EVENTS2, QMD_CMD = "onebrain qmd-reindex", QMD_MATCHER = "Write|Edit";
|
|
10209
10185
|
var init_register_hooks = __esm(() => {
|
|
10210
10186
|
init_dist2();
|
|
10211
10187
|
init_lib();
|
|
10212
10188
|
init_harness();
|
|
10213
10189
|
import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
10214
10190
|
HOOK_COMMANDS = {
|
|
10215
|
-
Stop: "onebrain checkpoint stop"
|
|
10216
|
-
PostCompact: "onebrain checkpoint postcompact"
|
|
10217
|
-
};
|
|
10218
|
-
HOOK_EVENTS = ["Stop", "PostCompact"];
|
|
10219
|
-
STALE_HOOK_COMMANDS = {
|
|
10220
|
-
PreCompact: "onebrain checkpoint precompact"
|
|
10191
|
+
Stop: "onebrain checkpoint stop"
|
|
10221
10192
|
};
|
|
10193
|
+
HOOK_EVENTS = ["Stop"];
|
|
10222
10194
|
PERMISSIONS_TO_ADD = [
|
|
10223
10195
|
"Read",
|
|
10224
10196
|
"Write",
|
|
@@ -10235,6 +10207,7 @@ var init_register_hooks = __esm(() => {
|
|
|
10235
10207
|
"WebFetch",
|
|
10236
10208
|
"WebSearch"
|
|
10237
10209
|
];
|
|
10210
|
+
ALLOWED_HOOK_EVENTS2 = new Set(["Stop", "PostToolUse"]);
|
|
10238
10211
|
});
|
|
10239
10212
|
|
|
10240
10213
|
// src/commands/internal/vault-sync.ts
|
|
@@ -10788,7 +10761,7 @@ var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
|
10788
10761
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
10789
10762
|
function resolveBinaryVersion() {
|
|
10790
10763
|
if (true)
|
|
10791
|
-
return "2.1.
|
|
10764
|
+
return "2.1.6";
|
|
10792
10765
|
try {
|
|
10793
10766
|
const pkg = require_package();
|
|
10794
10767
|
return pkg.version ?? "dev";
|
|
@@ -10797,43 +10770,52 @@ function resolveBinaryVersion() {
|
|
|
10797
10770
|
}
|
|
10798
10771
|
}
|
|
10799
10772
|
var ART_LINES = [
|
|
10800
|
-
` \u25C6${"\u2500".repeat(
|
|
10801
|
-
"
|
|
10802
|
-
"
|
|
10803
|
-
"
|
|
10804
|
-
` \u25C6${"\u2500".repeat(
|
|
10773
|
+
` \u25C6${"\u2500".repeat(26)}\u25C6`,
|
|
10774
|
+
" \u250C\u2500\u2510\u250C\u2510\u2577\u250C\u2500\u2574\u250C\u2510 \u250C\u2500\u2510\u250C\u2500\u2510\u2577\u250C\u2510\u2577",
|
|
10775
|
+
" \u2502 \u2502\u2502\u2514\u2524\u251C\u2574 \u251C\u2534\u2510\u251C\u252C\u2518\u251C\u2500\u2524\u2502\u2502\u2514\u2524",
|
|
10776
|
+
" \u2514\u2500\u2518\u2575 \u2575\u2514\u2500\u2574\u2514\u2500\u2518\u2575\u2514\u2574\u2575 \u2575\u2575\u2575 \u2575",
|
|
10777
|
+
` \u25C6${"\u2500".repeat(26)}\u25C6`
|
|
10805
10778
|
];
|
|
10806
|
-
var
|
|
10779
|
+
var PREFIX = "Your AI ";
|
|
10780
|
+
var TAGLINE_LEAD = " ";
|
|
10781
|
+
var TAGLINE_FALLBACK = `${PREFIX}Thinking Partner`;
|
|
10807
10782
|
var BANNER_LINE_COUNT = 1 + ART_LINES.length + 3;
|
|
10783
|
+
var PREFIX_COLOR = [120, 230, 255];
|
|
10784
|
+
var TRAILING_COLOR = [255, 80, 255];
|
|
10785
|
+
var FINAL_COLOR = [120, 230, 255];
|
|
10786
|
+
var SENTENCES = [
|
|
10787
|
+
{ trailing: "Remembers You", trailingWords: ["Remembers", "You"], wordTicks: [24, 32] },
|
|
10788
|
+
{ trailing: "Catches Insights", trailingWords: ["Catches", "Insights"], wordTicks: [27, 26] },
|
|
10789
|
+
{ trailing: "Thinking Partner", trailingWords: ["Thinking", "Partner"], wordTicks: [26, 31] }
|
|
10790
|
+
];
|
|
10808
10791
|
function supportsRgb() {
|
|
10809
10792
|
const c = process.env["COLORTERM"] ?? "";
|
|
10810
10793
|
return c === "truecolor" || c === "24bit";
|
|
10811
10794
|
}
|
|
10795
|
+
function rgb(r, g, b, ch) {
|
|
10796
|
+
return `\x1B[1;38;2;${r};${g};${b}m${ch}\x1B[0m`;
|
|
10797
|
+
}
|
|
10798
|
+
function rgbStr(c, ch) {
|
|
10799
|
+
return rgb(c[0], c[1], c[2], ch);
|
|
10800
|
+
}
|
|
10812
10801
|
function hsvToRgb(h, floor = 80) {
|
|
10813
10802
|
const c = 255;
|
|
10814
10803
|
const x = Math.round(c * (1 - Math.abs(h / 60 % 2 - 1)));
|
|
10815
10804
|
let r = 0;
|
|
10816
10805
|
let g = 0;
|
|
10817
10806
|
let b = 0;
|
|
10818
|
-
if (h < 60)
|
|
10819
|
-
r = c;
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
|
|
10823
|
-
g = c;
|
|
10824
|
-
|
|
10825
|
-
g = c;
|
|
10826
|
-
|
|
10827
|
-
|
|
10828
|
-
|
|
10829
|
-
b = c;
|
|
10830
|
-
} else if (h < 300) {
|
|
10831
|
-
r = x;
|
|
10832
|
-
b = c;
|
|
10833
|
-
} else {
|
|
10834
|
-
r = c;
|
|
10835
|
-
b = x;
|
|
10836
|
-
}
|
|
10807
|
+
if (h < 60)
|
|
10808
|
+
[r, g, b] = [c, x, 0];
|
|
10809
|
+
else if (h < 120)
|
|
10810
|
+
[r, g, b] = [x, c, 0];
|
|
10811
|
+
else if (h < 180)
|
|
10812
|
+
[r, g, b] = [0, c, x];
|
|
10813
|
+
else if (h < 240)
|
|
10814
|
+
[r, g, b] = [0, x, c];
|
|
10815
|
+
else if (h < 300)
|
|
10816
|
+
[r, g, b] = [x, 0, c];
|
|
10817
|
+
else
|
|
10818
|
+
[r, g, b] = [c, 0, x];
|
|
10837
10819
|
return [Math.min(255, r + floor), Math.min(255, g + floor), Math.min(255, b + floor)];
|
|
10838
10820
|
}
|
|
10839
10821
|
var HUE_PER_CHAR = 10;
|
|
@@ -10844,15 +10826,25 @@ function neonLine(line, lineIndex = 0, floor = 80) {
|
|
|
10844
10826
|
return ch;
|
|
10845
10827
|
const hue = ((i * HUE_PER_CHAR - lineIndex * HUE_PER_ROW) % 360 + 360) % 360;
|
|
10846
10828
|
const [r, g, b] = hsvToRgb(hue, floor);
|
|
10847
|
-
return
|
|
10829
|
+
return rgb(r, g, b, ch);
|
|
10848
10830
|
}).join("");
|
|
10849
10831
|
}
|
|
10850
|
-
function
|
|
10851
|
-
return line.split("").map((ch) => ch === " " ? ch : `\x1B[1;
|
|
10832
|
+
function whiteLine(line) {
|
|
10833
|
+
return line.split("").map((ch) => ch === " " ? ch : `\x1B[1;97m${ch}\x1B[0m`).join("");
|
|
10834
|
+
}
|
|
10835
|
+
function whiteGlowLine(line, alpha) {
|
|
10836
|
+
return line.split("").map((ch) => ch === " " ? ch : `\x1B[1;38;2;${alpha};${alpha};${alpha}m${ch}\x1B[0m`).join("");
|
|
10852
10837
|
}
|
|
10853
10838
|
function dimLine(line) {
|
|
10854
10839
|
return line.split("").map((ch) => ch === " " ? ch : `\x1B[2;38;2;50;50;70m${ch}\x1B[0m`).join("");
|
|
10855
10840
|
}
|
|
10841
|
+
function scanLineCh(line) {
|
|
10842
|
+
return line.split("").map((ch) => ch === " " ? ch : rgb(140, 255, 255, ch)).join("");
|
|
10843
|
+
}
|
|
10844
|
+
var CURSOR = rgb(140, 255, 255, "\u258C");
|
|
10845
|
+
var GLYPHS = "\u2593\u2591\u2592\u2588\u2502\u2524\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u256A\u256B\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u2518\u250C\u2551\u258C\u2580\u2584\u2590\u2206\u0192\u03A9\xA7\xB6\xB1\xF7\xD7\xF8\xA5\u20AC";
|
|
10846
|
+
var randGlyph = () => GLYPHS[Math.floor(Math.random() * GLYPHS.length)] ?? "?";
|
|
10847
|
+
var glitchWhite = (g) => `\x1B[1;97m${g}\x1B[0m`;
|
|
10856
10848
|
function outb(str) {
|
|
10857
10849
|
process.stdout.write(Buffer.from(str, "utf8"));
|
|
10858
10850
|
}
|
|
@@ -10869,11 +10861,274 @@ function printFrame(artLines, tagline) {
|
|
|
10869
10861
|
outb(`
|
|
10870
10862
|
`);
|
|
10871
10863
|
}
|
|
10864
|
+
function blankTagline() {
|
|
10865
|
+
return `${TAGLINE_LEAD}${" ".repeat(TAGLINE_FALLBACK.length)}`;
|
|
10866
|
+
}
|
|
10867
|
+
function buildTaglineLine(prefixLockedChars, trailingPart) {
|
|
10868
|
+
let s = TAGLINE_LEAD;
|
|
10869
|
+
for (let i = 0;i < PREFIX.length; i++) {
|
|
10870
|
+
if (i < prefixLockedChars) {
|
|
10871
|
+
s += PREFIX[i] === " " ? " " : rgbStr(PREFIX_COLOR, PREFIX[i]);
|
|
10872
|
+
} else {
|
|
10873
|
+
s += " ";
|
|
10874
|
+
}
|
|
10875
|
+
}
|
|
10876
|
+
s += trailingPart;
|
|
10877
|
+
return `${s}\x1B[K`;
|
|
10878
|
+
}
|
|
10879
|
+
var LOCK_LATENCY = 4;
|
|
10880
|
+
var PREFIX_TICK_MS = [27, 27];
|
|
10881
|
+
var INTER_WORD_PAUSE_MS = 65;
|
|
10882
|
+
var SENTENCE_HOLD_MS = 500;
|
|
10883
|
+
var WIPE_TICK_MS = 22;
|
|
10884
|
+
var WIPE_TRAIL = 3;
|
|
10885
|
+
var WIPE_PAUSE_MS = 80;
|
|
10886
|
+
async function playBannerIntro(rainbowArt, whiteArt) {
|
|
10887
|
+
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
10888
|
+
const up = (n) => outb(`\x1B[${n}F`);
|
|
10889
|
+
printFrame(ART_LINES.map(dimLine), blankTagline());
|
|
10890
|
+
for (let scan = 0;scan < ART_LINES.length; scan++) {
|
|
10891
|
+
await delay(55);
|
|
10892
|
+
up(BANNER_LINE_COUNT);
|
|
10893
|
+
printFrame(ART_LINES.map((l, i) => {
|
|
10894
|
+
if (i < scan - 2)
|
|
10895
|
+
return whiteLine(l);
|
|
10896
|
+
if (i === scan - 2)
|
|
10897
|
+
return whiteGlowLine(l, 200);
|
|
10898
|
+
if (i === scan - 1)
|
|
10899
|
+
return whiteGlowLine(l, 230);
|
|
10900
|
+
if (i === scan)
|
|
10901
|
+
return scanLineCh(l);
|
|
10902
|
+
return dimLine(l);
|
|
10903
|
+
}), blankTagline());
|
|
10904
|
+
}
|
|
10905
|
+
await delay(40);
|
|
10906
|
+
up(BANNER_LINE_COUNT);
|
|
10907
|
+
printFrame(whiteArt, blankTagline());
|
|
10908
|
+
await delay(600);
|
|
10909
|
+
let minD = 0;
|
|
10910
|
+
let maxD = 0;
|
|
10911
|
+
for (let row = 0;row < ART_LINES.length; row++) {
|
|
10912
|
+
minD = Math.min(minD, -row * 3);
|
|
10913
|
+
maxD = Math.max(maxD, ART_LINES[row].length - 1 - row * 3);
|
|
10914
|
+
}
|
|
10915
|
+
function flowFrame(frontD) {
|
|
10916
|
+
return ART_LINES.map((line, row) => line.split("").map((ch, col) => {
|
|
10917
|
+
if (ch === " ")
|
|
10918
|
+
return ch;
|
|
10919
|
+
const d = col - 3 * row;
|
|
10920
|
+
if (d <= frontD) {
|
|
10921
|
+
const hue = ((col * HUE_PER_CHAR - row * HUE_PER_ROW) % 360 + 360) % 360;
|
|
10922
|
+
const [r, g, b] = hsvToRgb(hue);
|
|
10923
|
+
return rgb(r, g, b, ch);
|
|
10924
|
+
}
|
|
10925
|
+
return `\x1B[1;97m${ch}\x1B[0m`;
|
|
10926
|
+
}).join(""));
|
|
10927
|
+
}
|
|
10928
|
+
for (let d = minD;d <= maxD; d++) {
|
|
10929
|
+
await delay(9);
|
|
10930
|
+
up(BANNER_LINE_COUNT);
|
|
10931
|
+
printFrame(flowFrame(d), blankTagline());
|
|
10932
|
+
}
|
|
10933
|
+
up(BANNER_LINE_COUNT);
|
|
10934
|
+
printFrame(rainbowArt, blankTagline());
|
|
10935
|
+
await delay(180);
|
|
10936
|
+
function shimmerArtFrame(highlight) {
|
|
10937
|
+
return ART_LINES.map((line, row) => line.split("").map((ch, col) => {
|
|
10938
|
+
if (ch === " ")
|
|
10939
|
+
return ch;
|
|
10940
|
+
const d = col - 3 * row;
|
|
10941
|
+
if (Math.abs(d - highlight) <= 1)
|
|
10942
|
+
return `\x1B[1;97m${ch}\x1B[0m`;
|
|
10943
|
+
const hue = ((col * HUE_PER_CHAR - row * HUE_PER_ROW) % 360 + 360) % 360;
|
|
10944
|
+
const [r, g, b] = hsvToRgb(hue);
|
|
10945
|
+
return rgb(r, g, b, ch);
|
|
10946
|
+
}).join(""));
|
|
10947
|
+
}
|
|
10948
|
+
for (let d = minD;d <= maxD; d++) {
|
|
10949
|
+
await delay(9);
|
|
10950
|
+
up(BANNER_LINE_COUNT);
|
|
10951
|
+
printFrame(shimmerArtFrame(d), blankTagline());
|
|
10952
|
+
}
|
|
10953
|
+
up(BANNER_LINE_COUNT);
|
|
10954
|
+
printFrame(rainbowArt, blankTagline());
|
|
10955
|
+
await delay(80);
|
|
10956
|
+
}
|
|
10957
|
+
async function decodeFirstSentence(rainbowArt, s) {
|
|
10958
|
+
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
10959
|
+
const up = (n) => outb(`\x1B[${n}F`);
|
|
10960
|
+
const prefixWords = ["Your", "AI"];
|
|
10961
|
+
for (let wi = 0;wi < prefixWords.length; wi++) {
|
|
10962
|
+
const w = prefixWords[wi];
|
|
10963
|
+
const tickMs = PREFIX_TICK_MS[wi];
|
|
10964
|
+
const totalTicks = w.length + LOCK_LATENCY;
|
|
10965
|
+
const baseIdx = prefixWords.slice(0, wi).reduce((a, x) => a + x.length + 1, 0);
|
|
10966
|
+
for (let t = 1;t <= totalTicks; t++) {
|
|
10967
|
+
await delay(tickMs);
|
|
10968
|
+
up(BANNER_LINE_COUNT);
|
|
10969
|
+
let prefixPart = TAGLINE_LEAD;
|
|
10970
|
+
for (let i = 0;i < PREFIX.length; i++) {
|
|
10971
|
+
if (i < baseIdx) {
|
|
10972
|
+
prefixPart += PREFIX[i] === " " ? " " : rgbStr(PREFIX_COLOR, PREFIX[i]);
|
|
10973
|
+
} else if (i >= baseIdx + w.length) {
|
|
10974
|
+
prefixPart += " ";
|
|
10975
|
+
} else {
|
|
10976
|
+
const localIdx = i - baseIdx;
|
|
10977
|
+
const age = t - localIdx;
|
|
10978
|
+
if (age > LOCK_LATENCY)
|
|
10979
|
+
prefixPart += rgbStr(PREFIX_COLOR, PREFIX[i]);
|
|
10980
|
+
else if (age > 0)
|
|
10981
|
+
prefixPart += glitchWhite(randGlyph());
|
|
10982
|
+
else if (age === 0 && t < w.length)
|
|
10983
|
+
prefixPart += CURSOR;
|
|
10984
|
+
else
|
|
10985
|
+
prefixPart += " ";
|
|
10986
|
+
}
|
|
10987
|
+
}
|
|
10988
|
+
const trailingBlank = " ".repeat(s.trailing.length);
|
|
10989
|
+
printFrame(rainbowArt, `${prefixPart}${trailingBlank}\x1B[K`);
|
|
10990
|
+
}
|
|
10991
|
+
if (wi < prefixWords.length - 1) {
|
|
10992
|
+
await delay(INTER_WORD_PAUSE_MS);
|
|
10993
|
+
}
|
|
10994
|
+
}
|
|
10995
|
+
await delay(INTER_WORD_PAUSE_MS);
|
|
10996
|
+
await decodeTrailing(rainbowArt, s, PREFIX.length);
|
|
10997
|
+
}
|
|
10998
|
+
async function decodeTrailing(rainbowArt, s, lockedPrefixChars) {
|
|
10999
|
+
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
11000
|
+
const up = (n) => outb(`\x1B[${n}F`);
|
|
11001
|
+
const words = s.trailingWords;
|
|
11002
|
+
const ticks = s.wordTicks;
|
|
11003
|
+
const offsets = [];
|
|
11004
|
+
let off = 0;
|
|
11005
|
+
for (const w of words) {
|
|
11006
|
+
offsets.push(off);
|
|
11007
|
+
off += w.length + 1;
|
|
11008
|
+
}
|
|
11009
|
+
for (let wi = 0;wi < words.length; wi++) {
|
|
11010
|
+
const w = words[wi];
|
|
11011
|
+
const tickMs = ticks[wi];
|
|
11012
|
+
const totalTicks = w.length + LOCK_LATENCY;
|
|
11013
|
+
for (let t = 1;t <= totalTicks; t++) {
|
|
11014
|
+
await delay(tickMs);
|
|
11015
|
+
up(BANNER_LINE_COUNT);
|
|
11016
|
+
let trailing = "";
|
|
11017
|
+
for (let j = 0;j < s.trailing.length; j++) {
|
|
11018
|
+
const ch = s.trailing[j];
|
|
11019
|
+
if (ch === " ") {
|
|
11020
|
+
trailing += " ";
|
|
11021
|
+
continue;
|
|
11022
|
+
}
|
|
11023
|
+
let owningWi = -1;
|
|
11024
|
+
let localIdx = -1;
|
|
11025
|
+
for (let k = 0;k < words.length; k++) {
|
|
11026
|
+
const start = offsets[k];
|
|
11027
|
+
const end = start + words[k].length;
|
|
11028
|
+
if (j >= start && j < end) {
|
|
11029
|
+
owningWi = k;
|
|
11030
|
+
localIdx = j - start;
|
|
11031
|
+
break;
|
|
11032
|
+
}
|
|
11033
|
+
}
|
|
11034
|
+
if (owningWi < wi) {
|
|
11035
|
+
trailing += rgbStr(TRAILING_COLOR, ch);
|
|
11036
|
+
} else if (owningWi > wi) {
|
|
11037
|
+
trailing += " ";
|
|
11038
|
+
} else {
|
|
11039
|
+
const age = t - localIdx;
|
|
11040
|
+
if (age > LOCK_LATENCY)
|
|
11041
|
+
trailing += rgbStr(TRAILING_COLOR, ch);
|
|
11042
|
+
else if (age > 0)
|
|
11043
|
+
trailing += glitchWhite(randGlyph());
|
|
11044
|
+
else if (age === 0 && t < w.length)
|
|
11045
|
+
trailing += CURSOR;
|
|
11046
|
+
else
|
|
11047
|
+
trailing += " ";
|
|
11048
|
+
}
|
|
11049
|
+
}
|
|
11050
|
+
printFrame(rainbowArt, buildTaglineLine(lockedPrefixChars, trailing));
|
|
11051
|
+
}
|
|
11052
|
+
if (wi < words.length - 1) {
|
|
11053
|
+
await delay(INTER_WORD_PAUSE_MS);
|
|
11054
|
+
}
|
|
11055
|
+
}
|
|
11056
|
+
}
|
|
11057
|
+
async function wipeSwapTransition(rainbowArt, from, to) {
|
|
11058
|
+
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
11059
|
+
const up = (n) => outb(`\x1B[${n}F`);
|
|
11060
|
+
for (let pos = from.trailing.length - 1;pos >= -WIPE_TRAIL; pos--) {
|
|
11061
|
+
await delay(WIPE_TICK_MS);
|
|
11062
|
+
up(BANNER_LINE_COUNT);
|
|
11063
|
+
let trailing = "";
|
|
11064
|
+
for (let j = 0;j < from.trailing.length; j++) {
|
|
11065
|
+
const ch = from.trailing[j];
|
|
11066
|
+
if (ch === " ") {
|
|
11067
|
+
trailing += " ";
|
|
11068
|
+
continue;
|
|
11069
|
+
}
|
|
11070
|
+
const offset = j - pos;
|
|
11071
|
+
if (offset >= 0 && offset <= WIPE_TRAIL) {
|
|
11072
|
+
trailing += rgb(140, 255, 255, randGlyph());
|
|
11073
|
+
} else if (j > pos) {
|
|
11074
|
+
trailing += " ";
|
|
11075
|
+
} else {
|
|
11076
|
+
trailing += rgbStr(TRAILING_COLOR, ch);
|
|
11077
|
+
}
|
|
11078
|
+
}
|
|
11079
|
+
printFrame(rainbowArt, buildTaglineLine(PREFIX.length, trailing));
|
|
11080
|
+
}
|
|
11081
|
+
await delay(WIPE_PAUSE_MS);
|
|
11082
|
+
await decodeTrailing(rainbowArt, to, PREFIX.length);
|
|
11083
|
+
}
|
|
11084
|
+
async function lockShimmer(rainbowArt, s) {
|
|
11085
|
+
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
11086
|
+
const up = (n) => outb(`\x1B[${n}F`);
|
|
11087
|
+
const SHIMMER_TICK_MS = 22;
|
|
11088
|
+
const TRAIL = 3;
|
|
11089
|
+
const STOPS = [
|
|
11090
|
+
[255, 255, 255],
|
|
11091
|
+
[200, 245, 255],
|
|
11092
|
+
[150, 235, 255]
|
|
11093
|
+
];
|
|
11094
|
+
const fullText = PREFIX + s.trailing;
|
|
11095
|
+
const N = fullText.length;
|
|
11096
|
+
for (let pos = 0;pos <= N + TRAIL; pos++) {
|
|
11097
|
+
await delay(SHIMMER_TICK_MS);
|
|
11098
|
+
up(BANNER_LINE_COUNT);
|
|
11099
|
+
let line = TAGLINE_LEAD;
|
|
11100
|
+
for (let j = 0;j < N; j++) {
|
|
11101
|
+
const ch = fullText[j];
|
|
11102
|
+
if (ch === " ") {
|
|
11103
|
+
line += " ";
|
|
11104
|
+
continue;
|
|
11105
|
+
}
|
|
11106
|
+
const offset = pos - j;
|
|
11107
|
+
if (offset >= 0 && offset < TRAIL) {
|
|
11108
|
+
line += rgbStr(STOPS[offset], ch);
|
|
11109
|
+
} else if (offset >= TRAIL) {
|
|
11110
|
+
line += rgbStr(FINAL_COLOR, ch);
|
|
11111
|
+
} else {
|
|
11112
|
+
const baseColor = j < PREFIX.length ? PREFIX_COLOR : TRAILING_COLOR;
|
|
11113
|
+
line += rgbStr(baseColor, ch);
|
|
11114
|
+
}
|
|
11115
|
+
}
|
|
11116
|
+
line += "\x1B[K";
|
|
11117
|
+
printFrame(rainbowArt, line);
|
|
11118
|
+
}
|
|
11119
|
+
up(BANNER_LINE_COUNT);
|
|
11120
|
+
let finalLine = TAGLINE_LEAD;
|
|
11121
|
+
for (let j = 0;j < N; j++) {
|
|
11122
|
+
const ch = fullText[j];
|
|
11123
|
+
finalLine += ch === " " ? " " : rgbStr(FINAL_COLOR, ch);
|
|
11124
|
+
}
|
|
11125
|
+
finalLine += "\x1B[K";
|
|
11126
|
+
printFrame(rainbowArt, finalLine);
|
|
11127
|
+
await delay(150);
|
|
11128
|
+
}
|
|
10872
11129
|
async function printBanner() {
|
|
10873
11130
|
if (!process.stdout.isTTY)
|
|
10874
11131
|
return;
|
|
10875
|
-
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
10876
|
-
const up = (n) => outb(`\x1B[${n}F`);
|
|
10877
11132
|
if (!supportsRgb()) {
|
|
10878
11133
|
outb(`
|
|
10879
11134
|
`);
|
|
@@ -10882,84 +11137,24 @@ async function printBanner() {
|
|
|
10882
11137
|
`);
|
|
10883
11138
|
outb(`
|
|
10884
11139
|
`);
|
|
10885
|
-
outb(
|
|
11140
|
+
outb(`${TAGLINE_LEAD}${import_picocolors.default.bold(import_picocolors.default.cyan(TAGLINE_FALLBACK))}
|
|
10886
11141
|
`);
|
|
10887
11142
|
outb(`
|
|
10888
11143
|
`);
|
|
10889
11144
|
return;
|
|
10890
11145
|
}
|
|
10891
|
-
|
|
11146
|
+
const rainbowArt = ART_LINES.map((l, i) => neonLine(l, i));
|
|
11147
|
+
const whiteArt = ART_LINES.map((l) => whiteLine(l));
|
|
10892
11148
|
try {
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
return `\x1B[1;38;2;${r};${g};${b}m${ch}\x1B[0m`;
|
|
10903
|
-
}).join(""));
|
|
10904
|
-
};
|
|
10905
|
-
printFrame(ART_LINES.map(dimLine), ` ${" ".repeat(TAGLINE.length)}`);
|
|
10906
|
-
for (let scan = 0;scan < ART_LINES.length; scan++) {
|
|
10907
|
-
await delay(65);
|
|
10908
|
-
up(BANNER_LINE_COUNT);
|
|
10909
|
-
printFrame(ART_LINES.map((l, i) => {
|
|
10910
|
-
if (i < scan - 2)
|
|
10911
|
-
return neonLine(l, i);
|
|
10912
|
-
if (i === scan - 2)
|
|
10913
|
-
return neonLine(l, i, 120);
|
|
10914
|
-
if (i === scan - 1)
|
|
10915
|
-
return neonLine(l, i, 200);
|
|
10916
|
-
if (i === scan)
|
|
10917
|
-
return scanLine(l);
|
|
10918
|
-
return dimLine(l);
|
|
10919
|
-
}), ` ${" ".repeat(TAGLINE.length)}`);
|
|
10920
|
-
}
|
|
10921
|
-
await delay(60);
|
|
10922
|
-
up(BANNER_LINE_COUNT);
|
|
10923
|
-
printFrame(ART_LINES.map((l, i) => neonLine(l, i)), ` ${" ".repeat(TAGLINE.length)}`);
|
|
10924
|
-
let minD = 0;
|
|
10925
|
-
let maxD = 0;
|
|
10926
|
-
for (let row = 0;row < ART_LINES.length; row++) {
|
|
10927
|
-
minD = Math.min(minD, -row * 3);
|
|
10928
|
-
maxD = Math.max(maxD, ART_LINES[row].length - 1 - row * 3);
|
|
10929
|
-
}
|
|
10930
|
-
for (let d = minD;d <= maxD; d++) {
|
|
10931
|
-
await delay(16);
|
|
10932
|
-
up(BANNER_LINE_COUNT);
|
|
10933
|
-
printFrame(diagFrame(d), ` ${" ".repeat(TAGLINE.length)}`);
|
|
10934
|
-
}
|
|
10935
|
-
for (let d = maxD;d >= minD; d--) {
|
|
10936
|
-
await delay(16);
|
|
10937
|
-
up(BANNER_LINE_COUNT);
|
|
10938
|
-
printFrame(diagFrame(d), ` ${" ".repeat(TAGLINE.length)}`);
|
|
10939
|
-
}
|
|
10940
|
-
up(BANNER_LINE_COUNT);
|
|
10941
|
-
printFrame(ART_LINES.map((l, i) => neonLine(l, i)), ` ${" ".repeat(TAGLINE.length)}`);
|
|
10942
|
-
await delay(200);
|
|
10943
|
-
const cursor = "\x1B[1;38;2;140;255;255m\u258C\x1B[0m";
|
|
10944
|
-
for (let len = 1;len <= TAGLINE.length; len++) {
|
|
10945
|
-
await delay(32);
|
|
10946
|
-
up(BANNER_LINE_COUNT);
|
|
10947
|
-
const hasCursor = len < TAGLINE.length;
|
|
10948
|
-
printFrame(ART_LINES.map((l, i) => neonLine(l, i)), ` \x1B[1;97m${TAGLINE.slice(0, len)}\x1B[0m${hasCursor ? cursor : ""}${" ".repeat(Math.max(0, TAGLINE.length - len - 1))}`);
|
|
10949
|
-
}
|
|
10950
|
-
const tagWithCursor = ` \x1B[1;97m${TAGLINE}\x1B[0m${cursor}`;
|
|
10951
|
-
const tagWhite = ` \x1B[1;97m${TAGLINE}\x1B[0m\x1B[K`;
|
|
10952
|
-
for (let b = 0;b < 2; b++) {
|
|
10953
|
-
await delay(600);
|
|
10954
|
-
up(BANNER_LINE_COUNT);
|
|
10955
|
-
printFrame(ART_LINES.map((l, i) => neonLine(l, i)), tagWhite);
|
|
10956
|
-
await delay(600);
|
|
10957
|
-
up(BANNER_LINE_COUNT);
|
|
10958
|
-
printFrame(ART_LINES.map((l, i) => neonLine(l, i)), tagWithCursor);
|
|
10959
|
-
}
|
|
10960
|
-
await delay(600);
|
|
10961
|
-
up(BANNER_LINE_COUNT);
|
|
10962
|
-
printFrame(ART_LINES.map((l, i) => neonLine(l, i)), ` ${import_picocolors.default.bold(import_picocolors.default.magenta(TAGLINE))}\x1B[K`);
|
|
11149
|
+
outb("\x1B[?25l");
|
|
11150
|
+
await playBannerIntro(rainbowArt, whiteArt);
|
|
11151
|
+
await decodeFirstSentence(rainbowArt, SENTENCES[0]);
|
|
11152
|
+
await new Promise((r) => setTimeout(r, SENTENCE_HOLD_MS));
|
|
11153
|
+
await wipeSwapTransition(rainbowArt, SENTENCES[0], SENTENCES[1]);
|
|
11154
|
+
await new Promise((r) => setTimeout(r, SENTENCE_HOLD_MS));
|
|
11155
|
+
await wipeSwapTransition(rainbowArt, SENTENCES[1], SENTENCES[2]);
|
|
11156
|
+
await new Promise((r) => setTimeout(r, SENTENCE_HOLD_MS));
|
|
11157
|
+
await lockShimmer(rainbowArt, SENTENCES[2]);
|
|
10963
11158
|
} finally {
|
|
10964
11159
|
outb("\x1B[?25h");
|
|
10965
11160
|
}
|
|
@@ -11072,7 +11267,12 @@ async function runDoctor(opts = {}) {
|
|
|
11072
11267
|
const totalChecks = results.length;
|
|
11073
11268
|
const errorCount = results.filter((r2) => r2.status === "error").length;
|
|
11074
11269
|
const warningCount = results.filter((r2) => r2.status === "warn").length;
|
|
11075
|
-
const fixableCount = results.filter((r2) =>
|
|
11270
|
+
const fixableCount = results.filter((r2) => {
|
|
11271
|
+
if (r2.status === "ok")
|
|
11272
|
+
return false;
|
|
11273
|
+
const fix = getFix(r2);
|
|
11274
|
+
return fix !== null && !fix.advisory;
|
|
11275
|
+
}).length;
|
|
11076
11276
|
const showFixHint = !opts.fix && fixableCount > 0;
|
|
11077
11277
|
const summaryParts = [`${totalChecks} checks`];
|
|
11078
11278
|
if (errorCount > 0)
|
|
@@ -11187,6 +11387,7 @@ function getFix(r2) {
|
|
|
11187
11387
|
const pendingMatch = r2.message.match(/(\d+) unembedded/);
|
|
11188
11388
|
const count = pendingMatch?.[1] ?? "some";
|
|
11189
11389
|
return {
|
|
11390
|
+
advisory: true,
|
|
11190
11391
|
fn: async (vaultDir) => {
|
|
11191
11392
|
const { join: join5 } = await import("path");
|
|
11192
11393
|
const { parse: parseYaml } = await Promise.resolve().then(() => __toESM(require_dist(), 1));
|
|
@@ -11232,14 +11433,14 @@ async function applyFixes(vaultDir, results, isTTY, registerHooksFn) {
|
|
|
11232
11433
|
const fixable = results.filter((r2) => r2.status !== "ok" && getFix(r2) !== null);
|
|
11233
11434
|
if (fixable.length === 0) {
|
|
11234
11435
|
if (isTTY)
|
|
11235
|
-
|
|
11436
|
+
writeLine(`${import_picocolors5.default.green("\u25C6")} Nothing to fix`);
|
|
11236
11437
|
else
|
|
11237
11438
|
writeLine("nothing to fix");
|
|
11238
11439
|
return;
|
|
11239
11440
|
}
|
|
11240
11441
|
if (isTTY) {
|
|
11241
|
-
|
|
11242
|
-
|
|
11442
|
+
writeLine("");
|
|
11443
|
+
barOpen(import_picocolors5.default.bold(`${fixable.length} fix(es) to apply:`));
|
|
11243
11444
|
barBlank();
|
|
11244
11445
|
for (const r2 of fixable) {
|
|
11245
11446
|
barLine(` ${import_picocolors5.default.cyan("\u25C6")} ${getFix(r2).description}`);
|
|
@@ -11749,7 +11950,7 @@ async function runInit(opts = {}) {
|
|
|
11749
11950
|
}
|
|
11750
11951
|
if (sp6) {
|
|
11751
11952
|
await randDelay();
|
|
11752
|
-
sp6.stop(hooksOk ? undefined : "not registered \u2014 run onebrain update", hooksOk ? ["Stop \u2713
|
|
11953
|
+
sp6.stop(hooksOk ? undefined : "not registered \u2014 run onebrain update", hooksOk ? ["Stop \u2713", "Bash(onebrain *) \u2713"] : undefined);
|
|
11753
11954
|
} else {
|
|
11754
11955
|
writeLine(`hooks: ${hooksOk ? "ok" : "warning \u2014 hooks not registered; run onebrain update"}`);
|
|
11755
11956
|
}
|
|
@@ -11776,24 +11977,24 @@ async function initCommand(opts = {}) {
|
|
|
11776
11977
|
}
|
|
11777
11978
|
|
|
11778
11979
|
// src/commands/internal/checkpoint.ts
|
|
11779
|
-
import { readFileSync, readdirSync, writeFileSync } from "fs";
|
|
11980
|
+
import { readFileSync, readdirSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
11780
11981
|
import { tmpdir as osTmpdir } from "os";
|
|
11781
11982
|
import { join as join7 } from "path";
|
|
11782
11983
|
var SKIP_WINDOW = 60;
|
|
11783
11984
|
var MIN_ACTIVITY = 2;
|
|
11784
|
-
var PRECOMPACT_RECENCY = 300;
|
|
11785
11985
|
var DEFAULT_MESSAGES_THRESHOLD = 15;
|
|
11786
11986
|
var DEFAULT_MINUTES_THRESHOLD = 30;
|
|
11787
11987
|
function stateFilePath(token, tmpDir) {
|
|
11788
11988
|
return join7(tmpDir, `onebrain-${token}.state`);
|
|
11789
11989
|
}
|
|
11990
|
+
var FRESH_STATE_DISK = "0:0:00";
|
|
11790
11991
|
function readState(token, tmpDir = osTmpdir()) {
|
|
11791
11992
|
const path = stateFilePath(token, tmpDir);
|
|
11792
11993
|
try {
|
|
11793
11994
|
const raw = readFileSync(path, "utf8").trim();
|
|
11794
11995
|
const parts = raw.split(":");
|
|
11795
|
-
if (parts.length
|
|
11796
|
-
throw new Error("
|
|
11996
|
+
if (parts.length !== 3) {
|
|
11997
|
+
throw new Error("state file must be exactly 3 fields");
|
|
11797
11998
|
}
|
|
11798
11999
|
const count = Number(parts[0]);
|
|
11799
12000
|
const last_ts = Number(parts[1]);
|
|
@@ -11804,7 +12005,7 @@ function readState(token, tmpDir = osTmpdir()) {
|
|
|
11804
12005
|
return { count, last_ts, last_stop_nn };
|
|
11805
12006
|
} catch {
|
|
11806
12007
|
try {
|
|
11807
|
-
writeFileSync(stateFilePath(token, tmpDir),
|
|
12008
|
+
writeFileSync(stateFilePath(token, tmpDir), FRESH_STATE_DISK, "utf8");
|
|
11808
12009
|
} catch (writeErr) {
|
|
11809
12010
|
process.stderr.write(`checkpoint: failed to rewrite state file for token ${token}: ${writeErr}
|
|
11810
12011
|
`);
|
|
@@ -11818,12 +12019,17 @@ function readState(token, tmpDir = osTmpdir()) {
|
|
|
11818
12019
|
}
|
|
11819
12020
|
function writeState(token, state, tmpDir = osTmpdir()) {
|
|
11820
12021
|
const path = stateFilePath(token, tmpDir);
|
|
12022
|
+
const tmpPath = `${path}.tmp.${process.pid}`;
|
|
11821
12023
|
const content = `${state.count}:${state.last_ts}:${state.last_stop_nn}`;
|
|
11822
12024
|
try {
|
|
11823
|
-
writeFileSync(
|
|
12025
|
+
writeFileSync(tmpPath, content, "utf8");
|
|
12026
|
+
renameSync(tmpPath, path);
|
|
11824
12027
|
} catch (err) {
|
|
11825
12028
|
process.stderr.write(`checkpoint: failed to write state file ${path}: ${err}
|
|
11826
12029
|
`);
|
|
12030
|
+
try {
|
|
12031
|
+
unlinkSync(tmpPath);
|
|
12032
|
+
} catch {}
|
|
11827
12033
|
}
|
|
11828
12034
|
}
|
|
11829
12035
|
var DEFAULT_LOGS_FOLDER = "07-logs";
|
|
@@ -11903,11 +12109,11 @@ function handleStop(token, vaultRoot, now = Math.floor(Date.now() / 1000), tmpDi
|
|
|
11903
12109
|
const elapsed = state.last_ts === 0 ? 0 : now - state.last_ts;
|
|
11904
12110
|
const thresholdMet = state.count >= messagesThreshold || elapsed >= timeThreshold;
|
|
11905
12111
|
if (!thresholdMet) {
|
|
11906
|
-
writeState(token, {
|
|
12112
|
+
writeState(token, { ...state }, tmpDir);
|
|
11907
12113
|
return;
|
|
11908
12114
|
}
|
|
11909
12115
|
if (state.count < MIN_ACTIVITY) {
|
|
11910
|
-
writeState(token, {
|
|
12116
|
+
writeState(token, { ...state }, tmpDir);
|
|
11911
12117
|
return;
|
|
11912
12118
|
}
|
|
11913
12119
|
const date = formatDate(now);
|
|
@@ -11917,27 +12123,12 @@ function handleStop(token, vaultRoot, now = Math.floor(Date.now() / 1000), tmpDi
|
|
|
11917
12123
|
emitBlock(`${nextNn}${since}`);
|
|
11918
12124
|
writeState(token, { count: 0, last_ts: now, last_stop_nn: nextNn }, tmpDir);
|
|
11919
12125
|
}
|
|
11920
|
-
function handlePostcompact(token, _vaultRoot, now = Math.floor(Date.now() / 1000), tmpDir = osTmpdir()) {
|
|
11921
|
-
const state = readState(token, tmpDir);
|
|
11922
|
-
if (state.last_ts > 0 && now - state.last_ts < PRECOMPACT_RECENCY) {
|
|
11923
|
-
writeState(token, { count: 0, last_ts: state.last_ts, last_stop_nn: state.last_stop_nn }, tmpDir);
|
|
11924
|
-
return;
|
|
11925
|
-
}
|
|
11926
|
-
emitBlock("auto-wrapup");
|
|
11927
|
-
writeState(token, { count: 0, last_ts: now, last_stop_nn: state.last_stop_nn }, tmpDir);
|
|
11928
|
-
}
|
|
11929
|
-
function postcompactFallback(token, vaultRoot, now = Math.floor(Date.now() / 1000), tmpDir = osTmpdir()) {
|
|
11930
|
-
handlePostcompact(token, vaultRoot, now, tmpDir);
|
|
11931
|
-
}
|
|
11932
12126
|
async function checkpointCommand(mode, token, vaultRoot) {
|
|
11933
12127
|
try {
|
|
11934
12128
|
switch (mode) {
|
|
11935
12129
|
case "stop":
|
|
11936
12130
|
handleStop(token, vaultRoot);
|
|
11937
12131
|
break;
|
|
11938
|
-
case "postcompact":
|
|
11939
|
-
postcompactFallback(token, vaultRoot);
|
|
11940
|
-
break;
|
|
11941
12132
|
case "reset":
|
|
11942
12133
|
handleReset(token);
|
|
11943
12134
|
break;
|
|
@@ -12142,12 +12333,6 @@ async function scanMonthDir(monthDir, currentToken, today, seenTokens) {
|
|
|
12142
12333
|
continue;
|
|
12143
12334
|
if (seenTokens.has(ftoken))
|
|
12144
12335
|
continue;
|
|
12145
|
-
try {
|
|
12146
|
-
const content = await readFile5(join9(monthDir, fname), "utf8");
|
|
12147
|
-
const fm = parseFrontmatter(content);
|
|
12148
|
-
if (fm && (fm["merged"] === true || fm["merged"] === "true"))
|
|
12149
|
-
continue;
|
|
12150
|
-
} catch {}
|
|
12151
12336
|
if (await hasManualSessionLog(monthDir, fdate))
|
|
12152
12337
|
continue;
|
|
12153
12338
|
seenTokens.add(ftoken);
|
|
@@ -12608,8 +12793,8 @@ function patchUtf8(stream) {
|
|
|
12608
12793
|
}
|
|
12609
12794
|
|
|
12610
12795
|
// src/index.ts
|
|
12611
|
-
var VERSION = "2.1.
|
|
12612
|
-
var RELEASE_DATE = "2026-04-
|
|
12796
|
+
var VERSION = "2.1.6";
|
|
12797
|
+
var RELEASE_DATE = "2026-04-30";
|
|
12613
12798
|
patchUtf8(process.stdout);
|
|
12614
12799
|
patchUtf8(process.stderr);
|
|
12615
12800
|
var VERSION_STRING = `OneBrain v${VERSION} \u2014 released ${RELEASE_DATE}`;
|
|
@@ -12661,9 +12846,9 @@ program2.command("session-init", { hidden: true }).description("Emit session tok
|
|
|
12661
12846
|
program2.command("orphan-scan", { hidden: true }).description("Scan for orphaned checkpoint files in logs folder").argument("<logs_folder>", "path to logs folder").argument("<session_token>", "current session token to exclude").action(async (logsFolder, sessionToken) => {
|
|
12662
12847
|
await orphanScanCommand(logsFolder, sessionToken);
|
|
12663
12848
|
});
|
|
12664
|
-
program2.command("checkpoint", { hidden: true }).description("Handle checkpoint lifecycle (stop/
|
|
12849
|
+
program2.command("checkpoint", { hidden: true }).description("Handle checkpoint lifecycle (stop/reset)").argument("<mode>", "stop | reset").option("--vault-dir <path>", "vault root directory (default: auto-detect from cwd)").action(async (mode, opts) => {
|
|
12665
12850
|
const token = await resolveSessionToken();
|
|
12666
|
-
const vaultRoot = opts.vaultDir ?? findVaultRoot(process.cwd());
|
|
12851
|
+
const vaultRoot = mode === "stop" ? opts.vaultDir ?? findVaultRoot(process.cwd()) : "";
|
|
12667
12852
|
await checkpointCommand(mode, token, vaultRoot);
|
|
12668
12853
|
});
|
|
12669
12854
|
program2.command("qmd-reindex", { hidden: true }).description("Trigger qmd index rebuild").action(async () => {
|