@metaphi-ai/hum 0.1.50 → 0.1.52

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 +56 -12
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -83545,7 +83545,7 @@ function runningVersion(candidates = engineCandidates(), opts = {}) {
83545
83545
  }
83546
83546
  return null;
83547
83547
  }
83548
- function startFailure(failures, { npm = /^(node|bun)(\.exe)?$/i.test(String(process.execPath).split(/[\\/]/).pop()), platform: platform2 = process.platform, version = true ? "0.1.50" : "" } = {}) {
83548
+ function startFailure(failures, { npm = /^(node|bun)(\.exe)?$/i.test(String(process.execPath).split(/[\\/]/).pop()), platform: platform2 = process.platform, version = true ? "0.1.52" : "" } = {}) {
83549
83549
  const refused = failures.find((f) => f.error && f.error.code !== "ENOENT");
83550
83550
  const fix = npm ? npmFix(version) : updateCommand({ kind: "native" }, platform2);
83551
83551
  if (!refused) {
@@ -85523,7 +85523,7 @@ var input_default = MultilineInput;
85523
85523
 
85524
85524
  // src/app.jsx
85525
85525
  var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
85526
- var MINE = true ? "0.1.50" : "";
85526
+ var MINE = true ? "0.1.52" : "";
85527
85527
  var fmtDur = (s) => s < 60 ? `${Math.max(1, Math.round(s))}s` : `${Math.floor(s / 60)}m ${Math.round(s % 60)}s`;
85528
85528
  var plural = (n, w) => `${n} ${w}${n === 1 ? "" : "s"}`;
85529
85529
  var firstResp = (e) => e.first_response_s ? ` \xB7 first response ${e.first_response_s.toFixed(1)}s` : "";
@@ -85594,6 +85594,8 @@ var COMMANDS = [
85594
85594
  { name: "/reasoning", desc: "how hard the model thinks, whatever the model: low, medium or high; /reasoning <level> sets it straight away" },
85595
85595
  { name: "/diff", desc: "what has changed since this session began (/diff last: the last exchange; /diff <path>: one file)" },
85596
85596
  { name: "/rewind", desc: "go back to something you said: the files, the conversation, or both (esc esc opens it too)" },
85597
+ { name: "/accept", desc: "the work as it stands is what you wanted (/accept <why>); recorded against the state it is in" },
85598
+ { name: "/reject", desc: "the work as it stands is not (/reject <why>)" },
85597
85599
  { name: "/cost", desc: "tokens and cost so far" },
85598
85600
  { name: "/usage-credits", desc: "your credits on our models, and the page that adds more (a code from Metaphi, or a purchase)" },
85599
85601
  { name: "/approve", desc: "approvals on|off \u2014 whether every change and command waits for you first (leaving the sandbox always asks)" },
@@ -85658,6 +85660,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85658
85660
  const [paused, setPaused] = (0, import_react24.useState)(false);
85659
85661
  const [reflections, setReflections] = (0, import_react24.useState)([]);
85660
85662
  const [why, setWhy] = (0, import_react24.useState)(null);
85663
+ const [offer, setOffer] = (0, import_react24.useState)(false);
85661
85664
  const reflection = phase === "idle" && !proposal && !question ? reflections[0] || null : null;
85662
85665
  const attachRef = (0, import_react24.useRef)([]);
85663
85666
  const inputRef = (0, import_react24.useRef)(null);
@@ -85677,6 +85680,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85677
85680
  const escRef = (0, import_react24.useRef)(0);
85678
85681
  const rewindRef = (0, import_react24.useRef)({ files: true, conversation: true });
85679
85682
  const wantRow = (0, import_react24.useRef)(null);
85683
+ const wroteRef = (0, import_react24.useRef)(false);
85680
85684
  const preHello = (0, import_react24.useRef)([]);
85681
85685
  const [meter, setMeter] = (0, import_react24.useState)({ tokens: 0, cap: 0, input: 0, output: 0 });
85682
85686
  const setPhaseBoth = (p) => {
@@ -85686,6 +85690,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85686
85690
  const append = (item) => setItems((prev) => [...prev, { id: nextId.current++, ...item }]);
85687
85691
  const steps = question ? question.questions && question.questions.length ? question.questions : [{ id: question.id, question: question.question, options: (question.options || []).map((o) => ({ label: o })), default: question.default }] : [];
85688
85692
  const step = steps.length ? steps[Math.min(qStep, steps.length - 1)] : null;
85693
+ const harnessQ = !!question && question.kind === "delivery" && qStep === 0;
85689
85694
  const stepOptions = step ? (step.options || []).map((o) => typeof o === "string" ? { label: o } : o) : [];
85690
85695
  const stepLabels = stepOptions.map((o) => o.label);
85691
85696
  const menu = value.trimStart().startsWith("/") && !value.includes(" ") ? COMMANDS.filter((c) => c.name.startsWith(value.trim())) : [];
@@ -85731,6 +85736,8 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85731
85736
  toolsRef.current = {};
85732
85737
  lastOutRef.current = null;
85733
85738
  attachRef.current = [];
85739
+ setOffer(false);
85740
+ wroteRef.current = false;
85734
85741
  setMeter((m) => ({ ...m, tokens: 0, input: 0, output: 0 }));
85735
85742
  };
85736
85743
  const flushDraft = () => {
@@ -85968,6 +85975,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
85968
85975
  }
85969
85976
  case "tool_result": {
85970
85977
  lastOutRef.current = { name: ev.name, content: ev.content || "" };
85978
+ if (ev.ok && (ev.name === "write_file" || ev.name === "edit_file")) wroteRef.current = true;
85971
85979
  const more = (ev.lines || 0) > 1 ? ` (+${ev.lines - 1} lines \xB7 ctrl+o expands)` : "";
85972
85980
  append({ kind: "tool_result", text: `${ev.summary || "(no output)"}${more}`, isError: !ev.ok });
85973
85981
  if (!ev.ok && ev.diagnostics && ev.diagnostics.length) {
@@ -86027,6 +86035,10 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86027
86035
  case "reflection":
86028
86036
  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 || "" }]);
86029
86037
  break;
86038
+ case "acceptance":
86039
+ setOffer(false);
86040
+ append({ kind: "info", text: ev.polarity > 0 ? "accepted" : "rejected" });
86041
+ break;
86030
86042
  case "reflection_closed":
86031
86043
  setReflections((rs) => rs.filter((r) => r.id !== ev.id));
86032
86044
  if (ev.vote !== "dismiss") append({ kind: "info", text: ev.vote === "up" ? "marked true" : "marked false" });
@@ -86115,6 +86127,8 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86115
86127
  const dur = turnT0.current ? fmtDur((Date.now() - turnT0.current) / 1e3) : fmtDur(ev.elapsed_s);
86116
86128
  turnT0.current = null;
86117
86129
  append({ kind: "turn", text: `${dur} \xB7 ${plural(ev.turns, "step")} \xB7 ${fmtCost2(ev.cost_usd)} session${firstResp(ev)}` + (ev.stop_reason !== "done" && !String(ev.stop_reason).startsWith("paused") ? ` \xB7 stopped: ${ev.stop_reason}` : "") });
86130
+ if (wroteRef.current) setOffer(true);
86131
+ wroteRef.current = false;
86118
86132
  setPhaseBoth("idle");
86119
86133
  setStatus("");
86120
86134
  break;
@@ -86258,13 +86272,13 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86258
86272
  }
86259
86273
  return;
86260
86274
  }
86261
- const vote = input === "1" ? "up" : input === "2" ? "down" : key.return || key.escape ? "dismiss" : null;
86262
- if (vote === "down") {
86275
+ const vote2 = input === "1" ? "up" : input === "2" ? "down" : key.return || key.escape ? "dismiss" : null;
86276
+ if (vote2 === "down") {
86263
86277
  setWhy(reflection.id);
86264
86278
  return;
86265
86279
  }
86266
- if (vote) {
86267
- closeReflection(reflection.id, vote);
86280
+ if (vote2) {
86281
+ closeReflection(reflection.id, vote2);
86268
86282
  return;
86269
86283
  }
86270
86284
  }
@@ -86316,6 +86330,18 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86316
86330
  answerStep("");
86317
86331
  return;
86318
86332
  }
86333
+ if (step.optional) {
86334
+ answerStep("");
86335
+ return;
86336
+ }
86337
+ if (harnessQ && key.escape) {
86338
+ setQuestion(null);
86339
+ setQStep(0);
86340
+ setQAnswers({});
86341
+ setQPicks([]);
86342
+ setQCursor(0);
86343
+ return;
86344
+ }
86319
86345
  return;
86320
86346
  }
86321
86347
  }
@@ -86422,7 +86448,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86422
86448
  const answerStep = (text) => {
86423
86449
  if (!question || !step) return;
86424
86450
  setValue("");
86425
- append({ kind: "you", text: step.secret ? "(kept to yourself)" : text || `(the default: ${step.default})` });
86451
+ append({ kind: "you", text: step.secret ? "(kept to yourself)" : text || (step.default ? `(the default: ${step.default})` : "(nothing)") });
86426
86452
  const answers = { ...qAnswers, [step.id]: text };
86427
86453
  if (qStep + 1 < steps.length) {
86428
86454
  setQAnswers(answers);
@@ -86438,6 +86464,10 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86438
86464
  setQCursor(0);
86439
86465
  engine2.send({ cmd: "answer", id: question.id, answers });
86440
86466
  };
86467
+ const vote = (polarity, why2 = "") => {
86468
+ engine2.send({ cmd: polarity > 0 ? "accept" : "reject", ...why2 ? { why: why2 } : {} });
86469
+ setOffer(false);
86470
+ };
86441
86471
  const runCommand = (line) => {
86442
86472
  const [name, ...rest] = line.split(/\s+/);
86443
86473
  const arg = rest.join(" ").trim();
@@ -86496,6 +86526,12 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86496
86526
  if (hello?.mcp === void 0) append({ kind: "warn", text: "this version of hum does not say what is mounted; update hum (/stop, then hum)" });
86497
86527
  else engine2.send({ cmd: "mcp" });
86498
86528
  break;
86529
+ case "/accept":
86530
+ vote(1, arg);
86531
+ break;
86532
+ case "/reject":
86533
+ vote(-1, arg);
86534
+ break;
86499
86535
  case "/hooks":
86500
86536
  engine2.send({ cmd: "hooks" });
86501
86537
  break;
@@ -86521,8 +86557,8 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86521
86557
  break;
86522
86558
  }
86523
86559
  };
86524
- const closeReflection = (id, vote, reason = "") => {
86525
- engine2.send({ cmd: "reflect_vote", id, vote, ...reason ? { why: reason } : {} });
86560
+ const closeReflection = (id, vote2, reason = "") => {
86561
+ engine2.send({ cmd: "reflect_vote", id, vote: vote2, ...reason ? { why: reason } : {} });
86526
86562
  setReflections((rs) => rs.filter((r) => r.id !== id));
86527
86563
  setWhy((w) => w === id ? null : w);
86528
86564
  setValue("");
@@ -86548,10 +86584,17 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86548
86584
  decide("reject", text);
86549
86585
  return;
86550
86586
  }
86551
- if (question && step && !/^\/(quit|exit|stop)\b/.test(text)) {
86587
+ if (question && step && !harnessQ && !/^\/(quit|exit|stop)\b/.test(text)) {
86552
86588
  answerStep(text);
86553
86589
  return;
86554
86590
  }
86591
+ if (harnessQ) {
86592
+ setQuestion(null);
86593
+ setQStep(0);
86594
+ setQAnswers({});
86595
+ setQPicks([]);
86596
+ setQCursor(0);
86597
+ }
86555
86598
  if (reflection) closeReflection(reflection.id, "dismiss");
86556
86599
  if (text.startsWith("/")) {
86557
86600
  runCommand(text);
@@ -86573,7 +86616,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86573
86616
  setPhaseBoth("busy");
86574
86617
  }
86575
86618
  };
86576
- const statusLine = phase === "connecting" ? "starting \u2026" : `${modelRef.current || ""} \xB7 ${fmtCost2(spend)}` + (ctxPct >= 10 ? ` \xB7 ctx ${ctxPct}%` : "") + (gate === "approve" ? " \xB7 approvals on" : "") + (needYou ? ` \xB7 ${needYou} need you` : "") + (ctrlc ? " \xB7 ctrl+c again to quit" : " \xB7 / for commands");
86619
+ const statusLine = phase === "connecting" ? "starting \u2026" : `${modelRef.current || ""} \xB7 ${fmtCost2(spend)}` + (ctxPct >= 10 ? ` \xB7 ctx ${ctxPct}%` : "") + (gate === "approve" ? " \xB7 approvals on" : "") + (needYou ? ` \xB7 ${needYou} need you` : "") + (offer ? " \xB7 /accept \xB7 /reject" : "") + (ctrlc ? " \xB7 ctrl+c again to quit" : " \xB7 / for commands");
86577
86620
  const spinnerLabel = phase === "connecting" ? " starting \u2026" : ` ${status || "working"}${elapsed >= 2 ? ` \xB7 ${fmtDur(elapsed)}` : ""}` + (thinkChars.current > 4e3 ? ` \xB7 ${(thinkChars.current / 1e3).toFixed(0)}k thinking` : "");
86578
86621
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", children: [
86579
86622
  /* @__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: [
@@ -86774,6 +86817,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
86774
86817
  stepLabels.length ? step.multi ? "a number ticks \xB7 space ticks the one marked \xB7 " : step.graded ? "a number marks \xB7 words after it if you like \xB7 " : "a number picks \xB7 " : "",
86775
86818
  step.graded ? "" : "type an answer",
86776
86819
  step.default ? " \xB7 enter takes the default" : "",
86820
+ !step.default && step.optional ? " \xB7 enter says nothing" : "",
86777
86821
  step.multi && stepLabels.length ? " \xB7 enter takes what is ticked" : "",
86778
86822
  step.secret ? " \xB7 it is not shown and not recorded" : ""
86779
86823
  ] })
@@ -87079,7 +87123,7 @@ init_update();
87079
87123
  init_install();
87080
87124
  var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
87081
87125
  import { spawnSync as spawnSync5 } from "node:child_process";
87082
- var MINE2 = true ? "0.1.50" : "0.0.0";
87126
+ var MINE2 = true ? "0.1.52" : "0.0.0";
87083
87127
  var layout = installLayout();
87084
87128
  function completeInstall() {
87085
87129
  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.50",
3
+ "version": "0.1.52",
4
4
  "description": "Hum: a self-improving coding agent for your terminal.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",