@ziamana/bruine 0.1.0 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +24 -1
  2. package/dist/bin.js +34 -4
  3. package/package.json +1 -1
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
  ![Windows · macOS · Linux](https://img.shields.io/badge/Windows%20%C2%B7%20macOS%20%C2%B7%20Linux-supported-8fe3a3)
15
- [![Changelog](https://img.shields.io/badge/version-0.1.0-ff9ed2)](CHANGELOG.md)
15
+ [![Changelog](https://img.shields.io/badge/version-0.1.1-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
 
@@ -35,6 +35,29 @@ bruine
35
35
  The first launch opens a setup wizard: it finds a local model server if you run one, asks for API
36
36
  keys if you want a cloud route, lets you pick skills, and writes `~/.bruine/`.
37
37
 
38
+ ## Install
39
+
40
+ You need **Node 22 or newer** and npm (it comes with Node). Check with `node --version`.
41
+
42
+ | | Get Node 22+ | Install bruine | Open it in |
43
+ |---|---|---|---|
44
+ | **Linux** | your package manager (`sudo pacman -S nodejs npm`, `sudo apt install nodejs npm` if it is 22+) or [nvm](https://github.com/nvm-sh/nvm) | `npm install -g @ziamana/bruine` | any terminal |
45
+ | **macOS** | `brew install node`, or the installer from [nodejs.org](https://nodejs.org) | `npm install -g @ziamana/bruine` | Terminal or iTerm2 |
46
+ | **Windows** | `winget install OpenJS.NodeJS.LTS`, or the installer from [nodejs.org](https://nodejs.org) | `npm install -g @ziamana/bruine` | Windows Terminal (PowerShell) |
47
+
48
+ Then type `bruine` in your project's folder. The command is `bruine`; `@ziamana/bruine` is only the
49
+ name npm knows it by.
50
+
51
+ - **Permission denied (`EACCES`) on Linux or macOS**: do not use `sudo`. Point npm at a folder you own:
52
+ `npm config set prefix ~/.local`, and make sure `~/.local/bin` is on your `PATH`.
53
+ - **Update**: `bruine update` (or `/update` in a session). **Remove**: `npm uninstall -g @ziamana/bruine`,
54
+ and delete `~/.bruine` if you want your settings gone too.
55
+ - **Where it was tested**: Linux every day. On macOS the unit tests pass on the CI runner and the
56
+ terminal tests are being fixed; on Windows both are being fixed, and it has not yet been run by hand
57
+ on a real Windows machine. If something breaks there,
58
+ [open an issue](https://github.com/ziamana/bruine/issues) with your terminal and `bruine --version`.
59
+ [docs/PLATFORMS.md](docs/PLATFORMS.md) lists what was checked.
60
+
38
61
  ## See it
39
62
 
40
63
  <img src="docs/demo/bruine.svg" alt="bruine in a terminal: a prompt, the model's reasoning streaming then folding away, a file read, an edit shown as a diff, two permission prompts, the tests passing, and a second prompt that was queued while it worked going out after" width="100%">
package/dist/bin.js CHANGED
@@ -4625,7 +4625,7 @@ var init_config = __esm({
4625
4625
  });
4626
4626
 
4627
4627
  // src/mcp/state.ts
4628
- import { mkdirSync, readFileSync as readFileSync6, renameSync, writeFileSync } from "fs";
4628
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync6, renameSync, writeFileSync } from "fs";
4629
4629
  import path7 from "path";
4630
4630
  function projectKey(dir, platform = process.platform) {
4631
4631
  const abs = path7.resolve(dir);
@@ -4643,7 +4643,7 @@ function readMcpState(home) {
4643
4643
  }
4644
4644
  }
4645
4645
  function writeMcpState(home, state2) {
4646
- mkdirSync(home, { recursive: true });
4646
+ mkdirSync2(home, { recursive: true });
4647
4647
  const target = path7.join(home, MCP_STATE_FILE);
4648
4648
  const temp = `${target}.${String(process.pid)}.tmp`;
4649
4649
  writeFileSync(temp, `${JSON.stringify(state2, null, 2)}
@@ -4802,7 +4802,7 @@ function flagMode(argv) {
4802
4802
  // src/profile.ts
4803
4803
  import { createRequire as createRequire2 } from "module";
4804
4804
  import { mkdir, readFile, rename, rm, stat, writeFile } from "fs/promises";
4805
- import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
4805
+ import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, rmSync, symlinkSync } from "fs";
4806
4806
  import path3 from "path";
4807
4807
  import { parse as parseYaml } from "yaml";
4808
4808
  var require3 = createRequire2(import.meta.url);
@@ -4934,6 +4934,30 @@ async function ensureProfile(dshHome, pathMod = path3) {
4934
4934
  await writePersonaPatch(p.patchYml, dshHome, pathMod);
4935
4935
  return { created: true, dir };
4936
4936
  }
4937
+ function linkProfileBundles(profileDir, own, dshBaseDir) {
4938
+ const type = process.platform === "win32" ? "junction" : "dir";
4939
+ const link = (target, at) => {
4940
+ mkdirSync(path3.dirname(at), { recursive: true });
4941
+ rmSync(at, { recursive: true, force: true });
4942
+ symlinkSync(target, at, type);
4943
+ };
4944
+ try {
4945
+ const modules = path3.join(profileDir, "node_modules");
4946
+ link(own.root, path3.join(modules, own.name));
4947
+ link(dshBaseDir, path3.join(modules, "@deepseek-ai", "dsh-base"));
4948
+ return true;
4949
+ } catch {
4950
+ return false;
4951
+ }
4952
+ }
4953
+ function resolveDshBaseDir() {
4954
+ try {
4955
+ const dshRequire = createRequire2(require3.resolve("@deepseek-ai/dsh/package.json"));
4956
+ return path3.dirname(dshRequire.resolve("@deepseek-ai/dsh-base/package.json"));
4957
+ } catch {
4958
+ return void 0;
4959
+ }
4960
+ }
4937
4961
 
4938
4962
  // src/bin.ts
4939
4963
  init_simple();
@@ -5060,8 +5084,14 @@ function selfPackageRoot() {
5060
5084
  function ensureBundleInstalled(profileDir, dshEntry, env, headless = false) {
5061
5085
  const marker = join7(profileDir, "node_modules", pkg2.name, "package.json");
5062
5086
  if (existsSync7(marker)) return;
5063
- const spec = selfPackageRoot() ?? `${pkg2.name}@${pkg2.version}`;
5087
+ const root = selfPackageRoot();
5064
5088
  if (!headless) console.log("Setting up bruine (one time)\u2026");
5089
+ const dshBase = resolveDshBaseDir();
5090
+ if (root !== void 0 && dshBase !== void 0 && linkProfileBundles(profileDir, { name: pkg2.name, root }, dshBase)) {
5091
+ if (!headless) console.log("Ready.");
5092
+ return;
5093
+ }
5094
+ const spec = root ?? `${pkg2.name}@${pkg2.version}`;
5065
5095
  const { status, error, output } = runDsh(
5066
5096
  dshEntry,
5067
5097
  ["plugin", "--profile", "bruine", "add", spec],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziamana/bruine",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Interactive terminal coding agent that runs your own models, local or OpenAI-compatible",
5
5
  "type": "module",
6
6
  "license": "MIT",