@holt-os/holt 0.18.0 → 0.18.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 (2) hide show
  1. package/dist/cli.js +68 -11
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -46,7 +46,7 @@ function createStatusBar() {
46
46
  let detached = false;
47
47
  const realWrite = out.write.bind(out);
48
48
  const rows = () => out.rows || 24;
49
- const paint = () => {
49
+ const paint2 = () => {
50
50
  if (detached) return;
51
51
  const r = rows();
52
52
  realWrite(
@@ -61,7 +61,7 @@ function createStatusBar() {
61
61
  `${CSI}1;${Math.max(1, r - 1)}r${CSI}${Math.max(1, r - 1)};1H`
62
62
  // move cursor into the region
63
63
  );
64
- paint();
64
+ paint2();
65
65
  };
66
66
  const onResize = () => {
67
67
  if (!detached) reserve();
@@ -93,7 +93,7 @@ function createStatusBar() {
93
93
  active: true,
94
94
  set(next) {
95
95
  text = next;
96
- paint();
96
+ paint2();
97
97
  },
98
98
  detach
99
99
  };
@@ -7547,7 +7547,7 @@ function holtTools() {
7547
7547
  }
7548
7548
 
7549
7549
  // src/version.ts
7550
- var VERSION = "0.18.0";
7550
+ var VERSION = "0.18.1";
7551
7551
 
7552
7552
  // src/commands/mcp.ts
7553
7553
  function printSetup() {
@@ -7593,6 +7593,7 @@ async function mcp(sub, rest = []) {
7593
7593
  }
7594
7594
 
7595
7595
  // src/commands/statusline.ts
7596
+ import { execFileSync } from "child_process";
7596
7597
  import { basename as basename3 } from "path";
7597
7598
  var SEP = " \xB7 ";
7598
7599
  function readStdin2(timeoutMs) {
@@ -7626,9 +7627,12 @@ function str(v) {
7626
7627
  const t = v.trim();
7627
7628
  return t.length ? t : void 0;
7628
7629
  }
7629
- function folderFrom(data) {
7630
+ function dirFrom(data) {
7630
7631
  const ws = get(data, "workspace");
7631
- const dir = str(get(ws, "current_dir")) ?? str(get(ws, "project_dir")) ?? str(get(ws, "cwd")) ?? str(get(data, "cwd")) ?? str(get(data, "current_dir"));
7632
+ return str(get(ws, "current_dir")) ?? str(get(ws, "project_dir")) ?? str(get(ws, "cwd")) ?? str(get(data, "cwd")) ?? str(get(data, "current_dir"));
7633
+ }
7634
+ function folderFrom(data) {
7635
+ const dir = dirFrom(data);
7632
7636
  if (!dir) return void 0;
7633
7637
  try {
7634
7638
  const base = basename3(dir.replace(/[\\/]+$/, ""));
@@ -7642,14 +7646,63 @@ function modelFrom(data) {
7642
7646
  if (typeof model === "string") return str(model);
7643
7647
  return str(get(model, "display_name")) ?? str(get(model, "id")) ?? str(get(data, "model_display_name")) ?? str(get(data, "model_id"));
7644
7648
  }
7645
- function renderStatusLine(data) {
7646
- const parts = ["Holt"];
7649
+ function contextPctFrom(data) {
7650
+ const cw = get(data, "context_window");
7651
+ const clamp = (n) => Math.max(0, Math.min(100, Math.round(n)));
7652
+ const used = get(cw, "used_percentage");
7653
+ if (typeof used === "number" && Number.isFinite(used)) return clamp(used);
7654
+ if (typeof used === "string" && used.trim() && Number.isFinite(Number(used))) {
7655
+ return clamp(Number(used));
7656
+ }
7657
+ const size = get(cw, "context_window_size");
7658
+ const cu = get(cw, "current_usage");
7659
+ if (typeof size === "number" && size > 0 && cu && typeof cu === "object") {
7660
+ const n = (k) => {
7661
+ const v = get(cu, k);
7662
+ return typeof v === "number" && Number.isFinite(v) ? v : 0;
7663
+ };
7664
+ const tokens2 = n("input_tokens") + n("cache_creation_input_tokens") + n("cache_read_input_tokens");
7665
+ if (tokens2 > 0) return clamp(tokens2 / size * 100);
7666
+ }
7667
+ return void 0;
7668
+ }
7669
+ function contextBar(pct) {
7670
+ if (pct === void 0) return `[${"\u2591".repeat(20)}] --`;
7671
+ const filled = Math.floor(pct / 5);
7672
+ return `[${"\u2588".repeat(filled)}${"\u2591".repeat(20 - filled)}] ${pct}%`;
7673
+ }
7674
+ function paint(code, text, color) {
7675
+ return color ? `\x1B[${code}m${text}\x1B[0m` : text;
7676
+ }
7677
+ function renderStatusLine(data, opts = {}) {
7678
+ const color = opts.color ?? false;
7679
+ const parts = [paint("1;35", "Holt", color)];
7647
7680
  const folder = folderFrom(data);
7648
- if (folder) parts.push(folder);
7681
+ if (folder) {
7682
+ const branch = str(opts.branch);
7683
+ parts.push(
7684
+ paint("1;34", folder, color) + (branch ? " " + paint("1;33", `(${branch})`, color) : "")
7685
+ );
7686
+ }
7649
7687
  const model = modelFrom(data);
7650
- if (model) parts.push(model);
7688
+ if (model) parts.push(paint("0;36", model, color));
7689
+ if (folder || model) parts.push(paint("0;32", contextBar(contextPctFrom(data)), color));
7651
7690
  return parts.join(SEP);
7652
7691
  }
7692
+ function gitBranch(dir) {
7693
+ if (!dir) return void 0;
7694
+ try {
7695
+ const out = execFileSync("git", ["-C", dir, "symbolic-ref", "--short", "HEAD"], {
7696
+ encoding: "utf8",
7697
+ stdio: ["ignore", "pipe", "ignore"],
7698
+ timeout: 500,
7699
+ env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" }
7700
+ });
7701
+ return str(out);
7702
+ } catch {
7703
+ return void 0;
7704
+ }
7705
+ }
7653
7706
  function parse(raw) {
7654
7707
  try {
7655
7708
  return JSON.parse(raw || "{}");
@@ -7661,7 +7714,11 @@ async function statusline() {
7661
7714
  let line = "Holt";
7662
7715
  try {
7663
7716
  const raw = await readStdin2(1e3);
7664
- line = renderStatusLine(parse(raw));
7717
+ const data = parse(raw);
7718
+ line = renderStatusLine(data, {
7719
+ branch: gitBranch(dirFrom(data)),
7720
+ color: !process.env.NO_COLOR
7721
+ });
7665
7722
  } catch {
7666
7723
  line = "Holt";
7667
7724
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holt-os/holt",
3
- "version": "0.18.0",
3
+ "version": "0.18.1",
4
4
  "description": "An open-source personal agent OS: any LLM, private memory you can see and walk.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -44,7 +44,7 @@
44
44
  "build": "tsup src/cli.ts --format esm --clean",
45
45
  "start": "node dist/cli.js",
46
46
  "typecheck": "tsc --noEmit",
47
- "test": "tsx scripts/specs.test.ts && tsx scripts/skillcompiler.test.ts && tsx scripts/scheduler.test.ts",
47
+ "test": "tsx scripts/specs.test.ts && tsx scripts/skillcompiler.test.ts && tsx scripts/scheduler.test.ts && tsx scripts/statusline.test.ts",
48
48
  "release": "bash scripts/release.sh"
49
49
  },
50
50
  "devDependencies": {