@onebrain-ai/cli 2.1.5 → 2.1.7

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 CHANGED
@@ -3,10 +3,10 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- <a href="https://github.com/kengio/onebrain/releases"><img src="https://img.shields.io/badge/dynamic/json?url=https://raw.githubusercontent.com/kengio/onebrain/main/.claude/plugins/onebrain/.claude-plugin/plugin.json&query=%24.version&label=version&style=flat-square&color=blue" alt="Version" /></a>
7
- <a href="LICENSE"><img src="https://img.shields.io/github/license/kengio/onebrain?style=flat-square" alt="License" /></a>
8
- <a href="https://github.com/kengio/onebrain/stargazers"><img src="https://img.shields.io/github/stars/kengio/onebrain?style=flat-square" alt="GitHub Stars" /></a>
9
- <a href="https://github.com/kengio/onebrain/commits/main"><img src="https://img.shields.io/github/last-commit/kengio/onebrain?style=flat-square" alt="Last Commit" /></a>
6
+ <a href="https://github.com/onebrain-ai/onebrain/releases"><img src="https://img.shields.io/badge/dynamic/json?url=https://raw.githubusercontent.com/onebrain-ai/onebrain/main/.claude/plugins/onebrain/.claude-plugin/plugin.json&query=%24.version&label=version&style=flat-square&color=blue" alt="Version" /></a>
7
+ <a href="LICENSE"><img src="https://img.shields.io/github/license/onebrain-ai/onebrain?style=flat-square" alt="License" /></a>
8
+ <a href="https://github.com/onebrain-ai/onebrain/stargazers"><img src="https://img.shields.io/github/stars/onebrain-ai/onebrain?style=flat-square" alt="GitHub Stars" /></a>
9
+ <a href="https://github.com/onebrain-ai/onebrain/commits/main"><img src="https://img.shields.io/github/last-commit/onebrain-ai/onebrain?style=flat-square" alt="Last Commit" /></a>
10
10
  </p>
11
11
 
12
12
  <h1 align="center">OneBrain</h1>
package/dist/onebrain CHANGED
@@ -9364,17 +9364,16 @@ async function checkSettingsHooks(vaultRoot, config) {
9364
9364
  confirmedHooks.push("PostToolUse \u2713");
9365
9365
  }
9366
9366
  }
9367
- const precompactGroups = settings.hooks?.["PreCompact"] ?? [];
9368
- const hasStalePreCompact = precompactGroups.some((g) => g.hooks?.some((h) => (h.command ?? "").includes(PRECOMPACT_ONEBRAIN_SUBSTRING)));
9369
- if (hasStalePreCompact) {
9370
- warnings.push("stale PreCompact hook found");
9371
- }
9372
9367
  for (const event of Object.keys(settings.hooks ?? {})) {
9373
9368
  const groups = settings.hooks?.[event] ?? [];
9374
9369
  for (const g of groups) {
9375
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
+ }
9376
9375
  for (const sub of STALE_HOOK_SUBSTRINGS) {
9377
- if ((h.command ?? "").includes(sub)) {
9376
+ if (cmd.includes(sub)) {
9378
9377
  warnings.push(`stale bash hook reference: ${sub}`);
9379
9378
  }
9380
9379
  }
@@ -9408,7 +9407,7 @@ async function checkSettingsHooks(vaultRoot, config) {
9408
9407
  ...okDetails.length > 0 ? { details: okDetails } : {}
9409
9408
  };
9410
9409
  }
9411
- 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", PRECOMPACT_ONEBRAIN_SUBSTRING = "onebrain", REQUIRED_PERMISSION = "Bash(onebrain *)", STALE_HOOK_SUBSTRINGS;
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;
9412
9411
  var init_validator = __esm(() => {
9413
9412
  import_yaml2 = __toESM(require_dist(), 1);
9414
9413
  STANDARD_FOLDER_KEYS = [
@@ -9444,9 +9443,9 @@ var init_validator = __esm(() => {
9444
9443
  "logs"
9445
9444
  ];
9446
9445
  REQUIRED_HOOKS = [
9447
- { event: "Stop", cmdSubstring: "onebrain checkpoint stop" },
9448
- { event: "PostCompact", cmdSubstring: "onebrain checkpoint postcompact" }
9446
+ { event: "Stop", cmdSubstring: "onebrain checkpoint stop" }
9449
9447
  ];
9448
+ ALLOWED_HOOK_EVENTS = new Set(["Stop", "PostToolUse"]);
9450
9449
  STALE_HOOK_SUBSTRINGS = ["checkpoint-hook.sh", "session-init.sh"];
9451
9450
  });
9452
9451
 
@@ -9460,7 +9459,7 @@ var init_lib = __esm(() => {
9460
9459
  var require_package = __commonJS((exports, module) => {
9461
9460
  module.exports = {
9462
9461
  name: "@onebrain-ai/cli",
9463
- version: "2.1.5",
9462
+ version: "2.1.7",
9464
9463
  description: "CLI for OneBrain \u2014 personal AI OS for Obsidian with persistent memory, 24+ skills, and Claude Code integration",
9465
9464
  keywords: [
9466
9465
  "onebrain",
@@ -9475,12 +9474,12 @@ var require_package = __commonJS((exports, module) => {
9475
9474
  "productivity",
9476
9475
  "vault"
9477
9476
  ],
9478
- homepage: "https://github.com/kengio/onebrain",
9477
+ homepage: "https://github.com/onebrain-ai/onebrain",
9479
9478
  repository: {
9480
9479
  type: "git",
9481
- url: "git+https://github.com/kengio/onebrain.git"
9480
+ url: "git+https://github.com/onebrain-ai/onebrain.git"
9482
9481
  },
9483
- bugs: "https://github.com/kengio/onebrain/issues",
9482
+ bugs: "https://github.com/onebrain-ai/onebrain/issues",
9484
9483
  license: "MIT",
9485
9484
  type: "module",
9486
9485
  bin: {
@@ -9978,12 +9977,22 @@ function applyHooks(settings) {
9978
9977
  settings.hooks = {};
9979
9978
  const hooks = settings.hooks;
9980
9979
  const result = {};
9981
- for (const [event, staleCmd] of Object.entries(STALE_HOOK_COMMANDS)) {
9982
- if (!hooks[event])
9980
+ for (const event of Object.keys(hooks)) {
9981
+ if (ALLOWED_HOOK_EVENTS2.has(event))
9983
9982
  continue;
9984
- hooks[event] = hooks[event].filter((group) => !group.hooks?.some((entry) => entry.command === staleCmd));
9985
- if (hooks[event].length === 0)
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) {
9986
9992
  delete hooks[event];
9993
+ } else {
9994
+ hooks[event] = filtered;
9995
+ }
9987
9996
  }
9988
9997
  for (const event of HOOK_EVENTS) {
9989
9998
  const cmd = HOOK_COMMANDS[event];
@@ -10172,20 +10181,16 @@ async function registerHooksCommand(vaultDir) {
10172
10181
  process.exit(1);
10173
10182
  }
10174
10183
  }
10175
- var import_picocolors4, HOOK_COMMANDS, HOOK_EVENTS, STALE_HOOK_COMMANDS, PERMISSIONS_TO_ADD, ONEBRAIN_MARKER = "# onebrain", PATH_EXPORT = 'export PATH="$HOME/.bun/bin:$HOME/.npm-global/bin:$PATH"', QMD_CMD = "onebrain qmd-reindex", QMD_MATCHER = "Write|Edit";
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";
10176
10185
  var init_register_hooks = __esm(() => {
10177
10186
  init_dist2();
10178
10187
  init_lib();
10179
10188
  init_harness();
10180
10189
  import_picocolors4 = __toESM(require_picocolors(), 1);
10181
10190
  HOOK_COMMANDS = {
10182
- Stop: "onebrain checkpoint stop",
10183
- PostCompact: "onebrain checkpoint postcompact"
10184
- };
10185
- HOOK_EVENTS = ["Stop", "PostCompact"];
10186
- STALE_HOOK_COMMANDS = {
10187
- PreCompact: "onebrain checkpoint precompact"
10191
+ Stop: "onebrain checkpoint stop"
10188
10192
  };
10193
+ HOOK_EVENTS = ["Stop"];
10189
10194
  PERMISSIONS_TO_ADD = [
10190
10195
  "Read",
10191
10196
  "Write",
@@ -10202,6 +10207,7 @@ var init_register_hooks = __esm(() => {
10202
10207
  "WebFetch",
10203
10208
  "WebSearch"
10204
10209
  ];
10210
+ ALLOWED_HOOK_EVENTS2 = new Set(["Stop", "PostToolUse"]);
10205
10211
  });
10206
10212
 
10207
10213
  // src/commands/internal/vault-sync.ts
@@ -10227,7 +10233,7 @@ function resolveBranch(updateChannel) {
10227
10233
  return updateChannel === "stable" ? "main" : "next";
10228
10234
  }
10229
10235
  async function downloadTarball(branch, fetchFn) {
10230
- const url = `https://api.github.com/repos/kengio/onebrain/tarball/${branch}`;
10236
+ const url = `https://api.github.com/repos/onebrain-ai/onebrain/tarball/${branch}`;
10231
10237
  const response = await fetchFn(url);
10232
10238
  if (!response.ok) {
10233
10239
  const hints = {
@@ -10606,7 +10612,7 @@ async function runVaultSync(vaultRoot, opts = {}) {
10606
10612
  result.version = pj["version"];
10607
10613
  }
10608
10614
  } catch {}
10609
- stopSpinner(`kengio/onebrain@${branch} (v${result.version})`);
10615
+ stopSpinner(`onebrain-ai/onebrain@${branch} (v${result.version})`);
10610
10616
  startSpinner("\uD83D\uDCC2", "Syncing files");
10611
10617
  try {
10612
10618
  const { filesAdded, filesRemoved } = await syncPluginFiles(extractedDir, vaultRoot, unlinkFn);
@@ -10755,7 +10761,7 @@ var import_picocolors5 = __toESM(require_picocolors(), 1);
10755
10761
  var import_picocolors = __toESM(require_picocolors(), 1);
10756
10762
  function resolveBinaryVersion() {
10757
10763
  if (true)
10758
- return "2.1.5";
10764
+ return "2.1.7";
10759
10765
  try {
10760
10766
  const pkg = require_package();
10761
10767
  return pkg.version ?? "dev";
@@ -11944,7 +11950,7 @@ async function runInit(opts = {}) {
11944
11950
  }
11945
11951
  if (sp6) {
11946
11952
  await randDelay();
11947
- sp6.stop(hooksOk ? undefined : "not registered \u2014 run onebrain update", hooksOk ? ["Stop \u2713 PostCompact \u2713", "Bash(onebrain *) \u2713"] : undefined);
11953
+ sp6.stop(hooksOk ? undefined : "not registered \u2014 run onebrain update", hooksOk ? ["Stop \u2713", "Bash(onebrain *) \u2713"] : undefined);
11948
11954
  } else {
11949
11955
  writeLine(`hooks: ${hooksOk ? "ok" : "warning \u2014 hooks not registered; run onebrain update"}`);
11950
11956
  }
@@ -11971,24 +11977,24 @@ async function initCommand(opts = {}) {
11971
11977
  }
11972
11978
 
11973
11979
  // src/commands/internal/checkpoint.ts
11974
- import { readFileSync, readdirSync, writeFileSync } from "fs";
11980
+ import { readFileSync, readdirSync, renameSync, unlinkSync, writeFileSync } from "fs";
11975
11981
  import { tmpdir as osTmpdir } from "os";
11976
11982
  import { join as join7 } from "path";
11977
11983
  var SKIP_WINDOW = 60;
11978
11984
  var MIN_ACTIVITY = 2;
11979
- var PRECOMPACT_RECENCY = 300;
11980
11985
  var DEFAULT_MESSAGES_THRESHOLD = 15;
11981
11986
  var DEFAULT_MINUTES_THRESHOLD = 30;
11982
11987
  function stateFilePath(token, tmpDir) {
11983
11988
  return join7(tmpDir, `onebrain-${token}.state`);
11984
11989
  }
11990
+ var FRESH_STATE_DISK = "0:0:00";
11985
11991
  function readState(token, tmpDir = osTmpdir()) {
11986
11992
  const path = stateFilePath(token, tmpDir);
11987
11993
  try {
11988
11994
  const raw = readFileSync(path, "utf8").trim();
11989
11995
  const parts = raw.split(":");
11990
- if (parts.length < 3) {
11991
- throw new Error("v1 state format");
11996
+ if (parts.length !== 3) {
11997
+ throw new Error("state file must be exactly 3 fields");
11992
11998
  }
11993
11999
  const count = Number(parts[0]);
11994
12000
  const last_ts = Number(parts[1]);
@@ -11999,7 +12005,7 @@ function readState(token, tmpDir = osTmpdir()) {
11999
12005
  return { count, last_ts, last_stop_nn };
12000
12006
  } catch {
12001
12007
  try {
12002
- writeFileSync(stateFilePath(token, tmpDir), "0:0:00", "utf8");
12008
+ writeFileSync(stateFilePath(token, tmpDir), FRESH_STATE_DISK, "utf8");
12003
12009
  } catch (writeErr) {
12004
12010
  process.stderr.write(`checkpoint: failed to rewrite state file for token ${token}: ${writeErr}
12005
12011
  `);
@@ -12013,12 +12019,17 @@ function readState(token, tmpDir = osTmpdir()) {
12013
12019
  }
12014
12020
  function writeState(token, state, tmpDir = osTmpdir()) {
12015
12021
  const path = stateFilePath(token, tmpDir);
12022
+ const tmpPath = `${path}.tmp.${process.pid}`;
12016
12023
  const content = `${state.count}:${state.last_ts}:${state.last_stop_nn}`;
12017
12024
  try {
12018
- writeFileSync(path, content, "utf8");
12025
+ writeFileSync(tmpPath, content, "utf8");
12026
+ renameSync(tmpPath, path);
12019
12027
  } catch (err) {
12020
12028
  process.stderr.write(`checkpoint: failed to write state file ${path}: ${err}
12021
12029
  `);
12030
+ try {
12031
+ unlinkSync(tmpPath);
12032
+ } catch {}
12022
12033
  }
12023
12034
  }
12024
12035
  var DEFAULT_LOGS_FOLDER = "07-logs";
@@ -12098,11 +12109,11 @@ function handleStop(token, vaultRoot, now = Math.floor(Date.now() / 1000), tmpDi
12098
12109
  const elapsed = state.last_ts === 0 ? 0 : now - state.last_ts;
12099
12110
  const thresholdMet = state.count >= messagesThreshold || elapsed >= timeThreshold;
12100
12111
  if (!thresholdMet) {
12101
- writeState(token, { count: state.count, last_ts: state.last_ts, last_stop_nn: state.last_stop_nn }, tmpDir);
12112
+ writeState(token, { ...state }, tmpDir);
12102
12113
  return;
12103
12114
  }
12104
12115
  if (state.count < MIN_ACTIVITY) {
12105
- writeState(token, { count: state.count, last_ts: state.last_ts, last_stop_nn: state.last_stop_nn }, tmpDir);
12116
+ writeState(token, { ...state }, tmpDir);
12106
12117
  return;
12107
12118
  }
12108
12119
  const date = formatDate(now);
@@ -12112,27 +12123,12 @@ function handleStop(token, vaultRoot, now = Math.floor(Date.now() / 1000), tmpDi
12112
12123
  emitBlock(`${nextNn}${since}`);
12113
12124
  writeState(token, { count: 0, last_ts: now, last_stop_nn: nextNn }, tmpDir);
12114
12125
  }
12115
- function handlePostcompact(token, _vaultRoot, now = Math.floor(Date.now() / 1000), tmpDir = osTmpdir()) {
12116
- const state = readState(token, tmpDir);
12117
- if (state.last_ts > 0 && now - state.last_ts < PRECOMPACT_RECENCY) {
12118
- writeState(token, { count: 0, last_ts: state.last_ts, last_stop_nn: state.last_stop_nn }, tmpDir);
12119
- return;
12120
- }
12121
- emitBlock("auto-wrapup");
12122
- writeState(token, { count: 0, last_ts: now, last_stop_nn: state.last_stop_nn }, tmpDir);
12123
- }
12124
- function postcompactFallback(token, vaultRoot, now = Math.floor(Date.now() / 1000), tmpDir = osTmpdir()) {
12125
- handlePostcompact(token, vaultRoot, now, tmpDir);
12126
- }
12127
12126
  async function checkpointCommand(mode, token, vaultRoot) {
12128
12127
  try {
12129
12128
  switch (mode) {
12130
12129
  case "stop":
12131
12130
  handleStop(token, vaultRoot);
12132
12131
  break;
12133
- case "postcompact":
12134
- postcompactFallback(token, vaultRoot);
12135
- break;
12136
12132
  case "reset":
12137
12133
  handleReset(token);
12138
12134
  break;
@@ -12575,7 +12571,7 @@ init_vault_sync();
12575
12571
  // src/commands/update.ts
12576
12572
  var import_picocolors8 = __toESM(require_picocolors(), 1);
12577
12573
  init_cli_ui();
12578
- var GITHUB_REPO = "https://api.github.com/repos/kengio/onebrain";
12574
+ var GITHUB_REPO = "https://api.github.com/repos/onebrain-ai/onebrain";
12579
12575
  var GITHUB_RELEASES_URL = `${GITHUB_REPO}/releases/latest`;
12580
12576
  async function fetchLatestRelease(fetchFn) {
12581
12577
  const response = await fetchFn(GITHUB_RELEASES_URL, {
@@ -12797,8 +12793,8 @@ function patchUtf8(stream) {
12797
12793
  }
12798
12794
 
12799
12795
  // src/index.ts
12800
- var VERSION = "2.1.5";
12801
- var RELEASE_DATE = "2026-04-29";
12796
+ var VERSION = "2.1.7";
12797
+ var RELEASE_DATE = "2026-04-30";
12802
12798
  patchUtf8(process.stdout);
12803
12799
  patchUtf8(process.stderr);
12804
12800
  var VERSION_STRING = `OneBrain v${VERSION} \u2014 released ${RELEASE_DATE}`;
@@ -12850,9 +12846,9 @@ program2.command("session-init", { hidden: true }).description("Emit session tok
12850
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) => {
12851
12847
  await orphanScanCommand(logsFolder, sessionToken);
12852
12848
  });
12853
- program2.command("checkpoint", { hidden: true }).description("Handle checkpoint lifecycle (stop/postcompact/reset)").argument("<mode>", "stop | postcompact | reset").option("--vault-dir <path>", "vault root directory (default: auto-detect from cwd)").action(async (mode, opts) => {
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) => {
12854
12850
  const token = await resolveSessionToken();
12855
- const vaultRoot = opts.vaultDir ?? findVaultRoot(process.cwd());
12851
+ const vaultRoot = mode === "stop" ? opts.vaultDir ?? findVaultRoot(process.cwd()) : "";
12856
12852
  await checkpointCommand(mode, token, vaultRoot);
12857
12853
  });
12858
12854
  program2.command("qmd-reindex", { hidden: true }).description("Trigger qmd index rebuild").action(async () => {
@@ -116,7 +116,7 @@ Install Bun (https://bun.sh) to use the JS bundle fallback.
116
116
  return;
117
117
  }
118
118
  const destPath = join(__dirname2, "onebrain");
119
- const url = `https://github.com/kengio/onebrain/releases/download/v${version}/${binaryName}`;
119
+ const url = `https://github.com/onebrain-ai/onebrain/releases/download/v${version}/${binaryName}`;
120
120
  process.stdout.write(`[onebrain] Downloading ${binaryName} v${version}…
121
121
  `);
122
122
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onebrain-ai/cli",
3
- "version": "2.1.5",
3
+ "version": "2.1.7",
4
4
  "description": "CLI for OneBrain — personal AI OS for Obsidian with persistent memory, 24+ skills, and Claude Code integration",
5
5
  "keywords": [
6
6
  "onebrain",
@@ -15,12 +15,12 @@
15
15
  "productivity",
16
16
  "vault"
17
17
  ],
18
- "homepage": "https://github.com/kengio/onebrain",
18
+ "homepage": "https://github.com/onebrain-ai/onebrain",
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "git+https://github.com/kengio/onebrain.git"
21
+ "url": "git+https://github.com/onebrain-ai/onebrain.git"
22
22
  },
23
- "bugs": "https://github.com/kengio/onebrain/issues",
23
+ "bugs": "https://github.com/onebrain-ai/onebrain/issues",
24
24
  "license": "MIT",
25
25
  "type": "module",
26
26
  "bin": {