@metaphi-ai/hum 0.1.34 → 0.1.36

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 +81 -37
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -75838,7 +75838,7 @@ function runningVersion(candidates = engineCandidates(), opts = {}) {
75838
75838
  }
75839
75839
  return null;
75840
75840
  }
75841
- function startFailure(failures, { npm = /^(node|bun)(\.exe)?$/i.test(String(process.execPath).split(/[\\/]/).pop()), platform: platform2 = process.platform, version = true ? "0.1.34" : "" } = {}) {
75841
+ function startFailure(failures, { npm = /^(node|bun)(\.exe)?$/i.test(String(process.execPath).split(/[\\/]/).pop()), platform: platform2 = process.platform, version = true ? "0.1.36" : "" } = {}) {
75842
75842
  const refused = failures.find((f) => f.error && f.error.code !== "ENOENT");
75843
75843
  const fix = npm ? npmFix(version) : updateCommand({ kind: "native" }, platform2);
75844
75844
  if (!refused) {
@@ -84541,7 +84541,7 @@ var input_default = MultilineInput;
84541
84541
 
84542
84542
  // src/app.jsx
84543
84543
  var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
84544
- var MINE = true ? "0.1.34" : "";
84544
+ var MINE = true ? "0.1.36" : "";
84545
84545
  var fmtDur = (s) => s < 60 ? `${Math.max(1, Math.round(s))}s` : `${Math.floor(s / 60)}m ${Math.round(s % 60)}s`;
84546
84546
  var plural = (n, w) => `${n} ${w}${n === 1 ? "" : "s"}`;
84547
84547
  var firstResp = (e) => e.first_response_s ? ` \xB7 first response ${e.first_response_s.toFixed(1)}s` : "";
@@ -84633,7 +84633,6 @@ var REWIND_CHOICES = [
84633
84633
  { key: "chat", label: "restore the conversation", desc: "hum carries on from what you said, on a new branch; nothing is deleted" },
84634
84634
  { key: "both", label: "both", desc: "" }
84635
84635
  ];
84636
- var OUTPUT_MAX_LINES = 200;
84637
84636
  var ERR_TAIL_LINES = 5;
84638
84637
  var THOUGHT_TAIL_LINES = 3;
84639
84638
  var diagLine = (d) => `${d.file ? `${d.file}${d.line != null ? `:${d.line}` : ""}: ` : ""}${d.severity || "error"}: ${d.message || ""}`;
@@ -84669,7 +84668,9 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84669
84668
  const [confirm, setConfirm] = (0, import_react24.useState)(null);
84670
84669
  const [gate, setGate] = (0, import_react24.useState)("off");
84671
84670
  const [paused, setPaused] = (0, import_react24.useState)(false);
84672
- const [reflection, setReflection] = (0, import_react24.useState)(null);
84671
+ const [reflections, setReflections] = (0, import_react24.useState)([]);
84672
+ const [why, setWhy] = (0, import_react24.useState)(null);
84673
+ const reflection = phase === "idle" && !proposal && !question ? reflections[0] || null : null;
84673
84674
  const attachRef = (0, import_react24.useRef)([]);
84674
84675
  const inputRef = (0, import_react24.useRef)(null);
84675
84676
  const nextId = (0, import_react24.useRef)(0);
@@ -84989,6 +84990,9 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84989
84990
  case "proposal":
84990
84991
  foldThinking();
84991
84992
  flushDraft();
84993
+ (ev.calls || []).forEach((c) => {
84994
+ if (c.diff) append({ kind: "output", name: `${c.desc} \xB7 the whole change`, lines: c.diff.split("\n"), diff: true });
84995
+ });
84992
84996
  setProposal({ content: ev.content || "", calls: ev.calls || [], remember: ev.remember || [], remember_text: ev.remember_text || "" });
84993
84997
  setStatus("waiting for your decision");
84994
84998
  break;
@@ -85015,12 +85019,15 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85015
85019
  setQCursor(0);
85016
85020
  append({ kind: "info", text: `answered: ${ev.answer}` });
85017
85021
  break;
85022
+ case "mcp":
85023
+ append({ kind: "mcp", servers: ev.servers || [] });
85024
+ break;
85018
85025
  case "reflection":
85019
- setReflection({ id: ev.id, well: ev.well || [], missed: ev.missed || [] });
85026
+ setReflections((rs) => rs.some((r) => r.id === ev.id) ? rs : [...rs, { id: ev.id, category: ev.category || "other", title: ev.title || "", details: ev.details || "", area: ev.area || "" }]);
85020
85027
  break;
85021
85028
  case "reflection_closed":
85022
- setReflection((r) => r && r.id === ev.id ? null : r);
85023
- if (ev.vote !== "dismiss") append({ kind: "info", text: ev.vote === "up" ? "upvoted" : "downvoted" });
85029
+ setReflections((rs) => rs.filter((r) => r.id !== ev.id));
85030
+ if (ev.vote !== "dismiss") append({ kind: "info", text: ev.vote === "up" ? "marked true" : "marked false" });
85024
85031
  break;
85025
85032
  case "paused":
85026
85033
  foldThinking();
@@ -85190,8 +85197,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85190
85197
  if (key.ctrl && input === "o") {
85191
85198
  const last = lastOutRef.current;
85192
85199
  if (last && last.content) {
85193
- const ls = last.content.split("\n");
85194
- append({ kind: "output", name: last.name, lines: ls.slice(0, OUTPUT_MAX_LINES), more: Math.max(0, ls.length - OUTPUT_MAX_LINES) });
85200
+ append({ kind: "output", name: last.name, lines: last.content.split("\n") });
85195
85201
  }
85196
85202
  return;
85197
85203
  }
@@ -85236,11 +85242,20 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85236
85242
  else if (/^[1-3]$/.test(input)) pick(REWIND_CHOICES[Number(input) - 1].key);
85237
85243
  return;
85238
85244
  }
85239
- if (reflection && !proposal && !question && !picker && !value.trim()) {
85245
+ if (reflection && !picker && !value.trim()) {
85246
+ if (why === reflection.id) {
85247
+ if (key.escape) {
85248
+ closeReflection(reflection.id, "down");
85249
+ }
85250
+ return;
85251
+ }
85240
85252
  const vote = input === "1" ? "up" : input === "2" ? "down" : key.return || key.escape ? "dismiss" : null;
85253
+ if (vote === "down") {
85254
+ setWhy(reflection.id);
85255
+ return;
85256
+ }
85241
85257
  if (vote) {
85242
- engine2.send({ cmd: "reflect_vote", id: reflection.id, vote });
85243
- setReflection(null);
85258
+ closeReflection(reflection.id, vote);
85244
85259
  return;
85245
85260
  }
85246
85261
  }
@@ -85475,12 +85490,22 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85475
85490
  break;
85476
85491
  }
85477
85492
  };
85493
+ const closeReflection = (id, vote, reason = "") => {
85494
+ engine2.send({ cmd: "reflect_vote", id, vote, ...reason ? { why: reason } : {} });
85495
+ setReflections((rs) => rs.filter((r) => r.id !== id));
85496
+ setWhy((w) => w === id ? null : w);
85497
+ setValue("");
85498
+ };
85478
85499
  const onSubmit = (line) => {
85479
85500
  const text = line.trim();
85480
85501
  setValue("");
85481
85502
  const queued = attachRef.current;
85482
85503
  const attached = text ? queued.filter((a) => text.includes(a.chip)) : queued;
85483
85504
  const dropped = queued.filter((a) => !attached.includes(a));
85505
+ if (why && reflection && why === reflection.id) {
85506
+ closeReflection(reflection.id, "down", text);
85507
+ return;
85508
+ }
85484
85509
  if (!text && attached.length === 0) return;
85485
85510
  if (!text && proposal) return;
85486
85511
  const hist = historyRef.current;
@@ -85496,10 +85521,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85496
85521
  answerStep(text);
85497
85522
  return;
85498
85523
  }
85499
- if (reflection) {
85500
- engine2.send({ cmd: "reflect_vote", id: reflection.id, vote: "dismiss" });
85501
- setReflection(null);
85502
- }
85524
+ if (reflection) closeReflection(reflection.id, "dismiss");
85503
85525
  if (text.startsWith("/")) {
85504
85526
  runCommand(text);
85505
85527
  return;
@@ -85510,10 +85532,6 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85510
85532
  if (phaseRef.current === "idle") setPhaseBoth("busy");
85511
85533
  return;
85512
85534
  }
85513
- if (paused && /^(continue|go on|carry on|keep going)\.?$/i.test(text)) {
85514
- runCommand("/continue");
85515
- return;
85516
- }
85517
85535
  if (paused) setPaused(false);
85518
85536
  if (dropped.length) append({ kind: "info", text: `not sent (chip removed): ${dropped.map((a) => a.label).join(", ")}` });
85519
85537
  append({ kind: "you", text, images: attached.map((a) => `#${a.n} ${a.label}`), steering: phaseRef.current === "busy" });
@@ -85641,8 +85659,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85641
85659
  item.kind === "errtail" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { flexDirection: "column", paddingLeft: 6, children: item.lines.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "red", dimColor: true, children: l }, i)) }),
85642
85660
  item.kind === "output" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 4, children: [
85643
85661
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: `full output \xB7 ${item.name}` }),
85644
- item.lines.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: l || " " }, i)),
85645
- item.more > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: `\u2026 +${item.more} more lines (the session file keeps everything)` }) : null
85662
+ item.lines.map((l, i) => item.diff ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: l.startsWith("+") ? "green" : l.startsWith("-") ? "red" : void 0, dimColor: !l.startsWith("+") && !l.startsWith("-"), children: l || " " }, i) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: l || " " }, i))
85646
85663
  ] }),
85647
85664
  item.kind === "turn" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
85648
85665
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: ACCENT, children: "\u273B " }),
@@ -85656,6 +85673,28 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85656
85673
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: item.text }),
85657
85674
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: "say what to do next \xB7 /continue lets it carry on" })
85658
85675
  ] }),
85676
+ item.kind === "mcp" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", children: [
85677
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
85678
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { bold: true, color: ACCENT, children: "MCP servers" }),
85679
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: ` \xB7 ${item.servers.length} in this session` })
85680
+ ] }),
85681
+ item.servers.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: " none \xB7 add [[mcp]] with a name and a url or a command to ~/.hum/config.toml; the ones your deployment provides arrive when you sign in" }) : null,
85682
+ [["deployment", "from your deployment"], ["config", "from your config (~/.hum/config.toml or the project's .hum/config.toml)"]].map(([src, label]) => {
85683
+ const rows = item.servers.filter((s) => (s.source || "config") === src);
85684
+ if (!rows.length) return null;
85685
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
85686
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: ` ${label}` }),
85687
+ rows.map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
85688
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
85689
+ s.error ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "red", children: "\u2717 " }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "green", children: "\u2714 " }),
85690
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { bold: true, children: s.name }),
85691
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: s.error ? ` \xB7 not mounted \xB7 ${s.error}` : ` \xB7 connected \xB7 ${s.tools.length} tool${s.tools.length === 1 ? "" : "s"}${s.instructions ? " \xB7 with instructions" : ""} \xB7 ${s.at}` })
85692
+ ] }),
85693
+ s.tools.length ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: ` ${s.tools.join(" \xB7 ")}` }) : null
85694
+ ] }, s.name))
85695
+ ] }, src);
85696
+ })
85697
+ ] }),
85659
85698
  item.kind === "info" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: item.text }),
85660
85699
  item.kind === "warn" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "yellow", children: item.text }),
85661
85700
  item.kind === "error" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "red", children: item.text })
@@ -85706,19 +85745,23 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85706
85745
  step.secret ? " \xB7 it is not shown and not recorded" : ""
85707
85746
  ] })
85708
85747
  ] }),
85709
- reflection && !proposal && !question && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { borderStyle: "round", borderColor: ACCENT, paddingX: 1, marginTop: 1, children: [
85748
+ reflection && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { borderStyle: "round", borderColor: ACCENT, paddingX: 1, marginTop: 1, children: [
85710
85749
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { flexDirection: "column", width: MASCOT_WIDTH + 1, flexShrink: 0, marginRight: 1, children: MASCOT.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: ACCENT, bold: true, children: row }, i)) }),
85711
85750
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", flexGrow: 1, children: [
85712
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { bold: true, children: "looking back" }),
85713
- reflection.well.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
85714
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "green", children: " \u2713 " }),
85715
- l
85716
- ] }, `w${i}`)),
85717
- reflection.missed.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
85718
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "yellow", children: " \u2717 " }),
85719
- l
85720
- ] }, `m${i}`)),
85721
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: " 1 upvote \xB7 2 downvote \xB7 enter dismiss" })
85751
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
85752
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: ACCENT, bold: true, children: "\u2726 hum on its own work" }),
85753
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: ` \xB7 ${reflection.category.replace(/_/g, " ")}${reflection.area ? ` \xB7 ${reflection.area}` : ""}` })
85754
+ ] }),
85755
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { bold: true, children: reflection.title }),
85756
+ reflection.details.split("\n").map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: ` ${l}` }, `d${i}`)),
85757
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: " " }),
85758
+ why === reflection.id ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
85759
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { bold: true, children: "What did it get wrong? " }),
85760
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: "type a line and press enter \xB7 enter alone records the no without a reason" })
85761
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
85762
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { bold: true, children: "Is this true? " }),
85763
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: `press 1 for yes \xB7 2 for no \xB7 enter to skip${reflections.length > 1 ? ` \xB7 ${reflections.length - 1} more after this` : ""}` })
85764
+ ] })
85722
85765
  ] })
85723
85766
  ] }),
85724
85767
  proposal && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: ACCENT, paddingX: 1, marginTop: 1, children: [
@@ -85749,7 +85792,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85749
85792
  ] }),
85750
85793
  (c.name === "bash" || c.name === "powershell") && c.desc !== `$ ${String(c.args?.command || "")}` ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: "cyan", children: [
85751
85794
  " $ ",
85752
- String(c.args?.command || "").split("\n").join(" \u23CE ").slice(0, 300)
85795
+ String(c.args?.command || "").split("\n").join(" \u23CE ")
85753
85796
  ] }) : null,
85754
85797
  c.escape ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: "yellow", children: [
85755
85798
  " outside the sandbox \u2014 ",
@@ -85767,7 +85810,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85767
85810
  },
85768
85811
  i
85769
85812
  )) : null,
85770
- c.diff && c.diff.split("\n").length > DIFF_TAIL_LINES ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: ` \u2026 +${c.diff.split("\n").length - DIFF_TAIL_LINES} more diff lines` }) : null
85813
+ c.diff && c.diff.split("\n").length > DIFF_TAIL_LINES ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: ` the whole change (${c.diff.split("\n").length} lines) is above` }) : null
85771
85814
  ] }, c.id))
85772
85815
  ] }),
85773
85816
  picker && picker.kind === "model" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, marginTop: 1, children: [
@@ -85927,12 +85970,13 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85927
85970
  mask: !!(step && step.secret),
85928
85971
  swallow: (input, key) => {
85929
85972
  if (picker || value.trim()) return false;
85973
+ if (reflection && why !== reflection.id && (input === "1" || input === "2")) return true;
85930
85974
  if (proposal && (input === "a" || input === "p") && (proposal.remember || []).length) return true;
85931
85975
  if (!question || !step) return false;
85932
85976
  if (/^[1-9]$/.test(input) && Number(input) <= stepLabels.length) return true;
85933
85977
  return !!(step.multi && stepLabels.length && input === " ");
85934
85978
  },
85935
- placeholder: question && step ? stepLabels.length ? "a number, or your answer" : "your answer" : proposal ? (proposal.remember || []).length ? "enter approves \xB7 a / p allow this shape \xB7 or type why not" : "enter to approve \xB7 or type why not" : paused ? "paused \xB7 say what to do, or /continue" : phase === "busy" ? "type to steer \xB7 esc to stop \xB7 !cmd runs a command" : session ? "what next?" : "what are we doing?"
85979
+ placeholder: why && reflection && why === reflection.id ? "what did it get wrong? (enter alone: just the no)" : question && step ? stepLabels.length ? "a number, or your answer" : "your answer" : proposal ? (proposal.remember || []).length ? "enter approves \xB7 a / p allow this shape \xB7 or type why not" : "enter to approve \xB7 or type why not" : paused ? "paused \xB7 say what to do, or /continue" : phase === "busy" ? "type to steer \xB7 esc to stop \xB7 !cmd runs a command" : session ? "what next?" : "what are we doing?"
85936
85980
  }
85937
85981
  )
85938
85982
  ] }),
@@ -85956,7 +86000,7 @@ init_update();
85956
86000
  init_install();
85957
86001
  var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
85958
86002
  import { spawnSync as spawnSync5 } from "node:child_process";
85959
- var MINE2 = true ? "0.1.34" : "0.0.0";
86003
+ var MINE2 = true ? "0.1.36" : "0.0.0";
85960
86004
  var layout = installLayout();
85961
86005
  function completeInstall() {
85962
86006
  if (layout.kind !== "npm" || !needsInstall(MINE2)) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaphi-ai/hum",
3
- "version": "0.1.34",
3
+ "version": "0.1.36",
4
4
  "description": "Hum (हम): a self-improving coding agent for your terminal.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",