nexrall-code 0.5.205 → 0.5.206

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/index.js +76 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -30921,6 +30921,7 @@ var require_askUser = __commonJS({
30921
30921
  properties: {
30922
30922
  question: { type: "string", description: "The full question, ending with a question mark." },
30923
30923
  header: { type: "string", description: "Very short label (max ~12 chars)." },
30924
+ multiSelect: { type: "boolean", description: "true when the user may pick MORE than one option (default: pick one)." },
30924
30925
  options: {
30925
30926
  type: "array",
30926
30927
  minItems: 2,
@@ -30960,7 +30961,12 @@ var require_askUser = __commonJS({
30960
30961
  const d = x2.description;
30961
30962
  options.push({ label, description: typeof d === "string" && d.trim() ? d.trim() : void 0 });
30962
30963
  }
30963
- out.push({ question, header: typeof o.header === "string" ? o.header.trim().slice(0, 14) : void 0, options });
30964
+ out.push({
30965
+ question,
30966
+ header: typeof o.header === "string" ? o.header.trim().slice(0, 14) : void 0,
30967
+ multiSelect: o.multiSelect === true ? true : void 0,
30968
+ options
30969
+ });
30964
30970
  }
30965
30971
  return out;
30966
30972
  }
@@ -30974,7 +30980,19 @@ var require_askUser = __commonJS({
30974
30980
  for (let i2 = 0; i2 < qs.length; i2++) {
30975
30981
  const a = answers[i2];
30976
30982
  const q = qs[i2];
30977
- if ("text" in a) {
30983
+ if ("indices" in a) {
30984
+ const labels = [];
30985
+ for (const ix of Array.isArray(a.indices) ? a.indices : []) {
30986
+ const opt = q.options[ix];
30987
+ if (opt && !labels.includes(opt.label))
30988
+ labels.push(opt.label);
30989
+ }
30990
+ const t2 = String(a.text ?? "").trim();
30991
+ if (!labels.length && !t2)
30992
+ return dismissed;
30993
+ const shown = labels.map((l) => `"${l}"`).join(", ");
30994
+ parts.push(`"${q.question}" = ${shown}${t2 ? `${shown ? " + " : ""}"${t2}" (user's own answer)` : ""}`);
30995
+ } else if ("text" in a) {
30978
30996
  const t2 = String(a.text ?? "").trim();
30979
30997
  if (!t2)
30980
30998
  return dismissed;
@@ -82673,6 +82691,7 @@ var ASK_USER_TOOL_SCHEMAS = [
82673
82691
  properties: {
82674
82692
  question: { type: "string", description: "The full question, ending with a question mark." },
82675
82693
  header: { type: "string", description: "Very short label (max ~12 chars)." },
82694
+ multiSelect: { type: "boolean", description: "true when the user may pick MORE than one option (default: pick one)." },
82676
82695
  options: {
82677
82696
  type: "array",
82678
82697
  minItems: 2,
@@ -82713,10 +82732,49 @@ function parseQuestions(input) {
82713
82732
  const d = x2.description;
82714
82733
  options.push({ label, description: typeof d === "string" && d.trim() ? d.trim() : void 0 });
82715
82734
  }
82716
- out.push({ question, header: typeof o.header === "string" ? o.header.trim().slice(0, 14) : void 0, options });
82735
+ out.push({
82736
+ question,
82737
+ header: typeof o.header === "string" ? o.header.trim().slice(0, 14) : void 0,
82738
+ multiSelect: o.multiSelect === true ? true : void 0,
82739
+ options
82740
+ });
82717
82741
  }
82718
82742
  return out;
82719
82743
  }
82744
+ async function askMulti(q, io) {
82745
+ const chosen = /* @__PURE__ */ new Set();
82746
+ let typed = "";
82747
+ let at = 0;
82748
+ for (; ; ) {
82749
+ const n = q.options.length;
82750
+ const options = [
82751
+ ...q.options.map((o, i2) => ({
82752
+ key: String(i2 + 1),
82753
+ label: `${chosen.has(i2) ? "[x]" : "[ ]"} ${o.description ? `${o.label} \u2014 ${o.description}` : o.label}`
82754
+ })),
82755
+ { key: String(n + 1), label: `${typed ? "[x]" : "[ ]"} Other (type your own answer)${typed ? `: ${typed}` : ""}` },
82756
+ { key: String(n + 2), label: chosen.size || typed ? "Done \u2014 submit these" : "Done (pick at least one first)" }
82757
+ ];
82758
+ const title = `${q.header ? `${q.header}: ` : ""}${q.question}`;
82759
+ const pick = await io.choose({ title, detail: "Select all that apply \u2014 toggle with Enter / its number", options, risk: "low", defaultIndex: at, replacesInput: true });
82760
+ if (pick < 0 || pick > n + 1)
82761
+ return null;
82762
+ at = pick;
82763
+ if (pick < n) {
82764
+ if (chosen.has(pick))
82765
+ chosen.delete(pick);
82766
+ else
82767
+ chosen.add(pick);
82768
+ } else if (pick === n) {
82769
+ typed = (await io.line(" Your answer: ")).trim();
82770
+ } else if (chosen.size || typed) {
82771
+ break;
82772
+ }
82773
+ }
82774
+ const labels = [...chosen].sort((a, b) => a - b).map((i2) => `"${q.options[i2].label}"`);
82775
+ const own = typed ? `"${typed}" (user's own answer)` : "";
82776
+ return `"${q.question}" = ${[...labels, own].filter(Boolean).join(", ")}`;
82777
+ }
82720
82778
  async function executeAskUserTool(name, input, io) {
82721
82779
  if (name !== ASK_USER_TOOL_NAME)
82722
82780
  return null;
@@ -82728,7 +82786,17 @@ async function executeAskUserTool(name, input, io) {
82728
82786
  if (typeof qs === "string")
82729
82787
  return { error: qs };
82730
82788
  const answers = [];
82789
+ const dismissedResult = {
82790
+ error: "The user dismissed the question without answering. Do not assume an answer; proceed on your best judgement or stop and say what you need."
82791
+ };
82731
82792
  for (const q of qs) {
82793
+ if (q.multiSelect) {
82794
+ const r2 = await askMulti(q, io);
82795
+ if (r2 === null)
82796
+ return dismissedResult;
82797
+ answers.push(r2);
82798
+ continue;
82799
+ }
82732
82800
  const options = [
82733
82801
  ...q.options.map((o, i2) => ({
82734
82802
  key: String(i2 + 1),
@@ -82736,19 +82804,16 @@ async function executeAskUserTool(name, input, io) {
82736
82804
  })),
82737
82805
  { key: String(q.options.length + 1), label: "Other (type your own answer)" }
82738
82806
  ];
82739
- const pick = await io.choose({ title: q.header ? `${q.header}: ${q.question}` : q.question, options, risk: "low" });
82740
- const dismissed = {
82741
- error: "The user dismissed the question without answering. Do not assume an answer; proceed on your best judgement or stop and say what you need."
82742
- };
82807
+ const pick = await io.choose({ title: q.header ? `${q.header}: ${q.question}` : q.question, options, risk: "low", replacesInput: true });
82743
82808
  if (pick === q.options.length) {
82744
82809
  const typed = (await io.line(" Your answer: ")).trim();
82745
82810
  if (!typed)
82746
- return dismissed;
82811
+ return dismissedResult;
82747
82812
  answers.push(`"${q.question}" = "${typed}" (user's own answer)`);
82748
82813
  continue;
82749
82814
  }
82750
82815
  if (pick < 0 || pick > q.options.length)
82751
- return dismissed;
82816
+ return dismissedResult;
82752
82817
  answers.push(`"${q.question}" = "${q.options[pick].label}"`);
82753
82818
  }
82754
82819
  return { output: "User answered: " + answers.join("; ") };
@@ -100187,6 +100252,7 @@ function choiceView(spec, sel, maxRows) {
100187
100252
  });
100188
100253
  const range = size < n ? `rows ${start + 1}-${start + size} of ${n} \xB7 ` : "";
100189
100254
  return {
100255
+ replacesInput: spec.replacesInput === true,
100190
100256
  title: spec.title,
100191
100257
  detail: spec.detail,
100192
100258
  risk: spec.risk,
@@ -102012,7 +102078,7 @@ var App2 = ({ onReady }) => {
102012
102078
  borderRight: false,
102013
102079
  borderDimColor: colorsOn
102014
102080
  }
102015
- ), /* @__PURE__ */ import_react36.default.createElement(Box_default, { ref: inputRowRef }, /* @__PURE__ */ import_react36.default.createElement(Text, { wrap: "hard" }, /* @__PURE__ */ import_react36.default.createElement(Text, null, promptFor(shownPrompt)), vsel ? /* @__PURE__ */ import_react36.default.createElement(import_react36.default.Fragment, null, /* @__PURE__ */ import_react36.default.createElement(Text, null, inputView.text.slice(0, vsel.from)), /* @__PURE__ */ import_react36.default.createElement(Text, { inverse: true }, inputView.text.slice(vsel.from, vsel.to)), /* @__PURE__ */ import_react36.default.createElement(Text, null, inputView.text.slice(vsel.to))) : /* @__PURE__ */ import_react36.default.createElement(import_react36.default.Fragment, null, /* @__PURE__ */ import_react36.default.createElement(Text, null, slices.before), /* @__PURE__ */ import_react36.default.createElement(Text, { inverse: true }, slices.atCursor), /* @__PURE__ */ import_react36.default.createElement(Text, null, slices.after), suggestion && line === "" && !isAxMode() ? /* @__PURE__ */ import_react36.default.createElement(Text, { dimColor: colorsOn }, suggestion) : null))), isAxMode() ? /* @__PURE__ */ import_react36.default.createElement(Box_default, { height: 1 }) : /* @__PURE__ */ import_react36.default.createElement(
102081
+ ), choiceVm?.replacesInput ? null : /* @__PURE__ */ import_react36.default.createElement(Box_default, { ref: inputRowRef }, /* @__PURE__ */ import_react36.default.createElement(Text, { wrap: "hard" }, /* @__PURE__ */ import_react36.default.createElement(Text, null, promptFor(shownPrompt)), vsel ? /* @__PURE__ */ import_react36.default.createElement(import_react36.default.Fragment, null, /* @__PURE__ */ import_react36.default.createElement(Text, null, inputView.text.slice(0, vsel.from)), /* @__PURE__ */ import_react36.default.createElement(Text, { inverse: true }, inputView.text.slice(vsel.from, vsel.to)), /* @__PURE__ */ import_react36.default.createElement(Text, null, inputView.text.slice(vsel.to))) : /* @__PURE__ */ import_react36.default.createElement(import_react36.default.Fragment, null, /* @__PURE__ */ import_react36.default.createElement(Text, null, slices.before), /* @__PURE__ */ import_react36.default.createElement(Text, { inverse: true }, slices.atCursor), /* @__PURE__ */ import_react36.default.createElement(Text, null, slices.after), suggestion && line === "" && !isAxMode() ? /* @__PURE__ */ import_react36.default.createElement(Text, { dimColor: colorsOn }, suggestion) : null))), isAxMode() ? /* @__PURE__ */ import_react36.default.createElement(Box_default, { height: 1 }) : /* @__PURE__ */ import_react36.default.createElement(
102016
102082
  Box_default,
102017
102083
  {
102018
102084
  borderStyle: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexrall-code",
3
- "version": "0.5.205",
3
+ "version": "0.5.206",
4
4
  "description": "Nexrall Code \u2014 AI coding assistant for your terminal (headless agent for scripts, CI and automation)",
5
5
  "keywords": [
6
6
  "ai",