@metaphi-ai/hum 0.1.10 → 0.1.12

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.mjs +97 -12
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -83566,6 +83566,44 @@ function renderMarkdown(text, width) {
83566
83566
  return renderBlocks(tokens, Math.max(20, width)).join("\n\n").replace(/\s+$/, "");
83567
83567
  }
83568
83568
 
83569
+ // src/wordmark.js
83570
+ var WORDMARK = [
83571
+ "\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557",
83572
+ "\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551",
83573
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551",
83574
+ "\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551",
83575
+ "\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551",
83576
+ "\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D"
83577
+ ];
83578
+ var TAGLINE = "\u0939\u092E \xB7 human and model, one harness";
83579
+
83580
+ // src/update.js
83581
+ var DIST = "https://storage.googleapis.com/hum-dist";
83582
+ async function latestVersion(fetchImpl = globalThis.fetch) {
83583
+ if (process.env.HUM_NO_UPDATE_CHECK || typeof fetchImpl !== "function") return "";
83584
+ try {
83585
+ const r = await fetchImpl(`${DIST}/releases/latest`, { signal: AbortSignal.timeout(2500) });
83586
+ if (!r.ok) return "";
83587
+ const v = (await r.text()).trim();
83588
+ return /^\d+\.\d+\.\d+$/.test(v) ? v : "";
83589
+ } catch {
83590
+ return "";
83591
+ }
83592
+ }
83593
+ var newer = (a, b) => {
83594
+ const pa = String(a).split(".").map(Number), pb = String(b).split(".").map(Number);
83595
+ for (let i = 0; i < 3; i += 1) {
83596
+ if ((pa[i] || 0) !== (pb[i] || 0)) return (pa[i] || 0) > (pb[i] || 0);
83597
+ }
83598
+ return false;
83599
+ };
83600
+ var updateCommand = (execPath = process.execPath, platform2 = process.platform) => {
83601
+ const native = !/^(node|bun)(\.exe)?$/i.test(String(execPath).split(/[\\/]/).pop());
83602
+ if (native) return platform2 === "win32" ? `irm ${DIST}/install.ps1 | iex` : `curl -fsSL ${DIST}/install.sh | sh`;
83603
+ return "npm i -g @metaphi-ai/hum@latest";
83604
+ };
83605
+ var updateLine = (latest, mine) => latest && newer(latest, mine) ? `hum ${latest} is out (this is ${mine}) \xB7 ${updateCommand()}` : "";
83606
+
83569
83607
  // src/input.jsx
83570
83608
  var import_react23 = __toESM(require_react(), 1);
83571
83609
  var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
@@ -83710,6 +83748,13 @@ var homeRel = (p) => {
83710
83748
  const h = os3.homedir();
83711
83749
  return p && h && p.startsWith(h) ? "~" + p.slice(h.length) : p;
83712
83750
  };
83751
+ var handEdit = (stat) => {
83752
+ const s = String(stat || "").trim();
83753
+ if (!s) return "you changed files by hand";
83754
+ const lines = s.split("\n");
83755
+ return lines.length === 1 ? `you edited ${s}` : `you edited files:
83756
+ ${lines.join("\n ")}`;
83757
+ };
83713
83758
  var fmtCost = (c) => c >= 0.01 ? `$${c.toFixed(2)}` : c > 0 ? `$${c.toFixed(4)}` : "$0";
83714
83759
  var HISTORY_PATH = path.join(os3.homedir(), ".hum", "history.json");
83715
83760
  var HISTORY_MAX = 300;
@@ -83858,11 +83903,13 @@ function App2({ engine: engine2, task, resume, images = [] }) {
83858
83903
  setGate(ev.gate === "approve" ? "approve" : "off");
83859
83904
  if (ev.session) setSession(ev.session);
83860
83905
  const state = ev.state && ev.state !== "new" && ev.state !== "idle" ? ` \xB7 ${ev.state}` : "";
83906
+ if (ev.fresh) append({ kind: "wordmark" });
83861
83907
  append({
83862
83908
  kind: "banner",
83863
- text: `${ev.model}${ev.user ? ` \xB7 ${ev.user}` : ""} \xB7 ${homeRel(ev.cwd)} \xB7 tools: ${ev.tools.join(", ")}${ev.sandbox ? ` \xB7 sandbox: ${ev.sandbox}` : ""}${state}`,
83909
+ text: `${ev.model}${ev.user ? ` \xB7 ${ev.user}` : ""} \xB7 ${homeRel(ev.cwd)} \xB7 tools: ${ev.tools.join(", ")}${ev.sandbox ? ` \xB7 sandbox: ${ev.sandbox}` : ""}${ev.workspace ? ` \xB7 ${ev.workspace}` : ""}${state}`,
83864
83910
  instruction: ev.session ? ev.instruction : null
83865
83911
  });
83912
+ if (ev.note) append({ kind: "warn", text: ev.note });
83866
83913
  preHello.current.forEach((it) => append(it));
83867
83914
  preHello.current = [];
83868
83915
  if (ev.session) {
@@ -83932,7 +83979,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
83932
83979
  append({ kind: "info", text: `context summarised and restarted${it.prompt_tokens_before ? ` at ${it.prompt_tokens_before.toLocaleString()} tokens` : ""}` });
83933
83980
  break;
83934
83981
  case "human_edit":
83935
- append({ kind: "info", text: `you edited files: ${it.stat}` });
83982
+ append({ kind: "info", text: handEdit(it.stat) });
83936
83983
  break;
83937
83984
  case "paused":
83938
83985
  append({ kind: "paused", text: it.detail, trip: it.kind });
@@ -84049,7 +84096,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84049
84096
  append({ kind: "info", text: ev.mode === "approve" ? "approvals on: changes and commands wait for you first" : "approvals off: the agent acts, you steer" });
84050
84097
  break;
84051
84098
  case "human_edit":
84052
- append({ kind: "info", text: `you edited files: ${ev.stat}` });
84099
+ append({ kind: "info", text: handEdit(ev.stat) });
84053
84100
  break;
84054
84101
  case "compaction":
84055
84102
  append({ kind: "info", text: `context summarised and restarted${ev.prompt_tokens_before ? ` at ${ev.prompt_tokens_before.toLocaleString()} tokens` : ""} (the session keeps everything)` });
@@ -84113,6 +84160,18 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84113
84160
  (0, import_react24.useEffect)(() => {
84114
84161
  engine2.on(handle);
84115
84162
  }, []);
84163
+ (0, import_react24.useEffect)(() => {
84164
+ if (!hello) return void 0;
84165
+ let live = true;
84166
+ latestVersion().then((v) => {
84167
+ const line = live ? updateLine(v, true ? "0.1.12" : hello.version || "0.0.0") : "";
84168
+ if (line) append({ kind: "info", text: line });
84169
+ }).catch(() => {
84170
+ });
84171
+ return () => {
84172
+ live = false;
84173
+ };
84174
+ }, [hello]);
84116
84175
  const quit = () => {
84117
84176
  if (phaseRef.current === "dead") return;
84118
84177
  const busy = phaseRef.current === "busy";
@@ -84315,6 +84374,10 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84315
84374
  const spinnerLabel = phase === "connecting" ? " starting \u2026" : ` ${status || "working"}${elapsed >= 2 ? ` \xB7 ${fmtDur(elapsed)}` : ""}` + (thinkChars.current > 4e3 ? ` \xB7 ${(thinkChars.current / 1e3).toFixed(0)}k thinking` : "");
84316
84375
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", children: [
84317
84376
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Static, { items, children: (item) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", marginBottom: ["hum", "you", "banner", "turn"].includes(item.kind) ? 1 : 0, children: [
84377
+ item.kind === "wordmark" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, children: [
84378
+ WORDMARK.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: ACCENT, bold: true, children: row }, i)),
84379
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: TAGLINE })
84380
+ ] }),
84318
84381
  item.kind === "banner" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { borderStyle: "round", borderColor: ACCENT, paddingX: 2, flexDirection: "column", alignSelf: "flex-start", children: [
84319
84382
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
84320
84383
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: ACCENT, bold: true, children: "\u2733 hum " }),
@@ -84352,10 +84415,13 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84352
84415
  " \u23BF ",
84353
84416
  item.text
84354
84417
  ] }),
84355
- item.kind === "tool" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
84356
- item.agent ? " \xB7 " : " \xB7 ",
84418
+ item.kind === "tool" && (item.agent ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
84419
+ " \xB7 ",
84357
84420
  item.text
84358
- ] }),
84421
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { children: [
84422
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { width: 2, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: ACCENT, children: "\u25CF" }) }),
84423
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { bold: true, children: item.text })
84424
+ ] })),
84359
84425
  item.kind === "plan" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
84360
84426
  item.explanation ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: item.explanation }) : null,
84361
84427
  item.steps.map((st, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
@@ -84374,10 +84440,10 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84374
84440
  ))
84375
84441
  ] }),
84376
84442
  item.kind === "tool_result" && (item.isError ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: "red", dimColor: true, children: [
84377
- item.agent ? " \u23BF " : " \u23BF ",
84443
+ item.agent ? " \u23BF " : " \u23BF ",
84378
84444
  item.text
84379
84445
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
84380
- item.agent ? " \u23BF " : " \u23BF ",
84446
+ item.agent ? " \u23BF " : " \u23BF ",
84381
84447
  item.text
84382
84448
  ] })),
84383
84449
  item.kind === "diff" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 4, children: [
@@ -84487,7 +84553,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84487
84553
  ] }, it.name);
84488
84554
  })
84489
84555
  ] }),
84490
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { borderStyle: "round", borderColor: "gray", paddingX: 1, marginTop: 1, children: [
84556
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { borderStyle: "single", borderColor: "gray", borderLeft: false, borderRight: false, paddingX: 1, marginTop: 1, children: [
84491
84557
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "cyan", children: "\u276F " }),
84492
84558
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
84493
84559
  input_default,
@@ -84668,11 +84734,15 @@ function attempt({ bin, args: args2 }, cwd2, { task, images, resume }) {
84668
84734
  settle(() => resolve(rec));
84669
84735
  return;
84670
84736
  }
84737
+ if (rec && rec.error) {
84738
+ settle(() => reject({ failed: rec.error }));
84739
+ return;
84740
+ }
84671
84741
  if (died && !rec) {
84672
84742
  settle(() => reject({ died: logPath }));
84673
84743
  return;
84674
84744
  }
84675
- if (Date.now() - t0 > 25e3) {
84745
+ if (Date.now() - t0 > 9e4) {
84676
84746
  settle(() => reject({ timeout: true }));
84677
84747
  return;
84678
84748
  }
@@ -84681,6 +84751,20 @@ function attempt({ bin, args: args2 }, cwd2, { task, images, resume }) {
84681
84751
  poll();
84682
84752
  });
84683
84753
  }
84754
+ function failureMessage(error) {
84755
+ return error.message + (error.hint ? `
84756
+ ${error.hint}` : "");
84757
+ }
84758
+ function diedMessage(logPath, text = null) {
84759
+ let tail2 = "";
84760
+ try {
84761
+ tail2 = (text ?? fs3.readFileSync(logPath, "utf8")).trim().split("\n").slice(-3).join("\n").trim();
84762
+ } catch {
84763
+ }
84764
+ return `the engine did not start${tail2 ? `:
84765
+ ${tail2}` : ""}
84766
+ (its log: ${logPath})`;
84767
+ }
84684
84768
  async function spawnEngine(cwd2, { task = null, images = [], resume = null, candidates = engineCandidates() } = {}) {
84685
84769
  const failures = [];
84686
84770
  for (const cand of candidates) {
@@ -84692,7 +84776,8 @@ async function spawnEngine(cwd2, { task = null, images = [], resume = null, cand
84692
84776
  failures.push({ ...cand, error: f.spawn });
84693
84777
  continue;
84694
84778
  }
84695
- if (f && f.died) throw new EngineError(`the engine did not start (see ${f.died})`);
84779
+ if (f && f.failed) throw new EngineError(failureMessage(f.failed));
84780
+ if (f && f.died) throw new EngineError(diedMessage(f.died));
84696
84781
  if (f && f.timeout) throw new EngineError("the engine did not start in time");
84697
84782
  throw f;
84698
84783
  }
@@ -84776,7 +84861,7 @@ import { spawnSync as spawnSync2 } from "node:child_process";
84776
84861
  var ENGINE_COMMANDS = /* @__PURE__ */ new Set(["run", "login", "logout", "whoami", "model", "key", "sessions", "show", "sync", "skill", "ps", "stop", "hooks", "engine"]);
84777
84862
  var argv0 = process.argv.slice(2);
84778
84863
  if (argv0[0] === "--version" || argv0[0] === "-V") {
84779
- process.stdout.write(`hum ${true ? "0.1.10" : "0.0.0"}
84864
+ process.stdout.write(`hum ${true ? "0.1.12" : "0.0.0"}
84780
84865
  `);
84781
84866
  process.exit(0);
84782
84867
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaphi-ai/hum",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Hum (हम): a self-improving coding agent for your terminal.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",