@ziamana/bruine 0.1.4 → 0.1.5

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
@@ -12,7 +12,7 @@
12
12
  [![License: MIT](https://img.shields.io/badge/license-MIT-b4a7ff)](LICENSE)
13
13
  [![Node 22+](https://img.shields.io/badge/node-22%2B-7dcfff)](https://nodejs.org)
14
14
  ![Linux tested · macOS and Windows in progress](https://img.shields.io/badge/Linux-tested-8fe3a3) ![macOS · Windows](https://img.shields.io/badge/macOS%20%C2%B7%20Windows-in%20progress-f5c97a)
15
- [![Changelog](https://img.shields.io/badge/version-0.1.4-ff9ed2)](CHANGELOG.md)
15
+ [![Changelog](https://img.shields.io/badge/version-0.1.5-ff9ed2)](CHANGELOG.md)
16
16
 
17
17
  <a href="docs/media/bruine-film.mp4"><img src="docs/media/hero.webp" alt="The bruine film: the word bruine becomes the logo in the rain, then the effort climbs from low to max and the rain turns into a storm" width="100%"></a>
18
18
 
package/dist/bin.js CHANGED
@@ -1559,7 +1559,7 @@ var init_theme = __esm({
1559
1559
 
1560
1560
  // src/update.ts
1561
1561
  import { spawn } from "child_process";
1562
- import { realpathSync } from "fs";
1562
+ import { realpathSync as realpathSync2 } from "fs";
1563
1563
  import { mkdir as mkdir4, readFile as readFile5, rename as rename4, writeFile as writeFile4 } from "fs/promises";
1564
1564
  import path5 from "path";
1565
1565
  function updateCachePath(dshHome, pathMod = path5) {
@@ -4783,7 +4783,7 @@ var init_approve = __esm({
4783
4783
  // src/bin.ts
4784
4784
  init_compat();
4785
4785
  import { spawn as spawn2, spawnSync as spawnSync3 } from "child_process";
4786
- import { existsSync as existsSync8, readFileSync as readFileSync7, realpathSync as realpathSync2 } from "fs";
4786
+ import { existsSync as existsSync8, readFileSync as readFileSync7, realpathSync as realpathSync3 } from "fs";
4787
4787
  import { createInterface } from "readline";
4788
4788
  import os from "os";
4789
4789
  import { dirname as dirname5, join as join8, resolve as resolve2 } from "path";
@@ -4855,7 +4855,7 @@ function flagMode(argv) {
4855
4855
  // src/profile.ts
4856
4856
  import { createRequire as createRequire2 } from "module";
4857
4857
  import { mkdir, readFile, rename, rm, stat, writeFile } from "fs/promises";
4858
- import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, rmSync, symlinkSync } from "fs";
4858
+ import { existsSync as existsSync3, lstatSync, mkdirSync, readFileSync as readFileSync2, realpathSync, rmSync, symlinkSync } from "fs";
4859
4859
  import path3 from "path";
4860
4860
  import { parse as parseYaml } from "yaml";
4861
4861
  var require3 = createRequire2(import.meta.url);
@@ -5003,6 +5003,19 @@ function linkProfileBundles(profileDir, own, dshBaseDir) {
5003
5003
  return false;
5004
5004
  }
5005
5005
  }
5006
+ function bundleIsCurrent(profileDir, name, own) {
5007
+ const at = path3.join(profileDir, "node_modules", name);
5008
+ const marker = path3.join(at, "package.json");
5009
+ if (!existsSync3(marker)) return false;
5010
+ if (own.root === void 0) return true;
5011
+ try {
5012
+ if (realpathSync(at) === realpathSync(own.root)) return true;
5013
+ if (lstatSync(at).isSymbolicLink()) return false;
5014
+ return JSON.parse(readFileSync2(marker, "utf8")).version === own.version;
5015
+ } catch {
5016
+ return false;
5017
+ }
5018
+ }
5006
5019
  function resolveDshBaseDir() {
5007
5020
  try {
5008
5021
  const dshRequire = createRequire2(require3.resolve("@deepseek-ai/dsh/package.json"));
@@ -5136,9 +5149,8 @@ function selfPackageRoot() {
5136
5149
  }
5137
5150
  }
5138
5151
  function ensureBundleInstalled(profileDir, dshEntry, env, headless = false) {
5139
- const marker = join8(profileDir, "node_modules", pkg2.name, "package.json");
5140
- if (existsSync8(marker)) return;
5141
5152
  const root = selfPackageRoot();
5153
+ if (bundleIsCurrent(profileDir, pkg2.name, { root, version: pkg2.version })) return;
5142
5154
  if (!headless) console.log("Setting up bruine (one time)\u2026");
5143
5155
  const dshBase = resolveDshBaseDir();
5144
5156
  if (root !== void 0 && dshBase !== void 0 && linkProfileBundles(profileDir, { name: pkg2.name, root }, dshBase)) {
@@ -5189,7 +5201,7 @@ async function runUpdate() {
5189
5201
  const entry = process.argv[1] ?? fileURLToPath2(import.meta.url);
5190
5202
  let real = entry;
5191
5203
  try {
5192
- real = realpathSync2(entry);
5204
+ real = realpathSync3(entry);
5193
5205
  } catch {
5194
5206
  }
5195
5207
  const cmd = updateCommand(detectInstallKind(real));
@@ -3265,6 +3265,21 @@ function attachTui(ctx, agent, ui, service, getAgent) {
3265
3265
  const reading = silence?.reading(id === void 0 ? void 0 : String(id));
3266
3266
  return reading === void 0 ? void 0 : { quietMs: Date.now() - reading.quietSince, budgetMs: reading.budget };
3267
3267
  });
3268
+ let backgroundTaskCount = 0;
3269
+ const jobs = ctx.get("jobs");
3270
+ const refreshBackgroundTasks = () => {
3271
+ let count = 0;
3272
+ try {
3273
+ count = (jobs?.list(liveAgent()) ?? []).filter((job) => job.kind !== "subagent" && (job.status === "running" || job.status === "stopping")).length;
3274
+ } catch {
3275
+ }
3276
+ if (count === backgroundTaskCount) return;
3277
+ backgroundTaskCount = count;
3278
+ ui.footer.set({ backgroundTasks: count });
3279
+ ui.requestRender();
3280
+ };
3281
+ const offJobsChanged = jobs?.onJobsChanged?.(refreshBackgroundTasks);
3282
+ refreshBackgroundTasks();
3268
3283
  let subagentCount = 0;
3269
3284
  const refreshSubagents = () => {
3270
3285
  const registry = ctx.get("agents");
@@ -3424,6 +3439,7 @@ function attachTui(ctx, agent, ui, service, getAgent) {
3424
3439
  }
3425
3440
  case "turn/start":
3426
3441
  refreshSubagents();
3442
+ refreshBackgroundTasks();
3427
3443
  tps.reset();
3428
3444
  ui.footer.set({ tps: 0, tpsEstimated: false, pp: void 0, cachePct: void 0, cacheFirst: false });
3429
3445
  turnStartWall = Date.now();
@@ -3645,6 +3661,11 @@ function attachTui(ctx, agent, ui, service, getAgent) {
3645
3661
  offAgentCreated();
3646
3662
  offAgentStatus();
3647
3663
  offAgentDisposed();
3664
+ offJobsChanged?.();
3665
+ if (backgroundTaskCount > 0) {
3666
+ ui.footer.set({ backgroundTasks: 0 });
3667
+ ui.requestRender();
3668
+ }
3648
3669
  if (subagentCount > 0) {
3649
3670
  ui.footer.set({ subagents: 0 });
3650
3671
  ui.requestRender();
@@ -1634,7 +1634,11 @@ var FooterComponent = class {
1634
1634
  const turn = this.#turnRow(w);
1635
1635
  const rows = [place, turn.line];
1636
1636
  const count = this.state.subagents ?? 0;
1637
- const agents = count > 0 ? this.#ink("sky")(`subagents ${Math.floor(count)}`) : "";
1637
+ const tasks = this.state.backgroundTasks ?? 0;
1638
+ const agents = [
1639
+ tasks > 0 ? this.#ink("sky")(`task ${Math.floor(tasks)}`) : "",
1640
+ count > 0 ? this.#ink("sky")(`subagents ${Math.floor(count)}`) : ""
1641
+ ].filter(Boolean).join(" ");
1638
1642
  const firstRoom = agents ? Math.max(1, w - visibleWidth4(agents) - GAP) : w;
1639
1643
  const speeds = this.#speedRows(w, firstRoom);
1640
1644
  if (agents) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziamana/bruine",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Interactive terminal coding agent that runs your own models, local or OpenAI-compatible",
5
5
  "type": "module",
6
6
  "license": "MIT",