@onebrain-ai/cli 2.3.1 → 2.3.2

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.
Files changed (3) hide show
  1. package/README.md +24 -8
  2. package/dist/onebrain +39 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -84,7 +84,7 @@ A great harness already knows how to talk to an LLM, edit files, and run shell c
84
84
  | | What OneBrain adds | Why it matters |
85
85
  |---|---|---|
86
86
  | 🧠 | **Memory** — Identity, preferences, decisions, project state — promoted across four tiers as it earns trust | The harness alone starts every session from zero. OneBrain doesn't. |
87
- | ⚡ | **Skills** — 29+ vault-aware verbs (`/braindump`, `/research`, `/distill`, `/learn`, `/wrapup`, …) | Pre-built workflows the harness would otherwise need you to script every time. |
87
+ | ⚡ | **Skills** — 31+ vault-aware verbs (`/braindump`, `/research`, `/distill`, `/learn`, `/wrapup`, …) | Pre-built workflows the harness would otherwise need you to script every time. |
88
88
  | 🎯 | **Calibration** — Every correction, every preference, every learned habit tunes the agent to *you* | The longer you use it, the sharper it gets — your vault is the training data. |
89
89
  | 🔀 | **Continuity** — Context lives in the vault, not the harness | Switch from Claude Code to Gemini CLI to Codex. Same memory. Same skills. Same agent. |
90
90
 
@@ -196,6 +196,8 @@ OneBrain has automatic behaviors that run without you doing anything:
196
196
 
197
197
  **`/wrapup` is manual only.** Run it yourself when you want a visible, full session summary with output shown.
198
198
 
199
+ **Pausing long work across sessions.** For multi-day tasks that don't fit one session, run `/pause` to save a snapshot, then `/resume` in a future session to pick up seamlessly. Pause snapshots accumulate per-thread in `07-logs/pause/`; the next `/wrapup` consolidates them into one session log. This fills the gap between auto-checkpoint (involuntary) and `/wrapup` (terminal).
200
+
199
201
  **The practical result:** Just say "bye" and everything is saved. If the session ends unexpectedly, you lose at most 15 messages — the last checkpoint recovers the rest.
200
202
 
201
203
  > Auto Checkpoint runs on Claude Code (`Stop` hook) and Gemini CLI (`AfterAgent` hook), and uses the `onebrain` CLI binary. Install with `npm install -g @onebrain-ai/cli`. Auto Session Summary works with any agent that follows INSTRUCTIONS.md.
@@ -210,7 +212,7 @@ OneBrain doesn't just store markdown. Every feature exists to make you and the a
210
212
  |---|---|---|
211
213
  | 🧠 | **Persistent Memory** | Remembers your name, goals, preferences, and decisions across every session |
212
214
  | 🖥️ | **Personal AI OS** | Full local stack: Claude Code + Obsidian + tmux + Telegram — no cloud infra needed |
213
- | ⚡ | **29+ Skills** | Braindump, research, consolidate, bookmark, import files, daily briefing, and more |
215
+ | ⚡ | **31+ Skills** | Braindump, research, consolidate, bookmark, import files, daily briefing, and more |
214
216
  | 📂 | **Vault-native Markdown** | Plain Markdown, no lock-in. Your data stays yours forever |
215
217
  | 🔀 | **Multi-Harness OS** | Switch between Claude Code, Gemini CLI, Codex, Qwen, or BYO LLM — context never breaks. [See architecture ↑](#the-harness-os-architecture) |
216
218
  | 🔌 | **Zero Config** | Clone, open in Obsidian, run `/onboarding`. Ready in under 2 minutes |
@@ -340,7 +342,9 @@ Same vault. Same skills. Same memory. The LLM swaps; OneBrain doesn't notice.
340
342
 
341
343
  <a id="commands"></a>
342
344
 
343
- ## 📋 29+ Commands
345
+ <!-- NEW-BADGE-CLEANUP: remove the green NEW shields.io badges from /search, /pause, /resume, /schedule-* on or after 2026-05-19 -->
346
+
347
+ ## 📋 31+ Commands
344
348
 
345
349
  Skills are organized by workflow phase. **Gemini CLI users:** prepend the `onebrain:` namespace, e.g. `/onebrain:braindump` instead of `/braindump` (avoids collisions with Gemini built-in commands like `/help` and `/tasks`).
346
350
 
@@ -373,7 +377,7 @@ Skills are organized by workflow phase. **Gemini CLI users:** prepend the `onebr
373
377
 
374
378
  | Command | What it does |
375
379
  |---------|-------------|
376
- | `/search` | General vault retrieval — answers what + why questions across MEMORY, sessions, plans, decisions logs, notes |
380
+ | `/search` ![NEW](https://img.shields.io/badge/NEW-success?style=flat-square) | General vault retrieval — answers what + why questions across MEMORY, sessions, plans, decisions logs, notes |
377
381
  | `/tasks` | Live task dashboard in Obsidian — creates/updates `TASKS.md` with always-current query sections |
378
382
  | `/moc` | Vault portal in Obsidian — creates/updates `MOC.md` with projects, areas, knowledge, tasks, and pinned links |
379
383
  | `/memory-review` | Interactive review of memory files — keep, update, deprecate, or delete entries |
@@ -389,10 +393,12 @@ Skills are organized by workflow phase. **Gemini CLI users:** prepend the `onebr
389
393
  | `/qmd` | Set up fast vault search index — enables semantic search across all notes |
390
394
  | `/help` | List all available commands with descriptions |
391
395
  | `/wrapup` | Wrap up session — merges any auto-checkpoints and saves full summary to session log |
392
- | `/schedule-add` | Interactive wizard for adding a recurring scheduled skill |
393
- | `/schedule-once` | One-shot wizard: schedule a skill to run once at a specific datetime |
394
- | `/schedule-list` | Show all scheduled entries |
395
- | `/schedule-remove` | Remove a scheduled entry |
396
+ | `/pause` ![NEW](https://img.shields.io/badge/NEW-success?style=flat-square) | Save a snapshot of long-running work mid-flight so a future session can `/resume` (does NOT end the session or clear context) |
397
+ | `/resume` ![NEW](https://img.shields.io/badge/NEW-success?style=flat-square) | Load the latest snapshot of an active pause thread and pick up seamlessly in a fresh session |
398
+ | `/schedule-add` ![NEW](https://img.shields.io/badge/NEW-success?style=flat-square) | Interactive wizard for adding a recurring scheduled skill |
399
+ | `/schedule-once` ![NEW](https://img.shields.io/badge/NEW-success?style=flat-square) | One-shot wizard: schedule a skill to run once at a specific datetime |
400
+ | `/schedule-list` ![NEW](https://img.shields.io/badge/NEW-success?style=flat-square) | Show all scheduled entries |
401
+ | `/schedule-remove` ![NEW](https://img.shields.io/badge/NEW-success?style=flat-square) | Remove a scheduled entry |
396
402
 
397
403
  <details>
398
404
  <summary><strong>📁 Vault Structure</strong></summary>
@@ -544,6 +550,16 @@ schedule:
544
550
 
545
551
  This matches the same shape Claude Code uses for `hooks` in `settings.json` — direct binary invocation with positional argv. No wrapper skill needed.
546
552
 
553
+ ### Quick start — preset bundles
554
+
555
+ Don't want to hand-craft cron entries? OneBrain ships three preset tiers. New vaults are prompted during `/onboarding`; existing vaults can trigger the selector by running `/schedule-add` when the `schedule:` block is empty.
556
+
557
+ - **Minimal** — `/daily` briefing only
558
+ - **Essentials (default)** — `/daily` + `/weekly` Friday + `/recap` Sunday
559
+ - **Maintenance Plus** — Essentials + `/doctor` monthly + `/tasks` daily + `onebrain qmd-reindex` Sunday (mixes skill + command modes)
560
+
561
+ Canonical tier definitions live at `.claude/plugins/onebrain/skills/_shared/schedule-presets.md`.
562
+
547
563
  CLI flags:
548
564
 
549
565
  | Flag | Purpose |
package/dist/onebrain CHANGED
@@ -9366,9 +9366,33 @@ async function checkClaudeSettings(vaultRoot) {
9366
9366
  }
9367
9367
  return { check: "claude-settings", status: "ok", message: "ok" };
9368
9368
  }
9369
- function hookPresent(settings, event, cmdSubstring) {
9369
+ function effectiveCommand(h) {
9370
+ const parts = [];
9371
+ if (typeof h.command === "string" && h.command.length > 0)
9372
+ parts.push(h.command);
9373
+ if (Array.isArray(h.args)) {
9374
+ for (const a of h.args)
9375
+ if (typeof a === "string" && a.length > 0)
9376
+ parts.push(a);
9377
+ }
9378
+ return parts.join(" ");
9379
+ }
9380
+ function detectHookForm(settings, event, cmdSubstring) {
9381
+ let sawLegacy = false;
9370
9382
  const groups = settings.hooks?.[event] ?? [];
9371
- return groups.some((g) => g.hooks?.some((h) => (h.command ?? "").includes(cmdSubstring)));
9383
+ for (const g of groups) {
9384
+ for (const h of g.hooks ?? []) {
9385
+ if (!effectiveCommand(h).includes(cmdSubstring))
9386
+ continue;
9387
+ const isCanonical = h.command === CANONICAL_HOOK_COMMAND && (h.args?.length ?? 0) > 0;
9388
+ if (isCanonical)
9389
+ return "exec";
9390
+ sawLegacy = true;
9391
+ }
9392
+ }
9393
+ if (sawLegacy)
9394
+ return "legacy";
9395
+ return "absent";
9372
9396
  }
9373
9397
  async function checkSettingsHooks(vaultRoot, config) {
9374
9398
  const settingsPath = join2(vaultRoot, ".claude", "settings.json");
@@ -9396,15 +9420,21 @@ async function checkSettingsHooks(vaultRoot, config) {
9396
9420
  const confirmedHooks = [];
9397
9421
  let permissionOk = false;
9398
9422
  for (const { event, cmdSubstring } of REQUIRED_HOOKS) {
9399
- if (!hookPresent(settings, event, cmdSubstring)) {
9423
+ const form = detectHookForm(settings, event, cmdSubstring);
9424
+ if (form === "absent") {
9400
9425
  warnings.push(`${event} hook missing`);
9426
+ } else if (form === "legacy") {
9427
+ warnings.push(`${event} hook in legacy shell form \u2014 --fix will migrate to exec form`);
9401
9428
  } else {
9402
9429
  confirmedHooks.push(`${event} \u2713`);
9403
9430
  }
9404
9431
  }
9405
9432
  if (config.qmd_collection) {
9406
- if (!hookPresent(settings, "PostToolUse", QMD_HOOK_SUBSTRING)) {
9433
+ const form = detectHookForm(settings, "PostToolUse", QMD_HOOK_SUBSTRING);
9434
+ if (form === "absent") {
9407
9435
  warnings.push("PostToolUse (qmd) hook missing");
9436
+ } else if (form === "legacy") {
9437
+ warnings.push("PostToolUse (qmd) hook in legacy shell form \u2014 --fix will migrate to exec form");
9408
9438
  } else {
9409
9439
  confirmedHooks.push("PostToolUse \u2713");
9410
9440
  }
@@ -9413,7 +9443,7 @@ async function checkSettingsHooks(vaultRoot, config) {
9413
9443
  const groups = settings.hooks?.[event] ?? [];
9414
9444
  for (const g of groups) {
9415
9445
  for (const h of g.hooks ?? []) {
9416
- const cmd = h.command ?? "";
9446
+ const cmd = effectiveCommand(h);
9417
9447
  if (!ALLOWED_HOOK_EVENTS.has(event) && cmd.includes(ONEBRAIN_COMMAND_SUBSTRING)) {
9418
9448
  warnings.push(`stale ${event} hook found (onebrain CLI only registers Stop + PostToolUse)`);
9419
9449
  }
@@ -9452,7 +9482,7 @@ async function checkSettingsHooks(vaultRoot, config) {
9452
9482
  ...okDetails.length > 0 ? { details: okDetails } : {}
9453
9483
  };
9454
9484
  }
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;
9485
+ 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, CANONICAL_HOOK_COMMAND = "onebrain";
9456
9486
  var init_validator = __esm(() => {
9457
9487
  import_yaml2 = __toESM(require_dist(), 1);
9458
9488
  STANDARD_FOLDER_KEYS = [
@@ -9560,7 +9590,7 @@ var init_lib = __esm(() => {
9560
9590
  var require_package = __commonJS((exports, module) => {
9561
9591
  module.exports = {
9562
9592
  name: "@onebrain-ai/cli",
9563
- version: "2.3.1",
9593
+ version: "2.3.2",
9564
9594
  description: "CLI for OneBrain \u2014 personal AI OS for Obsidian with persistent memory, 24+ skills, and Claude Code integration",
9565
9595
  keywords: [
9566
9596
  "onebrain",
@@ -11048,7 +11078,7 @@ var import_picocolors5 = __toESM(require_picocolors(), 1);
11048
11078
  var import_picocolors = __toESM(require_picocolors(), 1);
11049
11079
  function resolveBinaryVersion() {
11050
11080
  if (true)
11051
- return "2.3.1";
11081
+ return "2.3.2";
11052
11082
  try {
11053
11083
  const pkg = require_package();
11054
11084
  return pkg.version ?? "dev";
@@ -13728,7 +13758,7 @@ function patchUtf8(stream) {
13728
13758
  }
13729
13759
 
13730
13760
  // src/index.ts
13731
- var VERSION = "2.3.1";
13761
+ var VERSION = "2.3.2";
13732
13762
  var RELEASE_DATE = "2026-05-12";
13733
13763
  patchUtf8(process.stdout);
13734
13764
  patchUtf8(process.stderr);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onebrain-ai/cli",
3
- "version": "2.3.1",
3
+ "version": "2.3.2",
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",