@rotorsoft/gent 1.14.1 → 1.14.2

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.
package/dist/index.js CHANGED
@@ -2150,7 +2150,7 @@ import { homedir } from "os";
2150
2150
  // package.json
2151
2151
  var package_default = {
2152
2152
  name: "@rotorsoft/gent",
2153
- version: "1.14.1",
2153
+ version: "1.14.2",
2154
2154
  description: "AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs",
2155
2155
  keywords: [
2156
2156
  "cli",
@@ -3091,6 +3091,42 @@ function buildInputContent(label, value, cursorVisible) {
3091
3091
  const cursor = cursorVisible ? chalk4.cyan("_") : " ";
3092
3092
  return [label, "", chalk4.cyan("> ") + value + cursor];
3093
3093
  }
3094
+ function buildMultilineInputContent(label, value, cursorVisible, maxWidth) {
3095
+ const cursor = cursorVisible ? chalk4.cyan("_") : " ";
3096
+ const lines = [label, ""];
3097
+ if (value === "") {
3098
+ lines.push(chalk4.cyan(" ") + cursor);
3099
+ } else {
3100
+ const inputLines = value.split("\n");
3101
+ const contentWidth = maxWidth - 2;
3102
+ for (let i = 0; i < inputLines.length; i++) {
3103
+ const raw = inputLines[i];
3104
+ const wrapped = wrapLine(raw, contentWidth);
3105
+ for (let j = 0; j < wrapped.length; j++) {
3106
+ const isLastLine = i === inputLines.length - 1 && j === wrapped.length - 1;
3107
+ const text = wrapped[j] + (isLastLine ? cursor : "");
3108
+ lines.push(chalk4.cyan(" ") + text);
3109
+ }
3110
+ }
3111
+ }
3112
+ return lines;
3113
+ }
3114
+ function wrapLine(text, width) {
3115
+ if (width <= 0) return [text];
3116
+ if (text.length <= width) return [text];
3117
+ const result = [];
3118
+ let remaining = text;
3119
+ while (remaining.length > width) {
3120
+ let breakAt = remaining.lastIndexOf(" ", width);
3121
+ if (breakAt <= 0) breakAt = width;
3122
+ result.push(remaining.slice(0, breakAt));
3123
+ remaining = remaining.slice(breakAt).replace(/^ /, "");
3124
+ }
3125
+ if (remaining.length > 0 || result.length === 0) {
3126
+ result.push(remaining);
3127
+ }
3128
+ return result;
3129
+ }
3094
3130
  function termSize() {
3095
3131
  return {
3096
3132
  cols: process.stdout.columns || 80,
@@ -3155,6 +3191,8 @@ function readKey() {
3155
3191
  resolve({ name: "backspace", raw: data });
3156
3192
  } else if (data === " ") {
3157
3193
  resolve({ name: "tab", raw: data });
3194
+ } else if (data === "") {
3195
+ resolve({ name: "ctrl-s", raw: data });
3158
3196
  } else if (data.length === 1 && data.charCodeAt(0) >= 32) {
3159
3197
  resolve({ name: data, raw: data });
3160
3198
  } else {
@@ -3281,6 +3319,53 @@ async function showInput(opts) {
3281
3319
  }
3282
3320
  }
3283
3321
  }
3322
+ async function showMultilineInput(opts) {
3323
+ const w = modalWidth();
3324
+ let value = "";
3325
+ let cursorBlink = true;
3326
+ const contentWidth = w - 6;
3327
+ const render = () => {
3328
+ const content = buildMultilineInputContent(
3329
+ opts.label,
3330
+ value,
3331
+ cursorBlink,
3332
+ contentWidth
3333
+ );
3334
+ const footer = "Enter Newline Ctrl+S Submit Esc Cancel";
3335
+ const lines = buildModalFrame(opts.title, content, footer, w);
3336
+ renderOverlay(opts.dashboardLines, lines, w);
3337
+ };
3338
+ render();
3339
+ while (true) {
3340
+ const key = await readKey();
3341
+ switch (key.name) {
3342
+ case "ctrl-s":
3343
+ process.stdout.write(showCursor());
3344
+ return value.trim() || null;
3345
+ case "enter":
3346
+ value += "\n";
3347
+ cursorBlink = true;
3348
+ render();
3349
+ break;
3350
+ case "escape":
3351
+ process.stdout.write(showCursor());
3352
+ return null;
3353
+ case "backspace":
3354
+ if (value.length > 0) {
3355
+ value = value.slice(0, -1);
3356
+ }
3357
+ render();
3358
+ break;
3359
+ default:
3360
+ if (key.raw.length === 1 && key.raw.charCodeAt(0) >= 32) {
3361
+ value += key.raw;
3362
+ cursorBlink = true;
3363
+ render();
3364
+ }
3365
+ break;
3366
+ }
3367
+ }
3368
+ }
3284
3369
  function showStatus(title, message, dashboardLines) {
3285
3370
  const w = modalWidth();
3286
3371
  const content = [message];
@@ -3328,7 +3413,7 @@ async function executeAction(actionId, state, dashboardLines) {
3328
3413
  return switched ? CONTINUE : SKIP_REFRESH;
3329
3414
  }
3330
3415
  case "create": {
3331
- const description = await showInput({
3416
+ const description = await showMultilineInput({
3332
3417
  title: "New Ticket",
3333
3418
  label: "Describe the ticket:",
3334
3419
  dashboardLines