@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.
- package/CHANGELOG.md +10 -0
- package/dist/package/main.js +337 -463
- package/package.json +1 -1
- package/src/main.ts +9 -1
- package/src/renderer/compositor.ts +7 -1
- package/src/renderer/conversation-overlays.ts +1 -4
- package/src/renderer/onboarding/onboarding-wizard.ts +237 -499
- package/src/shell/onboarding-fullscreen.ts +40 -0
- package/src/version.ts +1 -1
package/dist/package/main.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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);
|