@onebrain-ai/cli 2.1.16 → 2.2.1
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 -5
- package/dist/onebrain +152 -42
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -198,7 +198,7 @@ OneBrain has automatic behaviors that run without you doing anything:
|
|
|
198
198
|
|
|
199
199
|
**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
200
|
|
|
201
|
-
> Auto Checkpoint
|
|
201
|
+
> 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.
|
|
202
202
|
|
|
203
203
|
---
|
|
204
204
|
|
|
@@ -214,7 +214,7 @@ OneBrain doesn't just store markdown. Every feature exists to make you and the a
|
|
|
214
214
|
| 📂 | **Vault-native Markdown** | Plain Markdown, no lock-in. Your data stays yours forever |
|
|
215
215
|
| 🔀 | **Multi-Harness OS** | Switch between Claude Code, Gemini CLI, Codex, Qwen, or BYO LLM — context never breaks. [See architecture ↑](#the-harness-os-architecture) |
|
|
216
216
|
| 🔌 | **Zero Config** | Clone, open in Obsidian, run `/onboarding`. Ready in under 2 minutes |
|
|
217
|
-
| 📓 | **Session Logs & Checkpoints** | Every conversation saved with summaries and action items. Auto-checkpoints fire every 15 messages or 30 min so nothing is lost mid-session *(
|
|
217
|
+
| 📓 | **Session Logs & Checkpoints** | Every conversation saved with summaries and action items. Auto-checkpoints fire every 15 messages or 30 min so nothing is lost mid-session *(supported on Claude Code and Gemini CLI)* |
|
|
218
218
|
| 💾 | **Auto Session Summary** | When you say "bye", the agent silently saves a complete session log — no `/wrapup` needed |
|
|
219
219
|
| 🔗 | **Knowledge Synthesis** | `/consolidate` turns inbox captures into permanent connected knowledge |
|
|
220
220
|
| 🔬 | **Confidence-scored Memory** | Every insight carries `[conf:high/medium/low]` + `[verified:YYYY-MM-DD]` — knowledge that grows more reliable with use |
|
|
@@ -276,7 +276,7 @@ Each harness reads OneBrain's instruction file automatically. Install it, run it
|
|
|
276
276
|
| **OpenAI Codex** | `npm install -g @openai/codex` | `codex` | `AGENTS.md` |
|
|
277
277
|
| **Qwen Code** | `npm install -g @qwen-code/qwen-code` | `qwen` | `AGENTS.md` |
|
|
278
278
|
|
|
279
|
-
> Auto-checkpoint and
|
|
279
|
+
> Auto-checkpoint and stop-hook coverage ship for Claude Code (`Stop` + optional `PostToolUse` qmd) and Gemini CLI (`AfterAgent` + optional `AfterTool` qmd) out of the box. Slash commands are namespaced on Gemini (`/onebrain:braindump`) to avoid collisions with built-ins; on Claude they invoke directly (`/braindump`). Other harnesses gain hook coverage as upstream support lands.
|
|
280
280
|
|
|
281
281
|
### 1. Install the OneBrain CLI
|
|
282
282
|
|
|
@@ -342,7 +342,7 @@ Same vault. Same skills. Same memory. The LLM swaps; OneBrain doesn't notice.
|
|
|
342
342
|
|
|
343
343
|
## 📋 24+ Commands
|
|
344
344
|
|
|
345
|
-
The full skill surface, alphabetized by workflow.
|
|
345
|
+
The full skill surface, alphabetized by workflow. **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
346
|
|
|
347
347
|
| Command | What it does |
|
|
348
348
|
|---------|-------------|
|
|
@@ -402,7 +402,8 @@ onebrain/
|
|
|
402
402
|
├── GEMINI.md Instructions for Gemini CLI
|
|
403
403
|
├── AGENTS.md Universal agent instructions
|
|
404
404
|
├── vault.yml Your vault configuration (created during onboarding)
|
|
405
|
-
|
|
405
|
+
├── .claude/plugins/ AI skills, hooks, and shared INSTRUCTIONS (read by Claude Code)
|
|
406
|
+
└── .gemini/ Gemini CLI project config — hooks + namespaced slash commands
|
|
406
407
|
```
|
|
407
408
|
|
|
408
409
|
The core workflow: capture everything to inbox → process with `/consolidate` → synthesize into knowledge or save as reference → archive what's done.
|
package/dist/onebrain
CHANGED
|
@@ -8909,7 +8909,7 @@ async function loadVaultConfig(vaultRoot) {
|
|
|
8909
8909
|
const file = Bun.file(vaultYmlPath);
|
|
8910
8910
|
const exists = await file.exists();
|
|
8911
8911
|
if (!exists) {
|
|
8912
|
-
throw new Error(
|
|
8912
|
+
throw new Error(`${VAULT_YML_NOT_FOUND_PREFIX}${vaultYmlPath}. Run onebrain init to set up this vault.`);
|
|
8913
8913
|
}
|
|
8914
8914
|
const text = await file.text();
|
|
8915
8915
|
const parsed = import_yaml.parse(text) ?? {};
|
|
@@ -8952,7 +8952,7 @@ async function loadVaultConfig(vaultRoot) {
|
|
|
8952
8952
|
}
|
|
8953
8953
|
return config;
|
|
8954
8954
|
}
|
|
8955
|
-
var import_yaml, DEFAULT_FOLDERS, DEFAULT_CHECKPOINT;
|
|
8955
|
+
var import_yaml, DEFAULT_FOLDERS, DEFAULT_CHECKPOINT, VAULT_YML_NOT_FOUND_PREFIX = "vault.yml not found at ";
|
|
8956
8956
|
var init_parser = __esm(() => {
|
|
8957
8957
|
import_yaml = __toESM(require_dist(), 1);
|
|
8958
8958
|
DEFAULT_FOLDERS = {
|
|
@@ -9545,7 +9545,9 @@ __export(exports_lib, {
|
|
|
9545
9545
|
checkOrphanCheckpoints: () => checkOrphanCheckpoints,
|
|
9546
9546
|
checkFolders: () => checkFolders,
|
|
9547
9547
|
checkClaudeSettings: () => checkClaudeSettings,
|
|
9548
|
-
atomicWrite: () => atomicWrite
|
|
9548
|
+
atomicWrite: () => atomicWrite,
|
|
9549
|
+
VAULT_YML_NOT_FOUND_PREFIX: () => VAULT_YML_NOT_FOUND_PREFIX,
|
|
9550
|
+
DEFAULT_CHECKPOINT: () => DEFAULT_CHECKPOINT
|
|
9549
9551
|
});
|
|
9550
9552
|
var init_lib = __esm(() => {
|
|
9551
9553
|
init_parser();
|
|
@@ -9558,7 +9560,7 @@ var init_lib = __esm(() => {
|
|
|
9558
9560
|
var require_package = __commonJS((exports, module) => {
|
|
9559
9561
|
module.exports = {
|
|
9560
9562
|
name: "@onebrain-ai/cli",
|
|
9561
|
-
version: "2.1
|
|
9563
|
+
version: "2.2.1",
|
|
9562
9564
|
description: "CLI for OneBrain \u2014 personal AI OS for Obsidian with persistent memory, 24+ skills, and Claude Code integration",
|
|
9563
9565
|
keywords: [
|
|
9564
9566
|
"onebrain",
|
|
@@ -10205,20 +10207,6 @@ function applyPermissions(settings) {
|
|
|
10205
10207
|
}
|
|
10206
10208
|
return added;
|
|
10207
10209
|
}
|
|
10208
|
-
async function registerGeminiHooks(vaultRoot) {
|
|
10209
|
-
const geminiSettingsPath = join4(vaultRoot, ".gemini", "settings.json");
|
|
10210
|
-
try {
|
|
10211
|
-
const text = await readFile(geminiSettingsPath, "utf8");
|
|
10212
|
-
const settings = JSON.parse(text);
|
|
10213
|
-
applyHooks(settings);
|
|
10214
|
-
await writeSettings(geminiSettingsPath, settings);
|
|
10215
|
-
} catch (err) {
|
|
10216
|
-
if (err.code !== "ENOENT") {
|
|
10217
|
-
process.stderr.write(`register-hooks: gemini warning: ${err instanceof Error ? err.message : String(err)}
|
|
10218
|
-
`);
|
|
10219
|
-
}
|
|
10220
|
-
}
|
|
10221
|
-
}
|
|
10222
10210
|
async function registerDirectPath() {
|
|
10223
10211
|
const home = homedir();
|
|
10224
10212
|
const candidates = [join4(home, ".zshrc"), join4(home, ".bashrc"), join4(home, ".profile")];
|
|
@@ -10316,9 +10304,6 @@ async function runRegisterHooks(opts = {}) {
|
|
|
10316
10304
|
if (!isTTY)
|
|
10317
10305
|
note("permissions ok");
|
|
10318
10306
|
}
|
|
10319
|
-
if (harness === "gemini") {
|
|
10320
|
-
await registerGeminiHooks(vaultRoot);
|
|
10321
|
-
}
|
|
10322
10307
|
if (harness === "direct") {
|
|
10323
10308
|
await registerDirectPath();
|
|
10324
10309
|
}
|
|
@@ -10495,6 +10480,43 @@ async function syncPluginFiles(extractedDir, vaultRoot, unlinkFn = unlink2) {
|
|
|
10495
10480
|
}
|
|
10496
10481
|
return { filesAdded, filesRemoved };
|
|
10497
10482
|
}
|
|
10483
|
+
async function syncGeminiConfig(extractedDir, vaultRoot, unlinkFn = unlink2) {
|
|
10484
|
+
const sourceGemini = join5(extractedDir, ".gemini");
|
|
10485
|
+
const destGemini = join5(vaultRoot, ".gemini");
|
|
10486
|
+
try {
|
|
10487
|
+
await stat4(sourceGemini);
|
|
10488
|
+
} catch {
|
|
10489
|
+
return { filesAdded: 0, filesRemoved: 0 };
|
|
10490
|
+
}
|
|
10491
|
+
await mkdirIdempotent(destGemini);
|
|
10492
|
+
const sourceFiles = await listFilesRecursive(sourceGemini);
|
|
10493
|
+
const sourceRelSet = new Set(sourceFiles.map((f2) => relative(sourceGemini, f2)));
|
|
10494
|
+
const destFiles = await listFilesRecursive(destGemini);
|
|
10495
|
+
const destRelSet = new Set(destFiles.map((f2) => relative(destGemini, f2)));
|
|
10496
|
+
const staleRels = [];
|
|
10497
|
+
for (const rel of destRelSet) {
|
|
10498
|
+
if (!sourceRelSet.has(rel))
|
|
10499
|
+
staleRels.push(rel);
|
|
10500
|
+
}
|
|
10501
|
+
let filesAdded = 0;
|
|
10502
|
+
for (const srcPath of sourceFiles) {
|
|
10503
|
+
const rel = relative(sourceGemini, srcPath);
|
|
10504
|
+
const destPath = join5(destGemini, rel);
|
|
10505
|
+
await mkdirIdempotent(dirname2(destPath));
|
|
10506
|
+
const content = await readFile2(srcPath);
|
|
10507
|
+
await writeFile3(destPath, content);
|
|
10508
|
+
filesAdded++;
|
|
10509
|
+
}
|
|
10510
|
+
let filesRemoved = 0;
|
|
10511
|
+
for (const rel of staleRels) {
|
|
10512
|
+
const destPath = join5(destGemini, rel);
|
|
10513
|
+
try {
|
|
10514
|
+
await unlinkFn(destPath);
|
|
10515
|
+
filesRemoved++;
|
|
10516
|
+
} catch {}
|
|
10517
|
+
}
|
|
10518
|
+
return { filesAdded, filesRemoved };
|
|
10519
|
+
}
|
|
10498
10520
|
async function copyRootDocs(extractedDir, vaultRoot) {
|
|
10499
10521
|
const docs = ["CONTRIBUTING.md", "CHANGELOG.md", "PLUGIN-CHANGELOG.md"];
|
|
10500
10522
|
for (const doc of docs) {
|
|
@@ -10821,9 +10843,10 @@ async function runVaultSync(vaultRoot, opts = {}) {
|
|
|
10821
10843
|
stopSpinner(`onebrain-ai/onebrain@${branch} (v${result.version})`);
|
|
10822
10844
|
startSpinner("\uD83D\uDCC2", "Syncing files");
|
|
10823
10845
|
try {
|
|
10824
|
-
const
|
|
10825
|
-
|
|
10826
|
-
result.
|
|
10846
|
+
const pluginResult = await syncPluginFiles(extractedDir, vaultRoot, unlinkFn);
|
|
10847
|
+
const geminiResult = await syncGeminiConfig(extractedDir, vaultRoot, unlinkFn);
|
|
10848
|
+
result.filesAdded = pluginResult.filesAdded + geminiResult.filesAdded;
|
|
10849
|
+
result.filesRemoved = pluginResult.filesRemoved + geminiResult.filesRemoved;
|
|
10827
10850
|
} catch (err) {
|
|
10828
10851
|
stopSpinner("plugin sync failed");
|
|
10829
10852
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -10968,7 +10991,7 @@ var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
|
10968
10991
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
10969
10992
|
function resolveBinaryVersion() {
|
|
10970
10993
|
if (true)
|
|
10971
|
-
return "2.1
|
|
10994
|
+
return "2.2.1";
|
|
10972
10995
|
try {
|
|
10973
10996
|
const pkg = require_package();
|
|
10974
10997
|
return pkg.version ?? "dev";
|
|
@@ -11460,7 +11483,8 @@ async function runDoctor(opts = {}) {
|
|
|
11460
11483
|
agent: "05-agent",
|
|
11461
11484
|
archive: "06-archive",
|
|
11462
11485
|
logs: "07-logs"
|
|
11463
|
-
}
|
|
11486
|
+
},
|
|
11487
|
+
checkpoint: { ...DEFAULT_CHECKPOINT }
|
|
11464
11488
|
};
|
|
11465
11489
|
const sp1 = createStep("\uD83D\uDCCB", "vault.yml");
|
|
11466
11490
|
const vaultYmlResult = await checkVaultYmlFn(vaultDir);
|
|
@@ -12582,9 +12606,12 @@ async function migrateCommand(migrationName, cutoffDate, vaultDir) {
|
|
|
12582
12606
|
}
|
|
12583
12607
|
|
|
12584
12608
|
// src/commands/internal/orphan-scan.ts
|
|
12609
|
+
init_parser();
|
|
12585
12610
|
var import_yaml6 = __toESM(require_dist(), 1);
|
|
12586
|
-
import { readFile as readFile5, readdir as readdir4 } from "fs/promises";
|
|
12611
|
+
import { readFile as readFile5, readdir as readdir4, stat as stat6 } from "fs/promises";
|
|
12587
12612
|
import { join as join9 } from "path";
|
|
12613
|
+
var MIN_GUARD_MINUTES = 60;
|
|
12614
|
+
var DEFAULT_ACTIVE_SESSION_GUARD_MS = 60 * 60 * 1000;
|
|
12588
12615
|
function parseFrontmatter(rawText) {
|
|
12589
12616
|
const text = rawText.replace(/\r\n/g, `
|
|
12590
12617
|
`);
|
|
@@ -12618,6 +12645,61 @@ async function listMdFiles2(dir) {
|
|
|
12618
12645
|
return [];
|
|
12619
12646
|
}
|
|
12620
12647
|
}
|
|
12648
|
+
async function getActiveSessionGuardMs(vaultRoot) {
|
|
12649
|
+
try {
|
|
12650
|
+
const config = await loadVaultConfig(vaultRoot);
|
|
12651
|
+
const cpMinutes = config.checkpoint.minutes;
|
|
12652
|
+
if (typeof cpMinutes !== "number" || !Number.isFinite(cpMinutes) || cpMinutes <= 0) {
|
|
12653
|
+
return DEFAULT_ACTIVE_SESSION_GUARD_MS;
|
|
12654
|
+
}
|
|
12655
|
+
const minutes = Math.max(MIN_GUARD_MINUTES, 2 * cpMinutes);
|
|
12656
|
+
return minutes * 60 * 1000;
|
|
12657
|
+
} catch (err) {
|
|
12658
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12659
|
+
const isExpectedAbsence = msg.startsWith(VAULT_YML_NOT_FOUND_PREFIX);
|
|
12660
|
+
if (!isExpectedAbsence) {
|
|
12661
|
+
try {
|
|
12662
|
+
process.stderr.write(`onebrain orphan-scan: vault.yml unreadable, using ${MIN_GUARD_MINUTES}-min Active-Session Guard default (${msg})
|
|
12663
|
+
`);
|
|
12664
|
+
} catch {}
|
|
12665
|
+
}
|
|
12666
|
+
return DEFAULT_ACTIVE_SESSION_GUARD_MS;
|
|
12667
|
+
}
|
|
12668
|
+
}
|
|
12669
|
+
async function getMtimeMs(path) {
|
|
12670
|
+
try {
|
|
12671
|
+
const s = await stat6(path);
|
|
12672
|
+
if (typeof s.mtimeMs !== "number" || !Number.isFinite(s.mtimeMs))
|
|
12673
|
+
return null;
|
|
12674
|
+
return s.mtimeMs;
|
|
12675
|
+
} catch {
|
|
12676
|
+
return null;
|
|
12677
|
+
}
|
|
12678
|
+
}
|
|
12679
|
+
async function getNewestMtimeMs(filePaths) {
|
|
12680
|
+
if (filePaths.length === 0)
|
|
12681
|
+
return null;
|
|
12682
|
+
let newest = Number.NEGATIVE_INFINITY;
|
|
12683
|
+
for (const p2 of filePaths) {
|
|
12684
|
+
const m3 = await getMtimeMs(p2);
|
|
12685
|
+
if (m3 === null)
|
|
12686
|
+
return null;
|
|
12687
|
+
if (m3 > newest)
|
|
12688
|
+
newest = m3;
|
|
12689
|
+
}
|
|
12690
|
+
return Number.isFinite(newest) ? newest : null;
|
|
12691
|
+
}
|
|
12692
|
+
async function isGroupActiveOrAmbiguous(filePaths, nowMs, guardMs) {
|
|
12693
|
+
if (!Number.isFinite(guardMs) || guardMs <= 0)
|
|
12694
|
+
return true;
|
|
12695
|
+
const newest = await getNewestMtimeMs(filePaths);
|
|
12696
|
+
if (newest === null)
|
|
12697
|
+
return true;
|
|
12698
|
+
const ageMs = nowMs - newest;
|
|
12699
|
+
if (ageMs < 0)
|
|
12700
|
+
return true;
|
|
12701
|
+
return ageMs < guardMs;
|
|
12702
|
+
}
|
|
12621
12703
|
async function hasManualSessionLog(monthDir, date) {
|
|
12622
12704
|
const files = await listMdFiles2(monthDir);
|
|
12623
12705
|
const sessionLogs = files.filter((f2) => f2.startsWith(date) && f2.includes("-session-") && f2.endsWith(".md"));
|
|
@@ -12632,10 +12714,19 @@ async function hasManualSessionLog(monthDir, date) {
|
|
|
12632
12714
|
}
|
|
12633
12715
|
return false;
|
|
12634
12716
|
}
|
|
12635
|
-
async function
|
|
12717
|
+
async function collectCandidateGroupsForMonth(monthDir, currentToken, today) {
|
|
12718
|
+
const groups = new Map;
|
|
12636
12719
|
const files = await listMdFiles2(monthDir);
|
|
12637
12720
|
const checkpoints = files.filter((f2) => f2.includes("-checkpoint-") && f2.endsWith(".md"));
|
|
12638
|
-
|
|
12721
|
+
const manualLogCache = new Map;
|
|
12722
|
+
async function dateHasManualLog(date) {
|
|
12723
|
+
const cached = manualLogCache.get(date);
|
|
12724
|
+
if (cached !== undefined)
|
|
12725
|
+
return cached;
|
|
12726
|
+
const result = await hasManualSessionLog(monthDir, date);
|
|
12727
|
+
manualLogCache.set(date, result);
|
|
12728
|
+
return result;
|
|
12729
|
+
}
|
|
12639
12730
|
for (const fname of checkpoints) {
|
|
12640
12731
|
const dateMatch = fname.match(/^(\d{4}-\d{2}-\d{2})-/);
|
|
12641
12732
|
if (!dateMatch)
|
|
@@ -12652,32 +12743,51 @@ async function scanMonthDir(monthDir, currentToken, today, seenTokens) {
|
|
|
12652
12743
|
continue;
|
|
12653
12744
|
if (ftoken === currentToken)
|
|
12654
12745
|
continue;
|
|
12655
|
-
if (
|
|
12656
|
-
continue;
|
|
12657
|
-
if (await hasManualSessionLog(monthDir, fdate))
|
|
12746
|
+
if (await dateHasManualLog(fdate))
|
|
12658
12747
|
continue;
|
|
12659
|
-
|
|
12660
|
-
|
|
12748
|
+
const fpath = join9(monthDir, fname);
|
|
12749
|
+
const existing = groups.get(ftoken);
|
|
12750
|
+
if (existing)
|
|
12751
|
+
existing.push(fpath);
|
|
12752
|
+
else
|
|
12753
|
+
groups.set(ftoken, [fpath]);
|
|
12661
12754
|
}
|
|
12662
|
-
return
|
|
12755
|
+
return groups;
|
|
12663
12756
|
}
|
|
12664
|
-
async function runOrphanScan(logsFolder, sessionToken, now) {
|
|
12757
|
+
async function runOrphanScan(logsFolder, sessionToken, now, vaultRoot) {
|
|
12758
|
+
if (!vaultRoot) {
|
|
12759
|
+
throw new Error("runOrphanScan: vaultRoot is required and must be a non-empty path");
|
|
12760
|
+
}
|
|
12665
12761
|
const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
|
|
12666
12762
|
const { thisYear, thisMonth, prevYear, prevMonth } = getMonthParts(now);
|
|
12667
12763
|
const monthDirs = [
|
|
12668
12764
|
{ year: thisYear, month: thisMonth },
|
|
12669
12765
|
{ year: prevYear, month: prevMonth }
|
|
12670
12766
|
];
|
|
12671
|
-
const
|
|
12672
|
-
let totalOrphans = 0;
|
|
12767
|
+
const allGroups = new Map;
|
|
12673
12768
|
for (const { year, month } of monthDirs) {
|
|
12674
12769
|
const monthDir = join9(logsFolder, year, month);
|
|
12675
|
-
|
|
12770
|
+
const monthGroups = await collectCandidateGroupsForMonth(monthDir, sessionToken, today);
|
|
12771
|
+
for (const [token, files] of monthGroups) {
|
|
12772
|
+
const existing = allGroups.get(token);
|
|
12773
|
+
if (existing)
|
|
12774
|
+
existing.push(...files);
|
|
12775
|
+
else
|
|
12776
|
+
allGroups.set(token, [...files]);
|
|
12777
|
+
}
|
|
12778
|
+
}
|
|
12779
|
+
const guardMs = await getActiveSessionGuardMs(vaultRoot);
|
|
12780
|
+
const nowMs = now.getTime();
|
|
12781
|
+
let totalOrphans = 0;
|
|
12782
|
+
for (const [, files] of allGroups) {
|
|
12783
|
+
if (await isGroupActiveOrAmbiguous(files, nowMs, guardMs))
|
|
12784
|
+
continue;
|
|
12785
|
+
totalOrphans++;
|
|
12676
12786
|
}
|
|
12677
12787
|
return { orphan_count: totalOrphans };
|
|
12678
12788
|
}
|
|
12679
12789
|
async function orphanScanCommand(logsFolder, sessionToken) {
|
|
12680
|
-
const result = await runOrphanScan(logsFolder, sessionToken, new Date);
|
|
12790
|
+
const result = await runOrphanScan(logsFolder, sessionToken, new Date, process.cwd());
|
|
12681
12791
|
process.stdout.write(`${JSON.stringify(result)}
|
|
12682
12792
|
`);
|
|
12683
12793
|
}
|
|
@@ -13199,8 +13309,8 @@ function patchUtf8(stream) {
|
|
|
13199
13309
|
}
|
|
13200
13310
|
|
|
13201
13311
|
// src/index.ts
|
|
13202
|
-
var VERSION = "2.1
|
|
13203
|
-
var RELEASE_DATE = "2026-05-
|
|
13312
|
+
var VERSION = "2.2.1";
|
|
13313
|
+
var RELEASE_DATE = "2026-05-07";
|
|
13204
13314
|
patchUtf8(process.stdout);
|
|
13205
13315
|
patchUtf8(process.stderr);
|
|
13206
13316
|
var VERSION_STRING = `OneBrain v${VERSION} \u2014 released ${RELEASE_DATE}`;
|