@pellux/goodvibes-agent 1.0.37 → 1.0.39

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.
@@ -817145,7 +817145,7 @@ var createStyledCell = (char, overrides = {}) => ({
817145
817145
  // src/version.ts
817146
817146
  import { readFileSync } from "fs";
817147
817147
  import { join } from "path";
817148
- var _version = "1.0.37";
817148
+ var _version = "1.0.39";
817149
817149
  try {
817150
817150
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
817151
817151
  _version = typeof pkg.version === "string" ? pkg.version : _version;
@@ -839197,6 +839197,12 @@ class Compositor {
839197
839197
  }
839198
839198
  }
839199
839199
  });
839200
+ for (let i4 = viewport.length;i4 < vHeight; i4 += 1) {
839201
+ const screenY = viewportStartY + i4;
839202
+ if (screenY >= height)
839203
+ break;
839204
+ newBuffer.blitLine(screenY, createEmptyLine(width));
839205
+ }
839200
839206
  if (hasPanel && panel.separator) {
839201
839207
  for (let i4 = viewport.length;i4 < vHeight; i4++) {
839202
839208
  const screenY = viewportStartY + i4;
@@ -906114,474 +906120,13 @@ function renderAutocompleteOverlay(autocomplete, width, viewportHeight = 24) {
906114
906120
  return lines;
906115
906121
  }
906116
906122
 
906117
- // src/renderer/onboarding/onboarding-wizard.ts
906118
- function modeLabel(mode) {
906119
- if (mode === "edit")
906120
- return "Edit existing";
906121
- if (mode === "reopen")
906122
- return "Reopen review";
906123
- return "New setup";
906124
- }
906125
- function changedScreensLabel(wizard) {
906126
- if (wizard.dirtyStepCount === 0)
906127
- return "no changes";
906128
- if (wizard.dirtyStepCount === 1)
906129
- return "1 changed screen";
906130
- return `${wizard.dirtyStepCount} changed screens`;
906131
- }
906132
- function stepGlyph(wizard, step, stepIndex) {
906133
- if (stepIndex === wizard.stepIndex) {
906134
- return { glyph: OVERLAY_GLYPHS.selected, fg: UI_TONES.state.active };
906135
- }
906136
- const total = wizard.getStepFieldCount(stepIndex);
906137
- const completed = wizard.getCompletedFieldCount(stepIndex);
906138
- if (wizard.isStepDirty(stepIndex)) {
906139
- return { glyph: "\u25C8", fg: UI_TONES.state.warn };
906140
- }
906141
- if (total > 0 && completed === total) {
906142
- return { glyph: "\u2713", fg: UI_TONES.state.good };
906143
- }
906144
- return { glyph: "\u2022", fg: UI_TONES.fg.muted };
906145
- }
906146
- function fieldBadgeTone(wizard, field) {
906147
- if (field.kind === "status")
906148
- return UI_TONES.state.info;
906149
- if (field.kind === "modelPicker")
906150
- return UI_TONES.state.info;
906151
- if (field.kind === "acknowledgement") {
906152
- const label = wizard.getFieldValueLabel(field);
906153
- return label === "Accepted" ? UI_TONES.state.good : label === "Pending" ? UI_TONES.state.warn : UI_TONES.fg.muted;
906154
- }
906155
- if (field.kind === "checklist") {
906156
- return wizard.getFieldValue(field) ? UI_TONES.state.good : UI_TONES.fg.muted;
906157
- }
906158
- if (field.kind === "radio")
906159
- return UI_TONES.state.active;
906160
- if (field.kind === "text" || field.kind === "masked") {
906161
- const missingRequired = wizard.getFieldValueLabel(field) === "Missing";
906162
- if (missingRequired)
906163
- return UI_TONES.state.warn;
906164
- if (field.kind === "masked")
906165
- return UI_TONES.state.warn;
906166
- }
906167
- return UI_TONES.fg.secondary;
906168
- }
906169
- function buildFieldRows(wizard, visibleFields, capacity) {
906170
- wizard.ensureSelectionVisible(visibleFields);
906171
- const fields = wizard.currentStep.fields;
906172
- const rows = [];
906173
- if (fields.length === 0 || capacity <= 0)
906174
- return rows;
906175
- const allRows = [];
906176
- fields.forEach((field, absoluteIndex) => {
906177
- const spacerRows = Math.max(0, field.spacerBeforeRows ?? 0);
906178
- for (let index = 0;index < spacerRows; index += 1) {
906179
- allRows.push({ kind: "empty" });
906180
- }
906181
- allRows.push({ kind: "field", field, absoluteIndex });
906182
- });
906183
- const selectedFieldIndex = wizard.getSelectedFieldIndex();
906184
- const selectedRowIndex = Math.max(0, allRows.findIndex((row) => row.kind === "field" && row.absoluteIndex === selectedFieldIndex));
906185
- const scrollFieldIndex = wizard.scrollOffsets[wizard.stepIndex] ?? 0;
906186
- const scrollRowIndex = allRows.findIndex((row) => row.kind === "field" && row.absoluteIndex === scrollFieldIndex);
906187
- const maxStart = Math.max(0, allRows.length - capacity);
906188
- let start2 = clamp3(scrollRowIndex >= 0 ? scrollRowIndex : 0, 0, maxStart);
906189
- if (selectedRowIndex < start2)
906190
- start2 = selectedRowIndex;
906191
- if (selectedRowIndex >= start2 + capacity)
906192
- start2 = selectedRowIndex - capacity + 1;
906193
- start2 = clamp3(start2, 0, maxStart);
906194
- if (capacity > 1 && start2 > 0 && selectedRowIndex === start2)
906195
- start2 = Math.max(0, start2 - 1);
906196
- if (capacity > 1 && start2 + capacity < allRows.length && selectedRowIndex === start2 + capacity - 1) {
906197
- start2 = Math.min(maxStart, start2 + 1);
906198
- }
906199
- rows.push(...allRows.slice(start2, start2 + capacity));
906200
- const firstVisibleRow = rows[0];
906201
- if (start2 > 0 && rows.length > 0 && !(firstVisibleRow?.kind === "field" && firstVisibleRow.absoluteIndex === selectedFieldIndex)) {
906202
- rows[0] = {
906203
- kind: "moreAbove",
906204
- text: `${OVERLAY_GLYPHS.moreAbove} ${start2} more above`
906205
- };
906206
- }
906207
- const hiddenBelow = Math.max(0, allRows.length - (start2 + capacity));
906208
- const lastVisibleRow = rows[rows.length - 1];
906209
- if (hiddenBelow > 0 && rows.length > 0 && !(lastVisibleRow?.kind === "field" && lastVisibleRow.absoluteIndex === selectedFieldIndex)) {
906210
- rows[rows.length - 1] = {
906211
- kind: "moreBelow",
906212
- text: `${OVERLAY_GLYPHS.moreBelow} ${hiddenBelow} more below`
906213
- };
906214
- }
906215
- while (rows.length < capacity)
906216
- rows.push({ kind: "empty" });
906217
- return rows.slice(0, capacity);
906218
- }
906219
- function fieldHint(wizard, field, selected) {
906220
- if (selected && wizard.isEditingTextField() && wizard.editingFieldId === field.id && (field.kind === "text" || field.kind === "masked")) {
906221
- const rawValue = wizard.editBuffer.length > 0 ? wizard.editBuffer : field.placeholder;
906222
- const editingValue = field.kind === "masked" && wizard.editBuffer.length > 0 ? "\u2022".repeat(Math.min(12, Math.max(4, wizard.editBuffer.length))) : formatEditingValue(rawValue, field.kind === "text" && field.multiline === true);
906223
- return `Editing: ${editingValue}\u2588`;
906224
- }
906225
- if (selected && field.kind === "modelPicker")
906226
- return `${field.hint} Press Enter to open picker.`;
906227
- if (selected && field.kind === "text") {
906228
- return field.multiline === true ? `${field.hint} Press Enter to edit; Ctrl-J inserts a new line.` : `${field.hint} Press Enter to edit inline.`;
906229
- }
906230
- if (selected && field.kind === "masked")
906231
- return `${field.hint} Press Enter to edit inline.`;
906232
- return field.hint;
906233
- }
906234
- function formatEditingValue(value, multiline) {
906235
- if (!multiline)
906236
- return value;
906237
- const lines = value.split(/\r?\n/);
906238
- if (lines.length <= 1)
906239
- return value;
906240
- const preview4 = lines[lines.length - 1] ?? "";
906241
- return `${preview4} (${lines.length} lines)`;
906242
- }
906243
- function fieldRowPrefix(wizard, field, selected) {
906244
- if (selected)
906245
- return `${OVERLAY_GLYPHS.selected} `;
906246
- if (wizard.isFieldDirty(field.id))
906247
- return "\u25C7 ";
906248
- if (field.kind === "checklist")
906249
- return wizard.getFieldValue(field) ? "\u2713 " : "\u25A1 ";
906250
- if (field.kind === "acknowledgement")
906251
- return wizard.getFieldValue(field) ? "\u2713 " : "\u25A1 ";
906252
- if (field.kind === "action")
906253
- return "\u25B6 ";
906254
- if (field.kind === "radio")
906255
- return "\u25C9 ";
906256
- return " ";
906257
- }
906258
- function selectedFieldText(wizard) {
906259
- if (wizard.isEditingTextField() && wizard.editingFieldId !== null) {
906260
- const editingField = wizard.getFieldById(wizard.editingFieldId);
906261
- if (editingField) {
906262
- return {
906263
- title: `Editing: ${editingField.label}`,
906264
- hint: fieldHint(wizard, editingField, true)
906265
- };
906266
- }
906267
- }
906268
- const field = wizard.getSelectedField();
906269
- if (!field) {
906270
- return {
906271
- title: "Selected: none",
906272
- hint: "No selectable row is active on this screen."
906273
- };
906274
- }
906275
- return {
906276
- title: `Selected: ${field.label} [${wizard.getFieldValueLabel(field)}]`,
906277
- hint: fieldHint(wizard, field, true)
906278
- };
906279
- }
906280
- function renderFieldRow(line2, wizard, fieldRow, startX, width) {
906281
- if (fieldRow.kind === "empty")
906282
- return;
906283
- if (fieldRow.kind === "moreAbove" || fieldRow.kind === "moreBelow") {
906284
- putOverlayText(line2, startX + 1, width - 2, truncateDisplay(fieldRow.text, width - 2), {
906285
- fg: UI_TONES.fg.muted,
906286
- bg: UI_TONES.bg.base,
906287
- dim: true
906288
- });
906289
- return;
906290
- }
906291
- const selected = fieldRow.absoluteIndex === wizard.getSelectedFieldIndex();
906292
- const field = fieldRow.field;
906293
- const fieldBg = selected ? DEFAULT_OVERLAY_PALETTE.selectedBg : UI_TONES.bg.base;
906294
- fillWidth(line2, startX, width, fieldBg);
906295
- const badge = truncateDisplay(`[${wizard.getFieldValueLabel(field)}]`, Math.max(8, Math.floor(width * 0.34)));
906296
- const badgeWidth = getDisplayWidth(badge);
906297
- const labelWidth = Math.max(0, width - badgeWidth - 4);
906298
- const prefix = fieldRowPrefix(wizard, field, selected);
906299
- putOverlayText(line2, startX + 1, labelWidth, truncateDisplay(`${prefix}${field.label}`, labelWidth), {
906300
- fg: UI_TONES.fg.primary,
906301
- bg: fieldBg,
906302
- bold: selected
906303
- });
906304
- putOverlayText(line2, startX + width - badgeWidth - 1, badgeWidth, badge, {
906305
- fg: fieldBadgeTone(wizard, field),
906306
- bg: fieldBg,
906307
- bold: selected
906308
- });
906309
- }
906310
- function footerText4(wizard) {
906311
- if (wizard.isEditingTextField()) {
906312
- return wizard.isEditingMultilineTextField() ? "[Enter] Save value [Ctrl-J] New line [Esc] Cancel edit [Backspace] Delete char [Del/Ctrl+U] Clear value" : "[Enter] Save value [Esc] Cancel edit [Backspace] Delete char [Del/Ctrl+U] Clear value";
906313
- }
906314
- return "[Enter] Toggle/open [Esc] Close [Tab/Shift+Tab] Screen [\u2191\u2193] Move [Del/Ctrl+U] Clear input";
906315
- }
906316
- function controlsText(wizard) {
906317
- if (wizard.isEditingTextField()) {
906318
- return wizard.isEditingMultilineTextField() ? "Controls: Enter saves, Ctrl-J inserts a line, Esc cancels, Backspace deletes, Del clears." : "Controls: Enter saves, Esc cancels, Backspace deletes, Del clears.";
906319
- }
906320
- return "Controls: Enter selects, Del clears, Tab moves.";
906321
- }
906322
- function renderWideLayout(wizard, width, viewportHeight, layout) {
906323
- const lines = [];
906324
- const bodyRows = getOnboardingWizardBodyRows(viewportHeight);
906325
- const visibleFields = getOnboardingWizardVisibleFieldCount(viewportHeight);
906326
- const currentStep = wizard.currentStep;
906327
- const borderFg = DEFAULT_OVERLAY_PALETTE.borderFg;
906328
- const headerBg = UI_TONES.bg.title;
906329
- const railBg = UI_TONES.bg.section;
906330
- const bodyBg = UI_TONES.bg.base;
906331
- const summaryBg = UI_TONES.bg.summary;
906332
- const innerLeft = layout.margin + 1;
906333
- const availableInner = layout.innerWidth - 2;
906334
- const leftWidthBase = layout.innerWidth >= 150 ? 32 : layout.innerWidth >= 108 ? 28 : 24;
906335
- const rightWidthBase = layout.innerWidth >= 150 ? 34 : layout.innerWidth >= 108 ? 32 : 24;
906336
- const minCenterWidth = layout.innerWidth >= 120 ? 48 : 40;
906337
- let leftWidth = Math.min(leftWidthBase, Math.max(20, availableInner - minCenterWidth - 12));
906338
- let rightWidth = Math.min(rightWidthBase, Math.max(22, availableInner - minCenterWidth - leftWidth));
906339
- let centerWidth = layout.innerWidth - leftWidth - rightWidth - 2;
906340
- if (centerWidth < minCenterWidth) {
906341
- const deficit = minCenterWidth - centerWidth;
906342
- const leftCut = Math.min(Math.max(0, leftWidth - 20), Math.ceil(deficit / 2));
906343
- leftWidth -= leftCut;
906344
- rightWidth -= Math.min(Math.max(0, rightWidth - 22), deficit - leftCut);
906345
- centerWidth = layout.innerWidth - leftWidth - rightWidth - 2;
906346
- }
906347
- const leftStart = innerLeft;
906348
- const leftSeparatorX = leftStart + leftWidth;
906349
- const centerStart = leftSeparatorX + 1;
906350
- const rightSeparatorX = centerStart + centerWidth;
906351
- const rightStart = rightSeparatorX + 1;
906352
- const descriptionLines = wrapText(currentStep.description, Math.max(18, centerWidth - 2)).slice(0, 2);
906353
- const summaryLines = [
906354
- currentStep.summaryTitle,
906355
- ...currentStep.summaryLines.slice(0, 2),
906356
- `Fields ${wizard.getCompletedFieldCount(wizard.stepIndex)}/${wizard.getStepFieldCount(wizard.stepIndex)} complete`,
906357
- changedScreensLabel(wizard)
906358
- ];
906359
- const selectedText = selectedFieldText(wizard);
906360
- const selectedHintLines = wrapText(selectedText.hint, Math.max(18, centerWidth - 2)).slice(0, 3);
906361
- const fieldStartRow = 8;
906362
- const fieldRows = buildFieldRows(wizard, visibleFields, Math.max(0, bodyRows - fieldStartRow));
906363
- const topLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, borderFg, headerBg);
906364
- putOverlayText(topLine, layout.margin + 2, layout.width - 4, "Onboarding Wizard", {
906365
- fg: UI_TONES.fg.primary,
906366
- bg: headerBg,
906367
- bold: true
906368
- });
906369
- const meta3 = `${modeLabel(wizard.mode)} ${wizard.stepIndex + 1}/${wizard.steps.length} ${changedScreensLabel(wizard)}`;
906370
- putOverlayText(topLine, Math.max(layout.margin + 2, layout.margin + layout.width - getDisplayWidth(meta3) - 3), layout.width - 4, meta3, {
906371
- fg: UI_TONES.fg.secondary,
906372
- bg: headerBg
906373
- });
906374
- lines.push(topLine);
906375
- const headerLine = createOverlayContentLine(width, layout, borderFg, headerBg);
906376
- fillWidth(headerLine, leftStart, leftWidth, railBg);
906377
- fillWidth(headerLine, centerStart, centerWidth, headerBg);
906378
- fillWidth(headerLine, rightStart, rightWidth, summaryBg);
906379
- drawVerticalRule(headerLine, leftSeparatorX, borderFg, headerBg);
906380
- drawVerticalRule(headerLine, rightSeparatorX, borderFg, headerBg);
906381
- putOverlayText(headerLine, leftStart + 1, leftWidth - 2, "Steps", {
906382
- fg: UI_TONES.fg.secondary,
906383
- bg: railBg,
906384
- bold: true
906385
- });
906386
- putOverlayText(headerLine, centerStart + 1, centerWidth - 2, truncateDisplay(currentStep.title, centerWidth - 2), {
906387
- fg: UI_TONES.state.active,
906388
- bg: headerBg,
906389
- bold: true
906390
- });
906391
- putOverlayText(headerLine, rightStart + 1, rightWidth - 2, "Summary", {
906392
- fg: UI_TONES.fg.secondary,
906393
- bg: summaryBg,
906394
- bold: true
906395
- });
906396
- lines.push(headerLine);
906397
- lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, borderFg, bodyBg));
906398
- for (let row = 0;row < bodyRows; row += 1) {
906399
- const line2 = createOverlayContentLine(width, layout, borderFg, bodyBg);
906400
- fillWidth(line2, leftStart, leftWidth, railBg);
906401
- fillWidth(line2, centerStart, centerWidth, bodyBg);
906402
- fillWidth(line2, rightStart, rightWidth, summaryBg);
906403
- drawVerticalRule(line2, leftSeparatorX, borderFg);
906404
- drawVerticalRule(line2, rightSeparatorX, borderFg);
906405
- if (row === 0) {
906406
- putOverlayText(line2, centerStart + 1, centerWidth - 2, truncateDisplay(currentStep.title, centerWidth - 2), {
906407
- fg: UI_TONES.fg.primary,
906408
- bg: bodyBg,
906409
- bold: true
906410
- });
906411
- } else if (row === 1) {
906412
- putOverlayText(line2, centerStart + 1, centerWidth - 2, descriptionLines[0] ?? "", {
906413
- fg: UI_TONES.fg.secondary,
906414
- bg: bodyBg
906415
- });
906416
- } else if (row === 2) {
906417
- putOverlayText(line2, centerStart + 1, centerWidth - 2, descriptionLines[1] ?? "", {
906418
- fg: UI_TONES.fg.secondary,
906419
- bg: bodyBg
906420
- });
906421
- } else if (row === 3) {
906422
- fillWidth(line2, centerStart, centerWidth, railBg);
906423
- putOverlayText(line2, centerStart + 1, centerWidth - 2, truncateDisplay(controlsText(wizard), centerWidth - 2), {
906424
- fg: UI_TONES.state.info,
906425
- bg: railBg
906426
- });
906427
- } else if (row === 4) {
906428
- fillWidth(line2, centerStart, centerWidth, DEFAULT_OVERLAY_PALETTE.selectedBg);
906429
- putOverlayText(line2, centerStart + 1, centerWidth - 2, truncateDisplay(`Focus: ${selectedText.title.replace(/^Selected: /, "")}`, centerWidth - 2), {
906430
- fg: UI_TONES.fg.primary,
906431
- bg: DEFAULT_OVERLAY_PALETTE.selectedBg,
906432
- bold: true
906433
- });
906434
- } else if (row >= 5 && row <= 7) {
906435
- fillWidth(line2, centerStart, centerWidth, DEFAULT_OVERLAY_PALETTE.selectedBg);
906436
- putOverlayText(line2, centerStart + 1, centerWidth - 2, selectedHintLines[row - 5] ?? "", {
906437
- fg: UI_TONES.fg.secondary,
906438
- bg: DEFAULT_OVERLAY_PALETTE.selectedBg
906439
- });
906440
- } else {
906441
- renderFieldRow(line2, wizard, fieldRows[row - fieldStartRow] ?? { kind: "empty" }, centerStart, centerWidth);
906442
- }
906443
- const step = wizard.steps[row] ?? null;
906444
- if (step) {
906445
- const stepState = stepGlyph(wizard, step, row);
906446
- const completion = `${wizard.getCompletedFieldCount(row)}/${wizard.getStepFieldCount(row)}`;
906447
- const completionWidth = getDisplayWidth(completion);
906448
- const stepLabelWidth = Math.max(0, leftWidth - completionWidth - 4);
906449
- putOverlayText(line2, leftStart + 1, stepLabelWidth, truncateDisplay(`${stepState.glyph} ${row + 1}. ${step.shortLabel}`, stepLabelWidth), {
906450
- fg: stepState.fg,
906451
- bg: railBg,
906452
- bold: row === wizard.stepIndex
906453
- });
906454
- putOverlayText(line2, Math.max(leftStart + 1, leftStart + leftWidth - completionWidth - 2), completionWidth, completion, {
906455
- fg: wizard.isStepDirty(row) ? UI_TONES.state.warn : UI_TONES.fg.muted,
906456
- bg: railBg
906457
- });
906458
- }
906459
- const summaryText = summaryLines[row];
906460
- if (summaryText) {
906461
- putOverlayText(line2, rightStart + 1, rightWidth - 2, truncateDisplay(summaryText, rightWidth - 2), {
906462
- fg: row === 0 ? UI_TONES.state.info : UI_TONES.fg.secondary,
906463
- bg: summaryBg,
906464
- bold: row === 0,
906465
- dim: row > 0
906466
- });
906467
- }
906468
- lines.push(line2);
906469
- }
906470
- lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, borderFg, bodyBg));
906471
- const footer = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, borderFg, headerBg);
906472
- putOverlayText(footer, layout.margin + 2, layout.width - 4, truncateDisplay(footerText4(wizard), layout.width - 4), {
906473
- fg: UI_TONES.fg.muted,
906474
- bg: headerBg,
906475
- dim: true
906476
- });
906477
- lines.push(footer);
906478
- return lines.slice(0, viewportHeight);
906479
- }
906480
- function renderCollapsedLayout(wizard, width, viewportHeight, layout) {
906481
- const lines = [];
906482
- const bodyRows = getOnboardingWizardBodyRows(viewportHeight);
906483
- const visibleFields = getOnboardingWizardVisibleFieldCount(viewportHeight);
906484
- const currentStep = wizard.currentStep;
906485
- const borderFg = DEFAULT_OVERLAY_PALETTE.borderFg;
906486
- const headerBg = UI_TONES.bg.title;
906487
- const bodyBg = UI_TONES.bg.base;
906488
- const innerStart = layout.margin + 1;
906489
- const innerWidth = layout.innerWidth;
906490
- const descriptionLines = wrapText(currentStep.description, Math.max(14, innerWidth - 2)).slice(0, 2);
906491
- const selectedText = selectedFieldText(wizard);
906492
- const selectedHintLines = wrapText(selectedText.hint, Math.max(14, innerWidth - 2)).slice(0, 3);
906493
- const fieldStartRow = 8;
906494
- const fieldRows = buildFieldRows(wizard, visibleFields, Math.max(0, bodyRows - fieldStartRow));
906495
- const topLine = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.topLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.topRight, borderFg, headerBg);
906496
- putOverlayText(topLine, layout.margin + 2, layout.width - 4, "Onboarding Wizard", {
906497
- fg: UI_TONES.fg.primary,
906498
- bg: headerBg,
906499
- bold: true
906500
- });
906501
- const meta3 = `${wizard.stepIndex + 1}/${wizard.steps.length} \u2022 ${changedScreensLabel(wizard)}`;
906502
- putOverlayText(topLine, Math.max(layout.margin + 2, layout.margin + layout.width - getDisplayWidth(meta3) - 3), layout.width - 4, meta3, {
906503
- fg: UI_TONES.fg.secondary,
906504
- bg: headerBg
906505
- });
906506
- lines.push(topLine);
906507
- const headerLine = createOverlayContentLine(width, layout, borderFg, headerBg);
906508
- fillWidth(headerLine, innerStart, innerWidth, headerBg);
906509
- putOverlayText(headerLine, innerStart + 1, innerWidth - 2, fitDisplay(`${modeLabel(wizard.mode)} \u2022 ${currentStep.shortLabel}`, innerWidth - 2), {
906510
- fg: UI_TONES.state.active,
906511
- bg: headerBg,
906512
- bold: true
906513
- });
906514
- lines.push(headerLine);
906515
- lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, borderFg, bodyBg));
906516
- for (let row = 0;row < bodyRows; row += 1) {
906517
- const line2 = createOverlayContentLine(width, layout, borderFg, bodyBg);
906518
- fillWidth(line2, innerStart, innerWidth, bodyBg);
906519
- if (row === 0) {
906520
- putOverlayText(line2, innerStart + 1, innerWidth - 2, truncateDisplay(currentStep.title, innerWidth - 2), {
906521
- fg: UI_TONES.fg.primary,
906522
- bg: bodyBg,
906523
- bold: true
906524
- });
906525
- } else if (row === 1) {
906526
- putOverlayText(line2, innerStart + 1, innerWidth - 2, descriptionLines[0] ?? "", {
906527
- fg: UI_TONES.fg.secondary,
906528
- bg: bodyBg
906529
- });
906530
- } else if (row === 2) {
906531
- putOverlayText(line2, innerStart + 1, innerWidth - 2, descriptionLines[1] ?? "", {
906532
- fg: UI_TONES.fg.secondary,
906533
- bg: bodyBg
906534
- });
906535
- } else if (row === 3) {
906536
- fillWidth(line2, innerStart, innerWidth, UI_TONES.bg.section);
906537
- putOverlayText(line2, innerStart + 1, innerWidth - 2, truncateDisplay(controlsText(wizard), innerWidth - 2), {
906538
- fg: UI_TONES.state.info,
906539
- bg: UI_TONES.bg.section
906540
- });
906541
- } else if (row === 4) {
906542
- fillWidth(line2, innerStart, innerWidth, DEFAULT_OVERLAY_PALETTE.selectedBg);
906543
- putOverlayText(line2, innerStart + 1, innerWidth - 2, truncateDisplay(`Focus: ${selectedText.title.replace(/^Selected: /, "")}`, innerWidth - 2), {
906544
- fg: UI_TONES.fg.primary,
906545
- bg: DEFAULT_OVERLAY_PALETTE.selectedBg,
906546
- bold: true
906547
- });
906548
- } else if (row >= 5 && row <= 7) {
906549
- fillWidth(line2, innerStart, innerWidth, DEFAULT_OVERLAY_PALETTE.selectedBg);
906550
- putOverlayText(line2, innerStart + 1, innerWidth - 2, selectedHintLines[row - 5] ?? "", {
906551
- fg: UI_TONES.fg.secondary,
906552
- bg: DEFAULT_OVERLAY_PALETTE.selectedBg
906553
- });
906554
- } else {
906555
- renderFieldRow(line2, wizard, fieldRows[row - fieldStartRow] ?? { kind: "empty" }, innerStart, innerWidth);
906556
- }
906557
- lines.push(line2);
906558
- }
906559
- lines.push(createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.teeLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.teeRight, borderFg, bodyBg));
906560
- const footer = createOverlayFilledBorderLine(width, layout, OVERLAY_GLYPHS.bottomLeft, OVERLAY_GLYPHS.horizontal, OVERLAY_GLYPHS.bottomRight, borderFg, headerBg);
906561
- putOverlayText(footer, layout.margin + 2, layout.width - 4, truncateDisplay(footerText4(wizard), layout.width - 4), {
906562
- fg: UI_TONES.fg.muted,
906563
- bg: headerBg,
906564
- dim: true
906565
- });
906566
- lines.push(footer);
906567
- return lines.slice(0, viewportHeight);
906568
- }
906569
- function renderOnboardingWizard(wizard, width, viewportHeight) {
906570
- const layout = createOverlayBoxLayout(width, 0, Math.max(20, width));
906571
- const collapsed = layout.innerWidth < 86;
906572
- return collapsed ? renderCollapsedLayout(wizard, width, viewportHeight, layout) : renderWideLayout(wizard, width, viewportHeight, layout);
906573
- }
906574
-
906575
906123
  // src/renderer/conversation-overlays.ts
906576
906124
  function applyConversationOverlays(viewport, context) {
906577
906125
  const { input, conversation, commandRegistry, keybindingsManager, conversationWidth, viewportHeight, contextWindow } = context;
906578
906126
  let next = viewport;
906579
906127
  const bottomDockInset = 1 + (input.searchManager.active || input.historySearch.active ? 1 : 0);
906580
906128
  if (input.onboardingWizard.active) {
906581
- const lines = renderOnboardingWizard(input.onboardingWizard, conversationWidth, viewportHeight);
906582
- next = replaceViewportWithOverlay(lines, conversationWidth, viewportHeight);
906583
- if (!input.modelPicker.active)
906584
- return next;
906129
+ return next;
906585
906130
  }
906586
906131
  if (input.filePicker.active) {
906587
906132
  const lines = renderFilePickerOverlay(input.filePicker, conversationWidth, viewportHeight);
@@ -906932,6 +906477,328 @@ function handleBlockingShellInput(options) {
906932
906477
  return { handled: false, pendingPermission, recoveryPending };
906933
906478
  }
906934
906479
 
906480
+ // src/renderer/onboarding/onboarding-wizard.ts
906481
+ function modeLabel(mode) {
906482
+ if (mode === "edit")
906483
+ return "Edit existing";
906484
+ if (mode === "reopen")
906485
+ return "Reopen review";
906486
+ return "New setup";
906487
+ }
906488
+ function changedScreensLabel(wizard) {
906489
+ if (wizard.dirtyStepCount === 0)
906490
+ return "no changes";
906491
+ if (wizard.dirtyStepCount === 1)
906492
+ return "1 changed screen";
906493
+ return `${wizard.dirtyStepCount} changed screens`;
906494
+ }
906495
+ function stepGlyph(wizard, step, stepIndex) {
906496
+ if (stepIndex === wizard.stepIndex)
906497
+ return { glyph: GLYPHS.navigation.selected, fg: FULLSCREEN_PALETTE.info };
906498
+ const total = wizard.getStepFieldCount(stepIndex);
906499
+ const completed = wizard.getCompletedFieldCount(stepIndex);
906500
+ if (wizard.isStepDirty(stepIndex))
906501
+ return { glyph: GLYPHS.status.review, fg: FULLSCREEN_PALETTE.warn };
906502
+ if (total > 0 && completed === total)
906503
+ return { glyph: GLYPHS.status.success, fg: FULLSCREEN_PALETTE.good };
906504
+ return { glyph: GLYPHS.status.pending, fg: FULLSCREEN_PALETTE.muted };
906505
+ }
906506
+ function fieldRowPrefix(wizard, field, selected) {
906507
+ if (selected)
906508
+ return `${GLYPHS.navigation.selected} `;
906509
+ if (wizard.isFieldDirty(field.id))
906510
+ return `${GLYPHS.status.skipped} `;
906511
+ if (field.kind === "checklist")
906512
+ return wizard.getFieldValue(field) ? `${GLYPHS.status.success} ` : "\u25A1 ";
906513
+ if (field.kind === "acknowledgement")
906514
+ return wizard.getFieldValue(field) ? `${GLYPHS.status.success} ` : "\u25A1 ";
906515
+ if (field.kind === "action")
906516
+ return `${GLYPHS.navigation.next} `;
906517
+ if (field.kind === "radio")
906518
+ return `${GLYPHS.status.active} `;
906519
+ return " ";
906520
+ }
906521
+ function fieldColor(wizard, field, selected) {
906522
+ if (selected)
906523
+ return FULLSCREEN_PALETTE.text;
906524
+ if (field.kind === "status" || field.kind === "modelPicker")
906525
+ return FULLSCREEN_PALETTE.info;
906526
+ if (field.kind === "masked")
906527
+ return FULLSCREEN_PALETTE.warn;
906528
+ if (field.kind === "acknowledgement")
906529
+ return wizard.getFieldValue(field) ? FULLSCREEN_PALETTE.good : FULLSCREEN_PALETTE.warn;
906530
+ if (field.kind === "checklist")
906531
+ return wizard.getFieldValue(field) ? FULLSCREEN_PALETTE.good : FULLSCREEN_PALETTE.muted;
906532
+ if (wizard.getFieldValueLabel(field) === "Missing")
906533
+ return FULLSCREEN_PALETTE.warn;
906534
+ return FULLSCREEN_PALETTE.text;
906535
+ }
906536
+ function formatEditingValue(value, multiline) {
906537
+ if (!multiline)
906538
+ return value;
906539
+ const lines = value.split(/\r?\n/);
906540
+ if (lines.length <= 1)
906541
+ return value;
906542
+ const preview4 = lines[lines.length - 1] ?? "";
906543
+ return `${preview4} (${lines.length} lines)`;
906544
+ }
906545
+ function fieldHint(wizard, field, selected) {
906546
+ if (selected && wizard.isEditingTextField() && wizard.editingFieldId === field.id && (field.kind === "text" || field.kind === "masked")) {
906547
+ const rawValue = wizard.editBuffer.length > 0 ? wizard.editBuffer : field.placeholder;
906548
+ const editingValue = field.kind === "masked" && wizard.editBuffer.length > 0 ? "\u2022".repeat(Math.min(12, Math.max(4, wizard.editBuffer.length))) : formatEditingValue(rawValue, field.kind === "text" && field.multiline === true);
906549
+ return `Editing: ${editingValue}${GLYPHS.surface.cursor}`;
906550
+ }
906551
+ if (selected && field.kind === "modelPicker")
906552
+ return `${field.hint} Press Enter to open picker.`;
906553
+ if (selected && field.kind === "text") {
906554
+ return field.multiline === true ? `${field.hint} Press Enter to edit; Ctrl-J inserts a new line.` : `${field.hint} Press Enter to edit inline.`;
906555
+ }
906556
+ if (selected && field.kind === "masked")
906557
+ return `${field.hint} Press Enter to edit inline.`;
906558
+ return field.hint;
906559
+ }
906560
+ function selectedFieldText(wizard) {
906561
+ if (wizard.isEditingTextField() && wizard.editingFieldId !== null) {
906562
+ const editingField = wizard.getFieldById(wizard.editingFieldId);
906563
+ if (editingField) {
906564
+ return {
906565
+ title: `Editing: ${editingField.label}`,
906566
+ hint: fieldHint(wizard, editingField, true)
906567
+ };
906568
+ }
906569
+ }
906570
+ const field = wizard.getSelectedField();
906571
+ if (!field)
906572
+ return { title: "Selected: none", hint: "No selectable row is active on this screen." };
906573
+ return {
906574
+ title: `Selected: ${field.label} [${wizard.getFieldValueLabel(field)}]`,
906575
+ hint: fieldHint(wizard, field, true)
906576
+ };
906577
+ }
906578
+ function footerText4(wizard) {
906579
+ if (wizard.isEditingTextField()) {
906580
+ return wizard.isEditingMultilineTextField() ? "Controls: [Enter] save \xB7 [Ctrl-J] new line \xB7 [Esc] cancel \xB7 [Backspace] delete \xB7 [Del/Ctrl+U] clear" : "Controls: [Enter] save \xB7 [Esc] cancel \xB7 [Backspace] delete \xB7 [Del/Ctrl+U] clear";
906581
+ }
906582
+ return "Controls: [Enter] toggle/open \xB7 [Esc] close \xB7 [Tab/Shift+Tab] screen \xB7 [Up/Down] move \xB7 [Del/Ctrl+U] clear";
906583
+ }
906584
+ function controlsText(wizard) {
906585
+ if (wizard.isEditingTextField()) {
906586
+ return wizard.isEditingMultilineTextField() ? "Controls: Enter saves, Ctrl-J inserts a line, Esc cancels, Backspace deletes, Del clears." : "Controls: Enter saves, Esc cancels, Backspace deletes, Del clears.";
906587
+ }
906588
+ return "Controls: Enter selects, Del clears, Tab moves.";
906589
+ }
906590
+ function buildFieldRows(wizard, visibleFields, capacity) {
906591
+ wizard.ensureSelectionVisible(visibleFields);
906592
+ const fields = wizard.currentStep.fields;
906593
+ const rows = [];
906594
+ if (fields.length === 0 || capacity <= 0)
906595
+ return rows;
906596
+ const allRows = [];
906597
+ fields.forEach((field, absoluteIndex) => {
906598
+ const spacerRows = Math.max(0, field.spacerBeforeRows ?? 0);
906599
+ for (let index = 0;index < spacerRows; index += 1)
906600
+ allRows.push({ kind: "empty" });
906601
+ allRows.push({ kind: "field", field, absoluteIndex });
906602
+ });
906603
+ const selectedFieldIndex = wizard.getSelectedFieldIndex();
906604
+ const selectedRowIndex = Math.max(0, allRows.findIndex((row) => row.kind === "field" && row.absoluteIndex === selectedFieldIndex));
906605
+ const scrollFieldIndex = wizard.scrollOffsets[wizard.stepIndex] ?? 0;
906606
+ const scrollRowIndex = allRows.findIndex((row) => row.kind === "field" && row.absoluteIndex === scrollFieldIndex);
906607
+ const maxStart = Math.max(0, allRows.length - capacity);
906608
+ let start2 = Math.max(0, Math.min(scrollRowIndex >= 0 ? scrollRowIndex : 0, maxStart));
906609
+ if (selectedRowIndex < start2)
906610
+ start2 = selectedRowIndex;
906611
+ if (selectedRowIndex >= start2 + capacity)
906612
+ start2 = selectedRowIndex - capacity + 1;
906613
+ start2 = Math.max(0, Math.min(start2, maxStart));
906614
+ if (capacity > 1 && start2 > 0 && selectedRowIndex === start2)
906615
+ start2 = Math.max(0, start2 - 1);
906616
+ if (capacity > 1 && start2 + capacity < allRows.length && selectedRowIndex === start2 + capacity - 1) {
906617
+ start2 = Math.min(maxStart, start2 + 1);
906618
+ }
906619
+ rows.push(...allRows.slice(start2, start2 + capacity));
906620
+ const firstVisibleRow = rows[0];
906621
+ if (start2 > 0 && rows.length > 0 && !(firstVisibleRow?.kind === "field" && firstVisibleRow.absoluteIndex === selectedFieldIndex)) {
906622
+ rows[0] = { kind: "moreAbove", text: `${GLYPHS.navigation.moreAbove} ${start2} more above` };
906623
+ }
906624
+ const hiddenBelow = Math.max(0, allRows.length - (start2 + capacity));
906625
+ const lastVisibleRow = rows[rows.length - 1];
906626
+ if (hiddenBelow > 0 && rows.length > 0 && !(lastVisibleRow?.kind === "field" && lastVisibleRow.absoluteIndex === selectedFieldIndex)) {
906627
+ rows[rows.length - 1] = { kind: "moreBelow", text: `${GLYPHS.navigation.moreBelow} ${hiddenBelow} more below` };
906628
+ }
906629
+ while (rows.length < capacity)
906630
+ rows.push({ kind: "empty" });
906631
+ return rows.slice(0, capacity);
906632
+ }
906633
+ function pushWrapped(rows, text, width, options = {}) {
906634
+ if (text.length === 0) {
906635
+ rows.push({ text: "", kind: "empty" });
906636
+ return;
906637
+ }
906638
+ for (const line2 of wrapText(text, Math.max(1, width))) {
906639
+ rows.push({ text: line2, ...options });
906640
+ }
906641
+ }
906642
+ function buildStepRows(wizard, height) {
906643
+ const rendered = wizard.steps.map((step, stepIndex) => {
906644
+ const selected = stepIndex === wizard.stepIndex;
906645
+ const state4 = stepGlyph(wizard, step, stepIndex);
906646
+ const completion = `${wizard.getCompletedFieldCount(stepIndex)}/${wizard.getStepFieldCount(stepIndex)}`;
906647
+ return {
906648
+ text: `${state4.glyph} ${stepIndex + 1}. ${step.shortLabel} ${completion}`,
906649
+ selected,
906650
+ kind: "item",
906651
+ fg: state4.fg,
906652
+ bold: selected
906653
+ };
906654
+ });
906655
+ const visible = Math.max(1, height);
906656
+ const window3 = stableWindow(rendered.length, wizard.stepIndex, visible);
906657
+ const rows = rendered.slice(window3.start, window3.end);
906658
+ if (window3.start > 0 && rows.length > 0) {
906659
+ rows[0] = { text: `${GLYPHS.navigation.moreAbove} ${window3.start} more step(s) above`, kind: "more", fg: FULLSCREEN_PALETTE.dim, dim: true };
906660
+ }
906661
+ if (window3.end < rendered.length && rows.length > 0) {
906662
+ rows[rows.length - 1] = { text: `${GLYPHS.navigation.moreBelow} ${rendered.length - window3.end} more step(s) below`, kind: "more", fg: FULLSCREEN_PALETTE.dim, dim: true };
906663
+ }
906664
+ while (rows.length < height)
906665
+ rows.push({ text: "", kind: "empty" });
906666
+ return rows.slice(0, height);
906667
+ }
906668
+ function buildContextRows2(wizard, width) {
906669
+ const step = wizard.currentStep;
906670
+ const selected = selectedFieldText(wizard);
906671
+ const rows = [
906672
+ { text: step.title, fg: FULLSCREEN_PALETTE.title, bold: true }
906673
+ ];
906674
+ const pushSummaryRows = () => {
906675
+ rows.push({ text: "Summary", fg: FULLSCREEN_PALETTE.subtitle, bold: true });
906676
+ rows.push({ text: step.summaryTitle, fg: FULLSCREEN_PALETTE.info, bold: true });
906677
+ for (const line2 of step.summaryLines.slice(0, 4)) {
906678
+ pushWrapped(rows, line2, width, { fg: FULLSCREEN_PALETTE.text });
906679
+ }
906680
+ rows.push({
906681
+ text: `Fields ${wizard.getCompletedFieldCount(wizard.stepIndex)}/${wizard.getStepFieldCount(wizard.stepIndex)} complete \xB7 ${changedScreensLabel(wizard)}`,
906682
+ fg: wizard.dirtyStepCount > 0 ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.muted
906683
+ });
906684
+ };
906685
+ const pushSelectedRows = () => {
906686
+ rows.push({ text: selected.title, fg: FULLSCREEN_PALETTE.info, bold: true });
906687
+ pushWrapped(rows, selected.hint, width, { fg: FULLSCREEN_PALETTE.text });
906688
+ pushWrapped(rows, controlsText(wizard), width, { fg: FULLSCREEN_PALETTE.info });
906689
+ };
906690
+ pushWrapped(rows, step.description, width, { fg: FULLSCREEN_PALETTE.text });
906691
+ rows.push({ text: "", kind: "empty" });
906692
+ if (wizard.isEditingTextField()) {
906693
+ pushSelectedRows();
906694
+ rows.push({ text: "", kind: "empty" });
906695
+ pushSummaryRows();
906696
+ } else {
906697
+ pushSummaryRows();
906698
+ rows.push({ text: "", kind: "empty" });
906699
+ pushSelectedRows();
906700
+ }
906701
+ if (wizard.hydrationPending || wizard.hydrationError !== null || wizard.applyFeedback !== null) {
906702
+ rows.push({ text: "", kind: "empty" });
906703
+ }
906704
+ if (wizard.hydrationPending) {
906705
+ rows.push({ text: "Loading current settings...", fg: FULLSCREEN_PALETTE.info, bold: true });
906706
+ }
906707
+ if (wizard.hydrationError !== null) {
906708
+ pushWrapped(rows, `Current settings could not load: ${wizard.hydrationError}`, width, { fg: FULLSCREEN_PALETTE.bad, bold: true });
906709
+ }
906710
+ if (wizard.applyFeedback !== null) {
906711
+ const feedbackColor = wizard.applyFeedback.severity === "error" ? FULLSCREEN_PALETTE.bad : wizard.applyFeedback.severity === "warning" ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.info;
906712
+ rows.push({ text: wizard.applyFeedback.title, fg: feedbackColor, bold: true });
906713
+ pushWrapped(rows, wizard.applyFeedback.summary, width, { fg: FULLSCREEN_PALETTE.text });
906714
+ for (const message of wizard.applyFeedback.messages) {
906715
+ pushWrapped(rows, message, width, { fg: FULLSCREEN_PALETTE.muted });
906716
+ }
906717
+ }
906718
+ return rows;
906719
+ }
906720
+ function formatFieldRowText(wizard, field, selected, width) {
906721
+ const badge = `[${wizard.getFieldValueLabel(field)}]`;
906722
+ const badgeWidth = getDisplayWidth(badge);
906723
+ const labelWidth = Math.max(1, width - badgeWidth - 2);
906724
+ const label = truncateDisplay(`${fieldRowPrefix(wizard, field, selected)}${field.label}`, labelWidth);
906725
+ return `${label}${" ".repeat(Math.max(1, width - getDisplayWidth(label) - badgeWidth))}${badge}`;
906726
+ }
906727
+ function buildControlRows2(wizard, width, height) {
906728
+ const visibleFields = Math.max(1, height);
906729
+ const fieldRows = buildFieldRows(wizard, visibleFields, height);
906730
+ const rows = fieldRows.map((row) => {
906731
+ if (row.kind === "empty")
906732
+ return { text: "", kind: "empty" };
906733
+ if (row.kind === "moreAbove" || row.kind === "moreBelow") {
906734
+ return { text: row.text, kind: "more", fg: FULLSCREEN_PALETTE.dim, dim: true };
906735
+ }
906736
+ const selected = row.absoluteIndex === wizard.getSelectedFieldIndex();
906737
+ return {
906738
+ text: formatFieldRowText(wizard, row.field, selected, width),
906739
+ selected,
906740
+ kind: "item",
906741
+ fg: fieldColor(wizard, row.field, selected),
906742
+ bold: selected || row.field.kind === "action"
906743
+ };
906744
+ });
906745
+ while (rows.length < height)
906746
+ rows.push({ text: "", kind: "empty" });
906747
+ return rows.slice(0, height);
906748
+ }
906749
+ function renderOnboardingWizard(wizard, width, viewportHeight) {
906750
+ const layoutOptions = {
906751
+ width,
906752
+ height: viewportHeight,
906753
+ leftWidth: width < 90 ? undefined : 30,
906754
+ contextRatio: 0.42,
906755
+ minContextRows: 8
906756
+ };
906757
+ const metrics = getFullscreenWorkspaceMetrics(layoutOptions);
906758
+ return renderFullscreenWorkspace({
906759
+ width,
906760
+ height: viewportHeight,
906761
+ title: "GoodVibes Agent / Onboarding Wizard",
906762
+ stateLabel: `${modeLabel(wizard.mode)} \xB7 ${wizard.stepIndex + 1}/${wizard.steps.length} \xB7 ${changedScreensLabel(wizard)}`,
906763
+ leftHeader: "Steps",
906764
+ mainHeader: wizard.currentStep.title,
906765
+ leftRows: buildStepRows(wizard, metrics.bodyRows),
906766
+ contextRows: buildContextRows2(wizard, metrics.contextWidth),
906767
+ controlRows: buildControlRows2(wizard, metrics.contextWidth, metrics.controlRows),
906768
+ footer: footerText4(wizard),
906769
+ leftWidth: layoutOptions.leftWidth,
906770
+ contextRatio: layoutOptions.contextRatio,
906771
+ minContextRows: layoutOptions.minContextRows
906772
+ });
906773
+ }
906774
+
906775
+ // src/shell/onboarding-fullscreen.ts
906776
+ function normalizeFullscreenViewport(lines, width, height) {
906777
+ const viewport = lines.slice(0, height).map((line2) => {
906778
+ if (line2.length === width)
906779
+ return line2;
906780
+ const next = createEmptyLine(width);
906781
+ for (let index = 0;index < Math.min(width, line2.length); index += 1) {
906782
+ next[index] = { ...line2[index] };
906783
+ }
906784
+ return next;
906785
+ });
906786
+ while (viewport.length < height)
906787
+ viewport.push(createEmptyLine(width));
906788
+ return viewport;
906789
+ }
906790
+ function createOnboardingFullscreenComposite(input, width, height) {
906791
+ const viewport = normalizeFullscreenViewport(input.modelPicker.active ? renderModelWorkspace(input.modelPicker, width, height) : renderOnboardingWizard(input.onboardingWizard, width, height), width, height);
906792
+ return {
906793
+ width,
906794
+ height,
906795
+ header: [],
906796
+ viewport,
906797
+ footer: [],
906798
+ panelWidth: 0
906799
+ };
906800
+ }
906801
+
906935
906802
  // src/shell/service-settings-sync.ts
906936
906803
  var AGENT_EXTERNAL_HOST_SERVICE_MESSAGE = "GoodVibes Agent uses a connected GoodVibes host and does not install, start, stop, restart, or uninstall it. Manage host lifecycle outside Agent.";
906937
906804
  function syncServiceSettingToPlatform(runtime3, change, _options = {}) {
@@ -909440,6 +909307,13 @@ async function main() {
909440
909307
  const render = () => {
909441
909308
  const width = stdout.columns || 80;
909442
909309
  const height = stdout.rows || 24;
909310
+ if (input.onboardingWizard.active) {
909311
+ input.setPanelMouseLayout(null);
909312
+ activeConversationWidth = width;
909313
+ conversation.setSplashSuppressed(true);
909314
+ compositor.composite(createOnboardingFullscreenComposite(input, width, height));
909315
+ return;
909316
+ }
909443
909317
  const currentModel = providerRegistry.getCurrentModel();
909444
909318
  const sessionSnapshot = uiServices.readModels.session.getSnapshot();
909445
909319
  const headerLines = UIFactory.createHeader(width, currentModel.id, currentModel.provider, conversation.title || undefined);