@metaphi-ai/hum 0.2.22 → 0.2.24

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 +62 -11
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -88639,7 +88639,7 @@ var win, MINE, npmFix, NPM_FIX, humHome, versionsDir, versionDir, pkgDir, coreDi
88639
88639
  var init_install = __esm({
88640
88640
  "src/install.js"() {
88641
88641
  win = process.platform === "win32";
88642
- MINE = true ? "0.2.22" : "";
88642
+ MINE = true ? "0.2.24" : "";
88643
88643
  npmFix = (version = "") => `npm i -g @metaphi-ai/hum@${version || "latest"} --foreground-scripts`;
88644
88644
  NPM_FIX = npmFix("latest");
88645
88645
  humHome = (env3 = process.env) => env3.HUM_HOME || path.join(os3.homedir(), ".hum");
@@ -88975,10 +88975,10 @@ function clientEnv() {
88975
88975
  platform: process.platform,
88976
88976
  arch: process.arch,
88977
88977
  terminal: process.env.TERM_PROGRAM || (process.env.WT_SESSION ? "Windows Terminal" : process.env.TERM || ""),
88978
- tui: true ? "0.2.22" : ""
88978
+ tui: true ? "0.2.24" : ""
88979
88979
  };
88980
88980
  }
88981
- function startFailure(failures, { npm = /^(node|bun)(\.exe)?$/i.test(String(process.execPath).split(/[\\/]/).pop()), platform: platform2 = process.platform, version = true ? "0.2.22" : "" } = {}) {
88981
+ function startFailure(failures, { npm = /^(node|bun)(\.exe)?$/i.test(String(process.execPath).split(/[\\/]/).pop()), platform: platform2 = process.platform, version = true ? "0.2.24" : "" } = {}) {
88982
88982
  const refused = failures.find((f) => f.error && f.error.code !== "ENOENT");
88983
88983
  const fix = npm ? npmFix(version) : updateCommand({ kind: "native" }, platform2);
88984
88984
  if (!refused) {
@@ -90514,7 +90514,7 @@ var input_default = MultilineInput;
90514
90514
 
90515
90515
  // src/app.jsx
90516
90516
  var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
90517
- var MINE2 = true ? "0.2.22" : "";
90517
+ var MINE2 = true ? "0.2.24" : "";
90518
90518
  var fmtDur = (s) => s < 60 ? `${Math.max(1, Math.round(s))}s` : `${Math.floor(s / 60)}m ${Math.round(s % 60)}s`;
90519
90519
  var plural = (n, w) => `${n} ${w}${n === 1 ? "" : "s"}`;
90520
90520
  var firstResp = (e) => e.first_response_s ? ` \xB7 first response ${e.first_response_s.toFixed(1)}s` : "";
@@ -90616,6 +90616,7 @@ var COMMANDS = [
90616
90616
  { name: "/context", desc: "what fills the context window: system prompt, tool schemas, messages, tool results" },
90617
90617
  { name: "/usage-credits", desc: "your credits on our models, and the page that adds more (a code from Metaphi, or a purchase)" },
90618
90618
  { name: "/approve", desc: "approvals on|off \u2014 whether every change and command waits for you first (leaving the sandbox always asks)" },
90619
+ { name: "/agent", desc: "speak to one running sub-agent (/agent 2 <what it should do>), or end it (/agent 2 stop); enter on its row starts the line" },
90619
90620
  { name: "/continue", desc: "after a pause: let the agent carry on" },
90620
90621
  { name: "/goal", desc: "the goal the session keeps working toward on its own, exchange after exchange, until the model marks it complete or blocked (/goal <objective>; /goal pause \xB7 resume \xB7 clear; /goal alone shows where it stands)" },
90621
90622
  { name: "/image", desc: "attach an image file to your next message (/image <path>); ctrl+v pastes a screenshot" },
@@ -90695,6 +90696,7 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
90695
90696
  const [sendingAsk, setSendingAsk] = (0, import_react36.useState)(null);
90696
90697
  const pendingAsk = (0, import_react36.useRef)(null);
90697
90698
  const [confirm, setConfirm] = (0, import_react36.useState)(null);
90699
+ const [trust, setTrust] = (0, import_react36.useState)(null);
90698
90700
  const [gate, setGate] = (0, import_react36.useState)("off");
90699
90701
  const [paused, setPaused] = (0, import_react36.useState)(false);
90700
90702
  const [reflections, setReflections] = (0, import_react36.useState)([]);
@@ -90811,6 +90813,7 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
90811
90813
  setPaused(false);
90812
90814
  setPicker(null);
90813
90815
  setConfirm(null);
90816
+ setTrust(null);
90814
90817
  setSpend(0);
90815
90818
  setGoal(null);
90816
90819
  setSession(null);
@@ -91130,7 +91133,7 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
91130
91133
  (ev.calls || []).forEach((c) => {
91131
91134
  if (c.diff) append({ kind: "output", name: `${c.desc} \xB7 the whole change`, lines: c.diff.split("\n"), diff: true });
91132
91135
  });
91133
- setProposal({ content: ev.content || "", calls: ev.calls || [], remember: ev.remember || [], remember_text: ev.remember_text || "" });
91136
+ setProposal({ content: ev.content || "", calls: ev.calls || [], remember: ev.remember || [], remember_text: ev.remember_text || "", agent: ev.agent || null });
91134
91137
  setStatus("waiting for your decision");
91135
91138
  break;
91136
91139
  case "question":
@@ -91209,6 +91212,9 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
91209
91212
  setPicker({ kind: "rewind", items: items2, index: want >= 0 ? want : items2.length - 1, top: 0, choice: null });
91210
91213
  break;
91211
91214
  }
91215
+ case "trust":
91216
+ setTrust({ path: ev.path || "", starts: ev.starts || [] });
91217
+ break;
91212
91218
  case "rewind_confirm":
91213
91219
  setPicker(null);
91214
91220
  setConfirm({ node: ev.node, said: ev.said || "", stat: ev.stat || "", why: ev.why || "" });
@@ -91371,7 +91377,7 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
91371
91377
  }
91372
91378
  return;
91373
91379
  }
91374
- const panelOpen = agents.length > 0 && !value && !picker && !confirm && !proposal && !question && !reflection;
91380
+ const panelOpen = agents.length > 0 && !value && !picker && !confirm && !trust && !proposal && !question && !reflection;
91375
91381
  if (panelOpen && panelIndex < 0 && key.downArrow) {
91376
91382
  setPanelIndex(0);
91377
91383
  return;
@@ -91392,10 +91398,29 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
91392
91398
  if (key.return) {
91393
91399
  const a = agents[panelIndex];
91394
91400
  if (a && a.worker) openLook(a);
91401
+ else if (a) {
91402
+ if (inputRef.current) inputRef.current.insert(`/agent ${a.n} `);
91403
+ setPanelIndex(-1);
91404
+ }
91395
91405
  return;
91396
91406
  }
91397
91407
  if (input && !key.ctrl && !key.meta && input >= " ") setPanelIndex(-1);
91398
91408
  }
91409
+ if (trust && !picker) {
91410
+ if (input === "y" || key.return) {
91411
+ setTrust(null);
91412
+ core2.send({ cmd: "trust", ok: true });
91413
+ append({ kind: "info", text: `trusted \xB7 ${trust.path}` });
91414
+ return;
91415
+ }
91416
+ if (input === "n" || key.escape) {
91417
+ setTrust(null);
91418
+ core2.send({ cmd: "trust", ok: false });
91419
+ append({ kind: "info", text: "left off \xB7 hum trust allows them later" });
91420
+ return;
91421
+ }
91422
+ return;
91423
+ }
91399
91424
  if (confirm && !picker) {
91400
91425
  if (key.return) {
91401
91426
  setConfirm(null);
@@ -91745,6 +91770,15 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
91745
91770
  case "/goal":
91746
91771
  core2.send(arg ? { cmd: "goal", text: arg } : { cmd: "goal" });
91747
91772
  break;
91773
+ case "/agent": {
91774
+ const m = /^(\d+)\s+([\s\S]+)$/.exec(arg || "");
91775
+ if (!m) {
91776
+ append({ kind: "info", text: "/agent <number> <what it should do>, or /agent <number> stop" });
91777
+ break;
91778
+ }
91779
+ core2.send(m[2].trim() === "stop" ? { cmd: "agent", agent: Number(m[1]), stop: true } : { cmd: "agent", agent: Number(m[1]), text: m[2].trim() });
91780
+ break;
91781
+ }
91748
91782
  case "/approve": {
91749
91783
  const mode = arg === "on" ? "approve" : arg === "off" ? "off" : gate === "approve" ? "off" : "approve";
91750
91784
  core2.send({ cmd: "gate", mode });
@@ -91842,7 +91876,7 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
91842
91876
  const statusLine = phase === "connecting" ? "starting \u2026" : `${modelRef.current || ""} \xB7 ${fmtCost2(spend)}` + (ctxPct >= 10 ? ` \xB7 ctx ${ctxPct}%` : "") + (gate === "approve" ? " \xB7 approvals on" : "") + (hello && hello.mounting && hello.mounting.length ? ` \xB7 mounting ${hello.mounting.join(", ")}` : "") + (goal && goal.text ? ` \xB7 \u25CE goal ${goal.status || "active"}` : "") + (needYou ? ` \xB7 ${needYou} need you` : "") + (ready ? ` \xB7 restart for hum ${ready}` : "") + (offer ? " \xB7 /accept \xB7 /reject" : "") + (agents.length && panelIndex < 0 && !looking ? " \xB7 \u2193 agents" : "") + (ctrlc ? " \xB7 ctrl+c again to quit" : " \xB7 / for commands");
91843
91877
  const spinnerLabel = phase === "connecting" ? " starting \u2026" : ` ${status || "working"}${elapsed >= 2 ? ` \xB7 ${fmtDur(elapsed)}` : ""}` + (thinkChars.current > 4e3 ? ` \xB7 ${(thinkChars.current / 1e3).toFixed(0)}k thinking` : "");
91844
91878
  const rows = stdout?.rows || DEFAULT_ROWS;
91845
- const chrome = 1 + 2 + 4 + (value.split("\n").length - 1) + 1 + (menu.length ? menu.length : 0) + (!menu.length && agents.length ? agents.length + 1 : 0) + (looking ? 4 + (looking.question ? (looking.question.options || []).length + 2 : Math.min(PEEK_LINES, looking.lines.length) + 1) : 0) + (question && step ? 9 + Math.min(consultHeight, consultLines.length) : 0) + (proposal ? 4 + proposal.calls.length * (1 + Math.min(DIFF_TAIL_LINES, 8)) : 0) + (reflection ? 8 + reflection.details.split("\n").length : 0) + (confirm ? 4 + Math.min(8, String(confirm.stat || "").split("\n").length) : 0) + (picker ? 14 : 0);
91879
+ const chrome = 1 + 2 + 4 + (value.split("\n").length - 1) + 1 + (menu.length ? menu.length : 0) + (!menu.length && agents.length ? agents.length + 1 : 0) + (looking ? 4 + (looking.question ? (looking.question.options || []).length + 2 : Math.min(PEEK_LINES, looking.lines.length) + 1) : 0) + (question && step ? 9 + Math.min(consultHeight, consultLines.length) : 0) + (proposal ? 4 + proposal.calls.length * (1 + Math.min(DIFF_TAIL_LINES, 8)) : 0) + (reflection ? 8 + reflection.details.split("\n").length : 0) + (confirm ? 4 + Math.min(8, String(confirm.stat || "").split("\n").length) : 0) + (trust ? 4 + trust.starts.length : 0) + (picker ? 14 : 0);
91846
91880
  const liveBudget = Math.max(LIVE_MIN_ROWS, Math.min(DRAFT_TAIL_LINES, rows - 1 - chrome));
91847
91881
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", children: [
91848
91882
  /* @__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: [
@@ -92004,8 +92038,8 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
92004
92038
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: ` \xB7 ${item.servers.length} in this session` })
92005
92039
  ] }),
92006
92040
  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,
92007
- [["deployment", "from your deployment"], ["config", "from your config (~/.hum/config.toml or the project's .hum/config.toml)"]].map(([src, label]) => {
92008
- const rows2 = item.servers.filter((s) => (s.source || "config") === src);
92041
+ [["deployment", "from your deployment"], ["config", "from your config (~/.hum/config.toml or the project's .hum/config.toml)"], ["plugin", "from a plugin"], ["agent", "from the agent file this session runs as"], ["program", "from the program that started this session"]].map(([src, label]) => {
92042
+ const rows2 = item.servers.filter((s) => (s.source || "config").split(":")[0] === src);
92009
92043
  if (!rows2.length) return null;
92010
92044
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
92011
92045
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: ` ${label}` }),
@@ -92089,7 +92123,8 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
92089
92123
  proposal && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: ACCENT, paddingX: 1, marginTop: 1, children: [
92090
92124
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
92091
92125
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: ACCENT, bold: true, children: "? " }),
92092
- "hum wants to",
92126
+ proposal.agent ? `hum's sub-agent ${proposal.agent.agent} (${proposal.agent.description || proposal.agent.kind})` : "hum",
92127
+ " wants to",
92093
92128
  proposal.calls.some((c) => c.escape) ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "yellow", children: " leave the sandbox" }) : null,
92094
92129
  " ",
92095
92130
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: "\xB7 enter approves \xB7 type a reason to reject \xB7 esc stops" })
@@ -92205,6 +92240,21 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
92205
92240
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { children: " " }),
92206
92241
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: "\u2190/\u2192 to adjust \xB7 Enter to confirm \xB7 s for this session only \xB7 Esc to cancel" })
92207
92242
  ] }),
92243
+ trust && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginTop: 1, children: [
92244
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: "yellow", bold: true, children: [
92245
+ "? ",
92246
+ "this repository's files would start, on your word ",
92247
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: "\xB7 y starts them \xB7 n leaves them off" })
92248
+ ] }),
92249
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
92250
+ " ",
92251
+ trust.path
92252
+ ] }),
92253
+ trust.starts.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
92254
+ " \xB7 ",
92255
+ l
92256
+ ] }, i))
92257
+ ] }),
92208
92258
  confirm && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginTop: 1, children: [
92209
92259
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: "yellow", bold: true, children: [
92210
92260
  "\u23EE ",
@@ -92343,6 +92393,7 @@ function App2({ core: core2, task, resume, images = [], peek = peekSession, upda
92343
92393
  if (question && (key.pageUp || key.pageDown || sendingAsk)) return true;
92344
92394
  if (picker) return !chunk;
92345
92395
  if (confirm) return !!(key.return || key.escape);
92396
+ if (trust) return input === "y" || input === "n" || !!(key.return || key.escape);
92346
92397
  if (value.trim()) return false;
92347
92398
  if (reflection && why !== reflection.id && (input === "1" || input === "2")) return true;
92348
92399
  if (proposal && (input === "a" || input === "p") && (proposal.remember || []).length) return true;
@@ -92419,7 +92470,7 @@ init_update();
92419
92470
  init_install();
92420
92471
  var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
92421
92472
  import { spawnSync as spawnSync5 } from "node:child_process";
92422
- var MINE3 = true ? "0.2.22" : "0.0.0";
92473
+ var MINE3 = true ? "0.2.24" : "0.0.0";
92423
92474
  var layout = installLayout();
92424
92475
  function completeInstall() {
92425
92476
  if (layout.kind !== "npm" || !needsInstall(MINE3)) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaphi-ai/hum",
3
- "version": "0.2.22",
3
+ "version": "0.2.24",
4
4
  "description": "Hum: a self-improving coding agent for your terminal.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",