@metaphi-ai/hum 0.1.24 → 0.1.26

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 +179 -40
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -83714,7 +83714,9 @@ var MultilineInput = (0, import_react23.forwardRef)(function MultilineInput2({
83714
83714
  focus = true,
83715
83715
  placeholder = "",
83716
83716
  history = [],
83717
- navActive = true
83717
+ navActive = true,
83718
+ mask = false,
83719
+ swallow = null
83718
83720
  }, ref) {
83719
83721
  const [cursor, setCursor] = (0, import_react23.useState)(value.length);
83720
83722
  const hist = (0, import_react23.useRef)({ index: null, stash: "" });
@@ -83815,24 +83817,26 @@ var MultilineInput = (0, import_react23.forwardRef)(function MultilineInput2({
83815
83817
  return;
83816
83818
  }
83817
83819
  if (key.escape || key.tab || key.meta) return;
83820
+ if (swallow && swallow(input, key)) return;
83818
83821
  const text = [...input.replace(/\r\n?/g, "\n")].filter((ch) => ch === "\n" || ch === " " || ch >= " ").join("");
83819
83822
  if (!text) return;
83820
83823
  hist.current.index = null;
83821
83824
  set(value.slice(0, c2) + text + value.slice(c2), c2 + text.length);
83822
83825
  }, { isActive: focus });
83823
83826
  if (!focus) {
83824
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: value.length > 0 ? value : source_default.dim(placeholder) });
83827
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: value.length > 0 ? mask ? "\u2022".repeat(value.length) : value : source_default.dim(placeholder) });
83825
83828
  }
83826
83829
  const c = clamp(cursor, value.length);
83830
+ const value_ = mask ? "\u2022".repeat(value.length) : value;
83827
83831
  let shown;
83828
83832
  if (value.length === 0) {
83829
83833
  shown = placeholder ? source_default.inverse(placeholder.charAt(0) || " ") + source_default.dim(placeholder.slice(1)) : source_default.inverse(" ");
83830
83834
  } else if (c >= value.length) {
83831
- shown = value + source_default.inverse(" ");
83832
- } else if (value[c] === "\n") {
83833
- shown = value.slice(0, c) + source_default.inverse(" ") + value.slice(c);
83835
+ shown = value_ + source_default.inverse(" ");
83836
+ } else if (value_[c] === "\n") {
83837
+ shown = value_.slice(0, c) + source_default.inverse(" ") + value_.slice(c);
83834
83838
  } else {
83835
- shown = value.slice(0, c) + source_default.inverse(value[c]) + value.slice(c + 1);
83839
+ shown = value_.slice(0, c) + source_default.inverse(value_[c]) + value_.slice(c + 1);
83836
83840
  }
83837
83841
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: shown });
83838
83842
  });
@@ -83907,11 +83911,12 @@ var COMMANDS = [
83907
83911
  { name: "/mcp", desc: "the MCP servers in this session \u2014 what each mounted, and any that did not" },
83908
83912
  { name: "/tools", desc: "the tools the model has, and the sandbox they run in" },
83909
83913
  { name: "/hooks", desc: "the lifecycle hooks in scope (~/.hum/hooks.json, <repo>/.hum/hooks.json; Claude Code and Codex hook files too)" },
83914
+ { name: "/permissions", desc: "the rules in force here \u2014 what runs without asking, what is refused, and where each rule came from" },
83910
83915
  { name: "/help", desc: "keys and commands" },
83911
83916
  { name: "/quit", desc: "leave; the session keeps running (hum resume brings you back)" },
83912
- { name: "/stop", desc: "end this session's engine (the record is saved)" }
83917
+ { name: "/stop", desc: "end this session for good (the record is saved)" }
83913
83918
  ];
83914
- var HELP = "!cmd runs a command as you \xB7 esc interrupts the model (what it had is kept) \xB7 type while it works to steer \xB7 edit files in your editor any time (recorded as your turn) \xB7 ctrl+o shows the full output of the last tool result \xB7 ctrl+v pastes a screenshot from the clipboard \xB7 @path.png or /image <path> attaches an image file \xB7 commands run in a sandbox (writes in the working directory, no network); leaving it asks you first (enter approves, a typed reason rejects) \xB7 /approve makes every change and command wait for you \xB7 /mcp lists the tool servers \xB7 /resume picks a past session (a running one attaches) \xB7 /compact restarts the context from a summary \xB7 ctrl+c twice leaves and the session keeps running (`hum resume` brings you back) \xB7 /stop ends it";
83919
+ var HELP = "!cmd runs a command as you \xB7 esc interrupts the model (what it had is kept) \xB7 type while it works to steer \xB7 edit files in your editor any time (recorded as your turn) \xB7 ctrl+o shows the full output of the last tool result \xB7 ctrl+v pastes a screenshot from the clipboard \xB7 @path.png or /image <path> attaches an image file \xB7 commands run in a sandbox (writes in the working directory, no network); leaving it asks you first (enter approves, a typed reason rejects) \xB7 /approve makes every change and command wait for you; at the panel, a allows that shape for the session and p writes it into the project \xB7 /permissions lists the rules in force \xB7 /mcp lists the tool servers \xB7 /resume picks a past session (a running one attaches) \xB7 /compact restarts the context from a summary \xB7 ctrl+c twice leaves and the session keeps running (`hum resume` brings you back) \xB7 /stop ends it";
83915
83920
  var DIFF_TAIL_LINES = 20;
83916
83921
  var OUTPUT_MAX_LINES = 200;
83917
83922
  var ERR_TAIL_LINES = 5;
@@ -83935,6 +83940,10 @@ function App2({ engine: engine2, task, resume, images = [] }) {
83935
83940
  const [picker, setPicker] = (0, import_react24.useState)(null);
83936
83941
  const [proposal, setProposal] = (0, import_react24.useState)(null);
83937
83942
  const [question, setQuestion] = (0, import_react24.useState)(null);
83943
+ const [qStep, setQStep] = (0, import_react24.useState)(0);
83944
+ const [qAnswers, setQAnswers] = (0, import_react24.useState)({});
83945
+ const [qPicks, setQPicks] = (0, import_react24.useState)([]);
83946
+ const [qCursor, setQCursor] = (0, import_react24.useState)(0);
83938
83947
  const [gate, setGate] = (0, import_react24.useState)("off");
83939
83948
  const [paused, setPaused] = (0, import_react24.useState)(false);
83940
83949
  const attachRef = (0, import_react24.useRef)([]);
@@ -83951,6 +83960,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
83951
83960
  const modelRef = (0, import_react24.useRef)("");
83952
83961
  const lastOutRef = (0, import_react24.useRef)(null);
83953
83962
  const helloRef = (0, import_react24.useRef)(false);
83963
+ const startedRef = (0, import_react24.useRef)(false);
83954
83964
  const preHello = (0, import_react24.useRef)([]);
83955
83965
  const [meter, setMeter] = (0, import_react24.useState)({ tokens: 0, cap: 0, input: 0, output: 0 });
83956
83966
  const setPhaseBoth = (p) => {
@@ -83958,6 +83968,10 @@ function App2({ engine: engine2, task, resume, images = [] }) {
83958
83968
  setPhase(p);
83959
83969
  };
83960
83970
  const append = (item) => setItems((prev) => [...prev, { id: nextId.current++, ...item }]);
83971
+ 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 }] : [];
83972
+ const step = steps.length ? steps[Math.min(qStep, steps.length - 1)] : null;
83973
+ const stepOptions = step ? (step.options || []).map((o) => typeof o === "string" ? { label: o } : o) : [];
83974
+ const stepLabels = stepOptions.map((o) => o.label);
83961
83975
  const menu = value.trimStart().startsWith("/") && !value.includes(" ") ? COMMANDS.filter((c) => c.name.startsWith(value.trim())) : [];
83962
83976
  const ctxPct = meter.cap > 0 && meter.tokens > 0 ? Math.round(meter.tokens / meter.cap * 100) : 0;
83963
83977
  (0, import_react24.useEffect)(() => {
@@ -83976,6 +83990,31 @@ function App2({ engine: engine2, task, resume, images = [] }) {
83976
83990
  thinkChars.current = 0;
83977
83991
  thinkT0.current = null;
83978
83992
  };
83993
+ const resetForSession = () => {
83994
+ setItems([]);
83995
+ setDraft("");
83996
+ draftRef.current = "";
83997
+ thoughtRef.current = null;
83998
+ setThinking("");
83999
+ thinkChars.current = 0;
84000
+ setProposal(null);
84001
+ setQuestion(null);
84002
+ setQStep(0);
84003
+ setQAnswers({});
84004
+ setQPicks([]);
84005
+ setQCursor(0);
84006
+ setPaused(false);
84007
+ setPicker(null);
84008
+ setSpend(0);
84009
+ setGoal(null);
84010
+ setSession(null);
84011
+ setStatus("");
84012
+ turnT0.current = null;
84013
+ toolsRef.current = {};
84014
+ lastOutRef.current = null;
84015
+ attachRef.current = [];
84016
+ setMeter((m) => ({ ...m, tokens: 0, input: 0, output: 0 }));
84017
+ };
83979
84018
  const flushDraft = () => {
83980
84019
  const d = draftRef.current.trim();
83981
84020
  draftRef.current = "";
@@ -84023,6 +84062,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84023
84062
  append({ kind: "agent_end", text: `agent ${ev.n} done \xB7 ${plural(ev.steps, "step")} \xB7 ${fmtCost(ev.cost_usd)}${ev.reason !== "done" ? ` \xB7 ${ev.reason}` : ""}` });
84024
84063
  break;
84025
84064
  case "hello": {
84065
+ if (helloRef.current) resetForSession();
84026
84066
  setHello(ev);
84027
84067
  helloRef.current = true;
84028
84068
  modelRef.current = ev.model;
@@ -84042,6 +84082,10 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84042
84082
  setStatus(ev.phase || "");
84043
84083
  turnT0.current = Date.now();
84044
84084
  } else setPhaseBoth("idle");
84085
+ }
84086
+ if (startedRef.current) break;
84087
+ startedRef.current = true;
84088
+ if (ev.session) {
84045
84089
  if (resume === "pick") engine2.send({ cmd: "sessions" });
84046
84090
  } else if (task) {
84047
84091
  if (images.length && !ev.images) append({ kind: "warn", text: "this version of hum does not take images; update hum" });
@@ -84166,6 +84210,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84166
84210
  setStatus(ev.phase || "");
84167
84211
  break;
84168
84212
  case "idle":
84213
+ setPhaseBoth("idle");
84169
84214
  setStatus("");
84170
84215
  break;
84171
84216
  case "reasoning_delta":
@@ -84213,16 +84258,30 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84213
84258
  case "proposal":
84214
84259
  foldThinking();
84215
84260
  flushDraft();
84216
- setProposal({ content: ev.content || "", calls: ev.calls || [] });
84261
+ setProposal({ content: ev.content || "", calls: ev.calls || [], remember: ev.remember || [], remember_text: ev.remember_text || "" });
84217
84262
  setStatus("waiting for your decision");
84218
84263
  break;
84219
84264
  case "question":
84220
84265
  foldThinking();
84221
84266
  flushDraft();
84222
- setQuestion({ id: ev.id, question: ev.question || "", options: ev.options || [], default: ev.default || null });
84267
+ setQuestion({
84268
+ id: ev.id,
84269
+ question: ev.question || "",
84270
+ options: ev.options || [],
84271
+ default: ev.default || null,
84272
+ questions: ev.questions || null
84273
+ });
84274
+ setQStep(0);
84275
+ setQAnswers({});
84276
+ setQPicks([]);
84277
+ setQCursor(0);
84223
84278
  break;
84224
84279
  case "question_closed":
84225
84280
  setQuestion(null);
84281
+ setQStep(0);
84282
+ setQAnswers({});
84283
+ setQPicks([]);
84284
+ setQCursor(0);
84226
84285
  append({ kind: "info", text: `answered: ${ev.answer}` });
84227
84286
  break;
84228
84287
  case "paused":
@@ -84316,7 +84375,7 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84316
84375
  (0, import_react24.useEffect)(() => {
84317
84376
  if (!hello) return void 0;
84318
84377
  let live = true;
84319
- updateNotice(true ? "0.1.24" : hello.version || "0.0.0").then((line) => {
84378
+ updateNotice(true ? "0.1.26" : hello.version || "0.0.0").then((line) => {
84320
84379
  if (live && line) append({ kind: "info", text: line });
84321
84380
  }).catch(() => {
84322
84381
  });
@@ -84369,15 +84428,49 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84369
84428
  decide("accept");
84370
84429
  return;
84371
84430
  }
84431
+ if (!value.trim() && (input === "a" || input === "p") && (proposal.remember || []).length) {
84432
+ decide("accept", "", input === "a" ? "session" : "project");
84433
+ return;
84434
+ }
84372
84435
  if (key.escape) {
84373
84436
  setProposal(null);
84374
84437
  engine2.send({ cmd: "interrupt" });
84375
84438
  return;
84376
84439
  }
84377
84440
  }
84378
- if (question && !picker) {
84441
+ if (question && step && !picker) {
84442
+ const n = stepLabels.length;
84443
+ if (step.multi && n) {
84444
+ if (key.upArrow) {
84445
+ setQCursor((c) => (c + n - 1) % n);
84446
+ return;
84447
+ }
84448
+ if (key.downArrow || key.tab) {
84449
+ setQCursor((c) => (c + 1) % n);
84450
+ return;
84451
+ }
84452
+ if (input === " " && !value.trim()) {
84453
+ togglePick(stepLabels[Math.min(qCursor, n - 1)]);
84454
+ return;
84455
+ }
84456
+ }
84457
+ if (!value.trim() && /^[1-9]$/.test(input) && Number(input) <= n) {
84458
+ const label = stepLabels[Number(input) - 1];
84459
+ if (step.multi) {
84460
+ setQCursor(Number(input) - 1);
84461
+ togglePick(label);
84462
+ } else answerStep(label);
84463
+ return;
84464
+ }
84379
84465
  if (key.return && !value.trim() || key.escape) {
84380
- if (question.default) engine2.send({ cmd: "answer", id: question.id, text: "" });
84466
+ if (step.multi && qPicks.length) {
84467
+ answerStep(qPicks.join(", "));
84468
+ return;
84469
+ }
84470
+ if (step.default) {
84471
+ answerStep("");
84472
+ return;
84473
+ }
84381
84474
  return;
84382
84475
  }
84383
84476
  }
@@ -84432,29 +84525,45 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84432
84525
  setMenuIndex(0);
84433
84526
  }, [value]);
84434
84527
  const attachTo = (port2) => {
84435
- setItems([]);
84436
- setDraft("");
84437
- draftRef.current = "";
84438
- thoughtRef.current = null;
84439
- setThinking("");
84440
- thinkChars.current = 0;
84441
- setProposal(null);
84442
- setPaused(false);
84443
- setSpend(0);
84528
+ resetForSession();
84444
84529
  helloRef.current = false;
84445
84530
  setPhaseBoth("connecting");
84446
- setStatus("");
84447
84531
  engine2.reconnect(port2).catch((e) => {
84448
84532
  append({ kind: "error", text: `could not attach: ${e.message}` });
84449
84533
  setPhaseBoth("idle");
84450
84534
  });
84451
84535
  };
84452
- const decide = (decision, note) => {
84536
+ const decide = (decision, note, remember) => {
84453
84537
  const p = proposal;
84454
84538
  setProposal(null);
84539
+ setValue("");
84455
84540
  const what = p && p.calls.length ? p.calls.map((c) => c.desc).join(" \xB7 ") : "the proposal";
84456
- append({ kind: "you", text: decision === "accept" ? `approved: ${what}` : `rejected: ${what}${note ? ` \u2014 ${note}` : ""}` });
84457
- engine2.send({ cmd: "decide", decision, note: note || "" });
84541
+ const also = remember ? ` \xB7 ${p.remember_text || "that shape"} allowed for ${remember === "session" ? "this session" : "this project"}` : "";
84542
+ append({ kind: "you", text: decision === "accept" ? `approved: ${what}${also}` : `rejected: ${what}${note ? ` \u2014 ${note}` : ""}` });
84543
+ engine2.send({ cmd: "decide", decision, note: note || "", ...remember ? { remember } : {} });
84544
+ };
84545
+ const togglePick = (label) => {
84546
+ setValue("");
84547
+ setQPicks((ps) => ps.includes(label) ? ps.filter((x) => x !== label) : [...ps, label]);
84548
+ };
84549
+ const answerStep = (text) => {
84550
+ if (!question || !step) return;
84551
+ setValue("");
84552
+ append({ kind: "you", text: step.secret ? "(kept to yourself)" : text || `(the default: ${step.default})` });
84553
+ const answers = { ...qAnswers, [step.id]: text };
84554
+ if (qStep + 1 < steps.length) {
84555
+ setQAnswers(answers);
84556
+ setQStep(qStep + 1);
84557
+ setQPicks([]);
84558
+ setQCursor(0);
84559
+ return;
84560
+ }
84561
+ setQuestion(null);
84562
+ setQStep(0);
84563
+ setQAnswers({});
84564
+ setQPicks([]);
84565
+ setQCursor(0);
84566
+ engine2.send({ cmd: "answer", id: question.id, answers });
84458
84567
  };
84459
84568
  const runCommand = (line) => {
84460
84569
  const [name, ...rest] = line.split(/\s+/);
@@ -84500,12 +84609,15 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84500
84609
  append({ kind: "info", text: `${(hello?.tools || []).join(", ")} \xB7 sandbox: ${hello?.sandbox || "none"}` });
84501
84610
  break;
84502
84611
  case "/mcp":
84503
- if (hello?.mcp === void 0) append({ kind: "warn", text: "this engine does not say what is mounted; update hum (/stop, then hum)" });
84612
+ if (hello?.mcp === void 0) append({ kind: "warn", text: "this version of hum does not say what is mounted; update hum (/stop, then hum)" });
84504
84613
  else engine2.send({ cmd: "mcp" });
84505
84614
  break;
84506
84615
  case "/hooks":
84507
84616
  engine2.send({ cmd: "hooks" });
84508
84617
  break;
84618
+ case "/permissions":
84619
+ engine2.send({ cmd: "permissions" });
84620
+ break;
84509
84621
  case "/continue":
84510
84622
  engine2.send({ cmd: "continue" });
84511
84623
  break;
@@ -84539,9 +84651,8 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84539
84651
  decide("reject", text);
84540
84652
  return;
84541
84653
  }
84542
- if (question && !/^\/(quit|exit|stop)\b/.test(text)) {
84543
- append({ kind: "you", text });
84544
- engine2.send({ cmd: "answer", id: question.id, text });
84654
+ if (question && step && !/^\/(quit|exit|stop)\b/.test(text)) {
84655
+ answerStep(text);
84545
84656
  return;
84546
84657
  }
84547
84658
  if (text.startsWith("/")) {
@@ -84695,23 +84806,35 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84695
84806
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: ACCENT, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(build_default, { type: "dots" }) }),
84696
84807
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: spinnerLabel })
84697
84808
  ] }),
84698
- question && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: ACCENT, paddingX: 1, marginTop: 1, children: [
84809
+ question && step && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: ACCENT, paddingX: 1, marginTop: 1, children: [
84810
+ step.header ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
84811
+ " ",
84812
+ step.header
84813
+ ] }) : null,
84699
84814
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
84700
84815
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: ACCENT, bold: true, children: "? " }),
84701
- question.question
84816
+ step.question,
84817
+ steps.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: ` (${qStep + 1} of ${steps.length})` }) : null
84702
84818
  ] }),
84703
- question.options.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
84704
- " ",
84819
+ stepOptions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { children: [
84820
+ step.multi ? i === Math.min(qCursor, stepLabels.length - 1) ? "\u203A " : " " : " ",
84821
+ step.multi ? qPicks.includes(o.label) ? "[x] " : "[ ] " : "",
84705
84822
  i + 1,
84706
84823
  ". ",
84707
- o,
84708
- question.default === o ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: " (default)" }) : null
84824
+ o.label,
84825
+ o.description ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
84826
+ " \u2014 ",
84827
+ o.description
84828
+ ] }) : null,
84829
+ step.default === o.label ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: " (default)" }) : null
84709
84830
  ] }, i)),
84710
84831
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
84711
84832
  " ",
84712
- question.options.length ? "a number picks \xB7 " : "",
84833
+ stepLabels.length ? step.multi ? "a number ticks \xB7 space ticks the one marked \xB7 " : "a number picks \xB7 " : "",
84713
84834
  "type an answer",
84714
- question.default ? " \xB7 enter takes the default" : ""
84835
+ step.default ? " \xB7 enter takes the default" : "",
84836
+ step.multi && stepLabels.length ? " \xB7 enter takes what is ticked" : "",
84837
+ step.secret ? " \xB7 it is not shown and not recorded" : ""
84715
84838
  ] })
84716
84839
  ] }),
84717
84840
  proposal && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: ACCENT, paddingX: 1, marginTop: 1, children: [
@@ -84722,6 +84845,14 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84722
84845
  " ",
84723
84846
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { dimColor: true, children: "\xB7 enter approves \xB7 type a reason to reject \xB7 esc stops" })
84724
84847
  ] }),
84848
+ (proposal.remember || []).length ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
84849
+ " a ",
84850
+ "allows ",
84851
+ proposal.remember_text,
84852
+ " for this session",
84853
+ " \xB7 p ",
84854
+ "for this project"
84855
+ ] }) : null,
84725
84856
  proposal.content ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { dimColor: true, children: [
84726
84857
  " ",
84727
84858
  proposal.content.split("\n")[0].slice(0, width - 4)
@@ -84842,7 +84973,15 @@ function App2({ engine: engine2, task, resume, images = [] }) {
84842
84973
  focus: phase !== "dead" && !picker,
84843
84974
  navActive: menu.length === 0,
84844
84975
  history: historyRef.current,
84845
- placeholder: question ? question.options.length ? "a number, or your answer" : "your answer" : proposal ? "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?"
84976
+ mask: !!(step && step.secret),
84977
+ swallow: (input, key) => {
84978
+ if (picker || value.trim()) return false;
84979
+ if (proposal && (input === "a" || input === "p") && (proposal.remember || []).length) return true;
84980
+ if (!question || !step) return false;
84981
+ if (/^[1-9]$/.test(input) && Number(input) <= stepLabels.length) return true;
84982
+ return !!(step.multi && stepLabels.length && input === " ");
84983
+ },
84984
+ 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?"
84846
84985
  }
84847
84986
  )
84848
84987
  ] }),
@@ -85135,7 +85274,7 @@ import { spawnSync as spawnSync3 } from "node:child_process";
85135
85274
  var ENGINE_COMMANDS = /* @__PURE__ */ new Set(["run", "login", "logout", "whoami", "model", "key", "sessions", "show", "sync", "skill", "ps", "stop", "hooks", "engine"]);
85136
85275
  var argv0 = process.argv.slice(2);
85137
85276
  if (argv0[0] === "--version" || argv0[0] === "-V") {
85138
- process.stdout.write(`hum ${true ? "0.1.24" : "0.0.0"}
85277
+ process.stdout.write(`hum ${true ? "0.1.26" : "0.0.0"}
85139
85278
  `);
85140
85279
  process.exit(0);
85141
85280
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaphi-ai/hum",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "description": "Hum (हम): a self-improving coding agent for your terminal.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",