@pellux/goodvibes-agent 1.0.37 → 1.0.38

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.
@@ -389782,23 +389782,6 @@ function createSchema2(db) {
389782
389782
  `);
389783
389783
  db.run(`CREATE INDEX IF NOT EXISTS idx_knowledge_schedules_job_id ON knowledge_schedules(job_id)`);
389784
389784
  }
389785
- function getKnowledgeSchemaStatements() {
389786
- const statements = [];
389787
- createSchema2({
389788
- run(sql) {
389789
- const normalized = sql.trim();
389790
- if (normalized.length > 0)
389791
- statements.push(normalized);
389792
- }
389793
- });
389794
- return statements;
389795
- }
389796
- function renderKnowledgeSchemaSql() {
389797
- return `${getKnowledgeSchemaStatements().map((statement) => statement.endsWith(";") ? statement : `${statement};`).join(`
389798
-
389799
- `)}
389800
- `;
389801
- }
389802
389785
  function rowObject(columns, values2) {
389803
389786
  return Object.fromEntries(columns.map((column, index) => [column, values2[index]]));
389804
389787
  }
@@ -703136,9 +703119,6 @@ var init_ingest = __esm(() => {
703136
703119
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/browser-history/index.js
703137
703120
  var init_browser_history = __esm(() => {
703138
703121
  init_ingest();
703139
- init_discover();
703140
- init_readers();
703141
- init_paths2();
703142
703122
  });
703143
703123
 
703144
703124
  // node_modules/graphql/jsutils/devAssert.mjs
@@ -720778,7 +720758,6 @@ var init_semantic = __esm(() => {
720778
720758
  init_llm();
720779
720759
  init_gap_repair();
720780
720760
  init_service4();
720781
- init_self_improvement();
720782
720761
  });
720783
720762
 
720784
720763
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/helpers.js
@@ -724747,40 +724726,8 @@ var init_map_view = __esm(() => {
724747
724726
  });
724748
724727
 
724749
724728
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/types.js
724750
- var HOME_GRAPH_NODE_KINDS, HOME_GRAPH_RELATIONS, HOME_GRAPH_CAPABILITIES;
724729
+ var HOME_GRAPH_CAPABILITIES;
724751
724730
  var init_types6 = __esm(() => {
724752
- HOME_GRAPH_NODE_KINDS = [
724753
- "ha_home",
724754
- "ha_entity",
724755
- "ha_device",
724756
- "ha_area",
724757
- "ha_automation",
724758
- "ha_script",
724759
- "ha_scene",
724760
- "ha_label",
724761
- "ha_integration",
724762
- "ha_room",
724763
- "ha_device_passport",
724764
- "ha_maintenance_item",
724765
- "ha_troubleshooting_case",
724766
- "ha_purchase",
724767
- "ha_network_node"
724768
- ];
724769
- HOME_GRAPH_RELATIONS = [
724770
- "controls",
724771
- "located_in",
724772
- "belongs_to_device",
724773
- "has_manual",
724774
- "has_receipt",
724775
- "has_warranty",
724776
- "has_issue",
724777
- "fixed_by",
724778
- "uses_battery",
724779
- "connected_via",
724780
- "part_of_network",
724781
- "mentioned_by",
724782
- "source_for"
724783
- ];
724784
724731
  HOME_GRAPH_CAPABILITIES = [
724785
724732
  "knowledge-space-isolation",
724786
724733
  "snapshot-sync",
@@ -726187,7 +726134,6 @@ var init_service5 = __esm(() => {
726187
726134
  var init_home_graph = __esm(() => {
726188
726135
  init_service5();
726189
726136
  init_extension();
726190
- init_types6();
726191
726137
  });
726192
726138
 
726193
726139
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/store-refinement.js
@@ -728515,14 +728461,10 @@ var init_service6 = __esm(() => {
728515
728461
  var init_project_planning = __esm(() => {
728516
728462
  init_service6();
728517
728463
  init_helpers3();
728518
- init_readiness();
728519
728464
  });
728520
728465
 
728521
728466
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/persistence.js
728522
- var init_persistence = __esm(() => {
728523
- init_store_schema();
728524
- init_store_load();
728525
- });
728467
+ var init_persistence = () => {};
728526
728468
 
728527
728469
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/projections.js
728528
728470
  class KnowledgeProjectionService {
@@ -732030,21 +731972,21 @@ var init_service7 = __esm(() => {
732030
731972
  var exports_knowledge = {};
732031
731973
  __export(exports_knowledge, {
732032
731974
  withKnowledgeSpace: () => withKnowledgeSpace,
732033
- uniqKnowledgeValues: () => uniq2,
732034
- stabilizeKnowledgeText: () => stableText,
732035
- runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement,
731975
+ uniqKnowledgeValues: () => uniq3,
731976
+ stabilizeKnowledgeText: () => stableText2,
731977
+ runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement2,
732036
731978
  resolveProjectPlanningSpace: () => resolveProjectPlanningSpace,
732037
- resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir,
731979
+ resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir2,
732038
731980
  renderPacket: () => renderPacket,
732039
731981
  renderKnowledgeSchemaSql: () => renderKnowledgeSchemaSql,
732040
731982
  renderKnowledgeMap: () => renderKnowledgeMap,
732041
731983
  readKnowledgeSearchText: () => readKnowledgeSearchText,
732042
- readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile,
731984
+ readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile2,
732043
731985
  projectPlanningSourceId: () => projectPlanningSourceId,
732044
731986
  projectPlanningProjectIdFromPath: () => projectPlanningProjectIdFromPath,
732045
731987
  projectPlanningCanonicalUri: () => projectPlanningCanonicalUri,
732046
731988
  projectKnowledgeSpaceId: () => projectKnowledgeSpaceId,
732047
- parseKnowledgeJsonValue: () => parseJsonValue,
731989
+ parseKnowledgeJsonValue: () => parseJsonValue2,
732048
731990
  normalizeProjectId: () => normalizeProjectId,
732049
731991
  normalizeKnowledgeSpaceId: () => normalizeKnowledgeSpaceId,
732050
731992
  normalizeHomeAssistantInstallationId: () => normalizeHomeAssistantInstallationId,
@@ -732052,12 +731994,12 @@ __export(exports_knowledge, {
732052
731994
  materializeGeneratedKnowledgeProjection: () => materializeGeneratedKnowledgeProjection,
732053
731995
  looksLikeRawPdfPayload: () => looksLikeRawPdfPayload,
732054
731996
  looksBinaryLikeText: () => looksBinaryLikeText,
732055
- loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot,
731997
+ loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot2,
732056
731998
  listGeneratedKnowledgePages: () => listGeneratedKnowledgePages,
732057
- listBrowserKinds: () => listBrowserKinds,
731999
+ listBrowserKinds: () => listBrowserKinds2,
732058
732000
  knowledgeSpaceMetadata: () => knowledgeSpaceMetadata,
732059
732001
  knowledgePageSourceWeight: () => knowledgePageSourceWeight,
732060
- knowledgeNowMs: () => nowMs,
732002
+ knowledgeNowMs: () => nowMs2,
732061
732003
  knowledgeExtractionNeedsRefresh: () => knowledgeExtractionNeedsRefresh,
732062
732004
  isUsefulKnowledgePageSourceCandidate: () => isUsefulKnowledgePageSourceCandidate,
732063
732005
  isUsefulKnowledgePageSource: () => isUsefulKnowledgePageSource,
@@ -732077,12 +732019,12 @@ __export(exports_knowledge, {
732077
732019
  generatedKnowledgeSourceId: () => generatedKnowledgeSourceId,
732078
732020
  generatedKnowledgeCanonicalUri: () => generatedKnowledgeCanonicalUri,
732079
732021
  extractKnowledgeArtifact: () => extractKnowledgeArtifact,
732080
- evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness,
732081
- discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles,
732022
+ evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness2,
732023
+ discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles2,
732082
732024
  createWebKnowledgeGapRepairer: () => createWebKnowledgeGapRepairer,
732083
732025
  createProviderBackedKnowledgeSemanticLlm: () => createProviderBackedKnowledgeSemanticLlm,
732084
732026
  createMemoryApi: () => createMemoryApi,
732085
- createKnowledgeSchema: () => createSchema2,
732027
+ createKnowledgeSchema: () => createSchema3,
732086
732028
  createKnowledgeApi: () => createKnowledgeApi,
732087
732029
  createDefaultKnowledgeConnectorRegistry: () => createDefaultKnowledgeConnectorRegistry,
732088
732030
  compareKnowledgePageSources: () => compareKnowledgePageSources,
@@ -734521,7 +734463,7 @@ var init_delivery_manager = __esm(() => {
734521
734463
  });
734522
734464
 
734523
734465
  // node_modules/@pellux/goodvibes-sdk/dist/platform/automation/scheduler-capacity.js
734524
- function computeSchedulerCapacity(slotsTotal, runs, nowMs2 = Date.now()) {
734466
+ function computeSchedulerCapacity(slotsTotal, runs, nowMs3 = Date.now()) {
734525
734467
  let slotsInUse = 0;
734526
734468
  const queuedRuns = [];
734527
734469
  for (const run7 of runs) {
@@ -734531,7 +734473,7 @@ function computeSchedulerCapacity(slotsTotal, runs, nowMs2 = Date.now()) {
734531
734473
  queuedRuns.push(run7);
734532
734474
  }
734533
734475
  const queueDepth = queuedRuns.length;
734534
- const oldestQueuedAgeMs = queueDepth > 0 ? nowMs2 - Math.min(...queuedRuns.map((r5) => r5.queuedAt)) : null;
734476
+ const oldestQueuedAgeMs = queueDepth > 0 ? nowMs3 - Math.min(...queuedRuns.map((r5) => r5.queuedAt)) : null;
734535
734477
  return { slotsTotal, slotsInUse, queueDepth, oldestQueuedAgeMs };
734536
734478
  }
734537
734479
 
@@ -817145,7 +817087,7 @@ var createStyledCell = (char, overrides = {}) => ({
817145
817087
  // src/version.ts
817146
817088
  import { readFileSync } from "fs";
817147
817089
  import { join } from "path";
817148
- var _version = "1.0.37";
817090
+ var _version = "1.0.38";
817149
817091
  try {
817150
817092
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
817151
817093
  _version = typeof pkg.version === "string" ? pkg.version : _version;
@@ -839197,6 +839139,12 @@ class Compositor {
839197
839139
  }
839198
839140
  }
839199
839141
  });
839142
+ for (let i4 = viewport.length;i4 < vHeight; i4 += 1) {
839143
+ const screenY = viewportStartY + i4;
839144
+ if (screenY >= height)
839145
+ break;
839146
+ newBuffer.blitLine(screenY, createEmptyLine(width));
839147
+ }
839200
839148
  if (hasPanel && panel.separator) {
839201
839149
  for (let i4 = viewport.length;i4 < vHeight; i4++) {
839202
839150
  const screenY = viewportStartY + i4;
@@ -840222,7 +840170,7 @@ var WORK_PLAN_STATUSES = [
840222
840170
  "failed",
840223
840171
  "cancelled"
840224
840172
  ];
840225
- function nowMs2() {
840173
+ function nowMs3() {
840226
840174
  return Date.now();
840227
840175
  }
840228
840176
  function isObject5(value) {
@@ -840328,7 +840276,7 @@ class WorkPlanStore {
840328
840276
  if (!normalizedTitle)
840329
840277
  throw new Error("Work plan item title is required.");
840330
840278
  const plan = this.readPlan();
840331
- const time4 = nowMs2();
840279
+ const time4 = nowMs3();
840332
840280
  const item = {
840333
840281
  id: createItemId(),
840334
840282
  title: normalizedTitle,
@@ -840352,7 +840300,7 @@ class WorkPlanStore {
840352
840300
  updateItem(idOrPrefix, patch2) {
840353
840301
  const plan = this.readPlan();
840354
840302
  const item = this.resolveItem(plan, idOrPrefix);
840355
- const time4 = nowMs2();
840303
+ const time4 = nowMs3();
840356
840304
  const nextStatus = patch2.status ?? item.status;
840357
840305
  const next = this.pruneItem({
840358
840306
  ...item,
@@ -840385,7 +840333,7 @@ class WorkPlanStore {
840385
840333
  removeItem(idOrPrefix) {
840386
840334
  const plan = this.readPlan();
840387
840335
  const item = this.resolveItem(plan, idOrPrefix);
840388
- const time4 = nowMs2();
840336
+ const time4 = nowMs3();
840389
840337
  const remaining = plan.items.filter((candidate) => candidate.id !== item.id);
840390
840338
  this.writePlan({
840391
840339
  ...plan,
@@ -840405,7 +840353,7 @@ class WorkPlanStore {
840405
840353
  ...plan,
840406
840354
  items: remaining,
840407
840355
  activeItemId: remaining[0]?.id,
840408
- updatedAt: nowMs2()
840356
+ updatedAt: nowMs3()
840409
840357
  });
840410
840358
  return removed;
840411
840359
  }
@@ -840444,7 +840392,7 @@ class WorkPlanStore {
840444
840392
  const parsed = JSON.parse(raw);
840445
840393
  if (!isObject5(parsed))
840446
840394
  return this.createEmptyPlan();
840447
- const time4 = nowMs2();
840395
+ const time4 = nowMs3();
840448
840396
  const createdAt = typeof parsed.createdAt === "number" ? parsed.createdAt : time4;
840449
840397
  const updatedAt = typeof parsed.updatedAt === "number" ? parsed.updatedAt : createdAt;
840450
840398
  const items = Array.isArray(parsed.items) ? parsed.items.map((item) => normalizeItem(item, createdAt)).filter((item) => item !== null) : [];
@@ -840463,7 +840411,7 @@ class WorkPlanStore {
840463
840411
  };
840464
840412
  }
840465
840413
  createEmptyPlan() {
840466
- const time4 = nowMs2();
840414
+ const time4 = nowMs3();
840467
840415
  return {
840468
840416
  id: createPlanId(this.options.projectId, this.options.projectRoot),
840469
840417
  projectId: this.options.projectId,
@@ -848695,13 +848643,13 @@ init_state3();
848695
848643
 
848696
848644
  // src/input/commands/recall-shared.ts
848697
848645
  var VALID_CLASSES = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
848698
- var VALID_SCOPES = ["session", "project", "team"];
848646
+ var VALID_SCOPES2 = ["session", "project", "team"];
848699
848647
  var VALID_REVIEW_STATES = ["fresh", "reviewed", "stale", "contradicted"];
848700
848648
  function isValidClass(s4) {
848701
848649
  return VALID_CLASSES.includes(s4);
848702
848650
  }
848703
848651
  function isValidScope(s4) {
848704
- return VALID_SCOPES.includes(s4);
848652
+ return VALID_SCOPES2.includes(s4);
848705
848653
  }
848706
848654
  function isValidReviewState(s4) {
848707
848655
  return VALID_REVIEW_STATES.includes(s4);
@@ -848744,7 +848692,7 @@ function handleRecallSearch(args2, context) {
848744
848692
  if (isValidScope(scope))
848745
848693
  filter.scope = scope;
848746
848694
  else {
848747
- context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
848695
+ context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES2.join(", ")}.`);
848748
848696
  return;
848749
848697
  }
848750
848698
  }
@@ -848919,7 +848867,7 @@ function handleRecallList(args2, context) {
848919
848867
  if (scopeIdx !== -1 && args2[scopeIdx + 1]) {
848920
848868
  const scope = args2[scopeIdx + 1];
848921
848869
  if (!isValidScope(scope)) {
848922
- context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
848870
+ context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES2.join(", ")}.`);
848923
848871
  return;
848924
848872
  }
848925
848873
  filter.scope = scope;
@@ -848969,7 +848917,7 @@ async function handleRecallAdd(args2, context) {
848969
848917
  const tags = tagsRaw ? tagsRaw.split(",").map((token) => token.trim()).filter(Boolean) : [];
848970
848918
  const scope = scopeRaw && isValidScope(scopeRaw) ? scopeRaw : "project";
848971
848919
  if (scopeRaw && !isValidScope(scopeRaw)) {
848972
- context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${VALID_SCOPES.join(", ")}.`);
848920
+ context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${VALID_SCOPES2.join(", ")}.`);
848973
848921
  return;
848974
848922
  }
848975
848923
  const provenance = [];
@@ -849103,7 +849051,7 @@ function handleRecallExport(args2, context) {
849103
849051
  if (scopeIdx !== -1 && commandArgs[scopeIdx + 1]) {
849104
849052
  const scope = commandArgs[scopeIdx + 1];
849105
849053
  if (!isValidScope(scope)) {
849106
- context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(", ")}.`);
849054
+ context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES2.join(", ")}.`);
849107
849055
  return;
849108
849056
  }
849109
849057
  filter.scope = scope;
@@ -849182,7 +849130,7 @@ function handleRecallHandoffExport(args2, context) {
849182
849130
  const scopeIdx = commandArgs.indexOf("--scope");
849183
849131
  const scopeRaw = scopeIdx !== -1 ? commandArgs[scopeIdx + 1] : "team";
849184
849132
  if (!scopeRaw || !isValidScope(scopeRaw)) {
849185
- context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${VALID_SCOPES.join(", ")}.`);
849133
+ context.print(`[memory] Unknown scope "${scopeRaw ?? ""}". Valid values ${VALID_SCOPES2.join(", ")}.`);
849186
849134
  return;
849187
849135
  }
849188
849136
  const bundle = memory.exportBundle({ scope: scopeRaw });
@@ -849298,7 +849246,7 @@ function handleRecallPromote(args2, context) {
849298
849246
  const id = parsed.rest[0];
849299
849247
  const scope = parsed.rest[1];
849300
849248
  if (!id || !scope || !isValidScope(scope)) {
849301
- context.print(`[memory] Usage: /memory promote <id> <${VALID_SCOPES.join("|")}> --yes`);
849249
+ context.print(`[memory] Usage: /memory promote <id> <${VALID_SCOPES2.join("|")}> --yes`);
849302
849250
  return;
849303
849251
  }
849304
849252
  if (!parsed.yes) {
@@ -863223,7 +863171,7 @@ import { mkdirSync as mkdirSync64, readFileSync as readFileSync85, writeFileSync
863223
863171
  import { dirname as dirname63, resolve as resolve39 } from "path";
863224
863172
  init_state3();
863225
863173
  var VALID_CLASSES2 = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
863226
- var VALID_SCOPES3 = ["session", "project", "team"];
863174
+ var VALID_SCOPES4 = ["session", "project", "team"];
863227
863175
  var VALID_REVIEW_STATES3 = ["fresh", "reviewed", "stale", "contradicted"];
863228
863176
  var VALID_PROVENANCE_KINDS = ["session", "turn", "task", "event", "file"];
863229
863177
  var VALUE_OPTIONS = new Set([
@@ -863323,7 +863271,7 @@ function isMemoryClass2(value) {
863323
863271
  return VALID_CLASSES2.includes(value);
863324
863272
  }
863325
863273
  function isMemoryScope2(value) {
863326
- return VALID_SCOPES3.includes(value);
863274
+ return VALID_SCOPES4.includes(value);
863327
863275
  }
863328
863276
  function isReviewState(value) {
863329
863277
  return VALID_REVIEW_STATES3.includes(value);
@@ -863338,7 +863286,7 @@ function requireClass(value) {
863338
863286
  }
863339
863287
  function requireScope(value) {
863340
863288
  if (!value || !isMemoryScope2(value))
863341
- throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${VALID_SCOPES3.join(", ")}`);
863289
+ throw new Error(`Invalid memory scope "${value ?? ""}". Valid values ${VALID_SCOPES4.join(", ")}`);
863342
863290
  return value;
863343
863291
  }
863344
863292
  function optionalScope(value) {
@@ -906130,41 +906078,99 @@ function changedScreensLabel(wizard) {
906130
906078
  return `${wizard.dirtyStepCount} changed screens`;
906131
906079
  }
906132
906080
  function stepGlyph(wizard, step, stepIndex) {
906133
- if (stepIndex === wizard.stepIndex) {
906134
- return { glyph: OVERLAY_GLYPHS.selected, fg: UI_TONES.state.active };
906135
- }
906081
+ if (stepIndex === wizard.stepIndex)
906082
+ return { glyph: GLYPHS.navigation.selected, fg: FULLSCREEN_PALETTE.info };
906136
906083
  const total = wizard.getStepFieldCount(stepIndex);
906137
906084
  const completed = wizard.getCompletedFieldCount(stepIndex);
906138
- if (wizard.isStepDirty(stepIndex)) {
906139
- return { glyph: "\u25C8", fg: UI_TONES.state.warn };
906085
+ if (wizard.isStepDirty(stepIndex))
906086
+ return { glyph: GLYPHS.status.review, fg: FULLSCREEN_PALETTE.warn };
906087
+ if (total > 0 && completed === total)
906088
+ return { glyph: GLYPHS.status.success, fg: FULLSCREEN_PALETTE.good };
906089
+ return { glyph: GLYPHS.status.pending, fg: FULLSCREEN_PALETTE.muted };
906090
+ }
906091
+ function fieldRowPrefix(wizard, field, selected) {
906092
+ if (selected)
906093
+ return `${GLYPHS.navigation.selected} `;
906094
+ if (wizard.isFieldDirty(field.id))
906095
+ return `${GLYPHS.status.skipped} `;
906096
+ if (field.kind === "checklist")
906097
+ return wizard.getFieldValue(field) ? `${GLYPHS.status.success} ` : "\u25A1 ";
906098
+ if (field.kind === "acknowledgement")
906099
+ return wizard.getFieldValue(field) ? `${GLYPHS.status.success} ` : "\u25A1 ";
906100
+ if (field.kind === "action")
906101
+ return `${GLYPHS.navigation.next} `;
906102
+ if (field.kind === "radio")
906103
+ return `${GLYPHS.status.active} `;
906104
+ return " ";
906105
+ }
906106
+ function fieldColor(wizard, field, selected) {
906107
+ if (selected)
906108
+ return FULLSCREEN_PALETTE.text;
906109
+ if (field.kind === "status" || field.kind === "modelPicker")
906110
+ return FULLSCREEN_PALETTE.info;
906111
+ if (field.kind === "masked")
906112
+ return FULLSCREEN_PALETTE.warn;
906113
+ if (field.kind === "acknowledgement")
906114
+ return wizard.getFieldValue(field) ? FULLSCREEN_PALETTE.good : FULLSCREEN_PALETTE.warn;
906115
+ if (field.kind === "checklist")
906116
+ return wizard.getFieldValue(field) ? FULLSCREEN_PALETTE.good : FULLSCREEN_PALETTE.muted;
906117
+ if (wizard.getFieldValueLabel(field) === "Missing")
906118
+ return FULLSCREEN_PALETTE.warn;
906119
+ return FULLSCREEN_PALETTE.text;
906120
+ }
906121
+ function formatEditingValue(value, multiline) {
906122
+ if (!multiline)
906123
+ return value;
906124
+ const lines = value.split(/\r?\n/);
906125
+ if (lines.length <= 1)
906126
+ return value;
906127
+ const preview4 = lines[lines.length - 1] ?? "";
906128
+ return `${preview4} (${lines.length} lines)`;
906129
+ }
906130
+ function fieldHint(wizard, field, selected) {
906131
+ if (selected && wizard.isEditingTextField() && wizard.editingFieldId === field.id && (field.kind === "text" || field.kind === "masked")) {
906132
+ const rawValue = wizard.editBuffer.length > 0 ? wizard.editBuffer : field.placeholder;
906133
+ 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);
906134
+ return `Editing: ${editingValue}${GLYPHS.surface.cursor}`;
906140
906135
  }
906141
- if (total > 0 && completed === total) {
906142
- return { glyph: "\u2713", fg: UI_TONES.state.good };
906136
+ if (selected && field.kind === "modelPicker")
906137
+ return `${field.hint} Press Enter to open picker.`;
906138
+ if (selected && field.kind === "text") {
906139
+ return field.multiline === true ? `${field.hint} Press Enter to edit; Ctrl-J inserts a new line.` : `${field.hint} Press Enter to edit inline.`;
906143
906140
  }
906144
- return { glyph: "\u2022", fg: UI_TONES.fg.muted };
906141
+ if (selected && field.kind === "masked")
906142
+ return `${field.hint} Press Enter to edit inline.`;
906143
+ return field.hint;
906145
906144
  }
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;
906145
+ function selectedFieldText(wizard) {
906146
+ if (wizard.isEditingTextField() && wizard.editingFieldId !== null) {
906147
+ const editingField = wizard.getFieldById(wizard.editingFieldId);
906148
+ if (editingField) {
906149
+ return {
906150
+ title: `Editing: ${editingField.label}`,
906151
+ hint: fieldHint(wizard, editingField, true)
906152
+ };
906153
+ }
906154
906154
  }
906155
- if (field.kind === "checklist") {
906156
- return wizard.getFieldValue(field) ? UI_TONES.state.good : UI_TONES.fg.muted;
906155
+ const field = wizard.getSelectedField();
906156
+ if (!field)
906157
+ return { title: "Selected: none", hint: "No selectable row is active on this screen." };
906158
+ return {
906159
+ title: `Selected: ${field.label} [${wizard.getFieldValueLabel(field)}]`,
906160
+ hint: fieldHint(wizard, field, true)
906161
+ };
906162
+ }
906163
+ function footerText4(wizard) {
906164
+ if (wizard.isEditingTextField()) {
906165
+ 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";
906157
906166
  }
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;
906167
+ return "Controls: [Enter] toggle/open \xB7 [Esc] close \xB7 [Tab/Shift+Tab] screen \xB7 [Up/Down] move \xB7 [Del/Ctrl+U] clear";
906168
+ }
906169
+ function controlsText(wizard) {
906170
+ if (wizard.isEditingTextField()) {
906171
+ 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.";
906166
906172
  }
906167
- return UI_TONES.fg.secondary;
906173
+ return "Controls: Enter selects, Del clears, Tab moves.";
906168
906174
  }
906169
906175
  function buildFieldRows(wizard, visibleFields, capacity) {
906170
906176
  wizard.ensureSelectionVisible(visibleFields);
@@ -906175,9 +906181,8 @@ function buildFieldRows(wizard, visibleFields, capacity) {
906175
906181
  const allRows = [];
906176
906182
  fields.forEach((field, absoluteIndex) => {
906177
906183
  const spacerRows = Math.max(0, field.spacerBeforeRows ?? 0);
906178
- for (let index = 0;index < spacerRows; index += 1) {
906184
+ for (let index = 0;index < spacerRows; index += 1)
906179
906185
  allRows.push({ kind: "empty" });
906180
- }
906181
906186
  allRows.push({ kind: "field", field, absoluteIndex });
906182
906187
  });
906183
906188
  const selectedFieldIndex = wizard.getSelectedFieldIndex();
@@ -906185,12 +906190,12 @@ function buildFieldRows(wizard, visibleFields, capacity) {
906185
906190
  const scrollFieldIndex = wizard.scrollOffsets[wizard.stepIndex] ?? 0;
906186
906191
  const scrollRowIndex = allRows.findIndex((row) => row.kind === "field" && row.absoluteIndex === scrollFieldIndex);
906187
906192
  const maxStart = Math.max(0, allRows.length - capacity);
906188
- let start2 = clamp3(scrollRowIndex >= 0 ? scrollRowIndex : 0, 0, maxStart);
906193
+ let start2 = Math.max(0, Math.min(scrollRowIndex >= 0 ? scrollRowIndex : 0, maxStart));
906189
906194
  if (selectedRowIndex < start2)
906190
906195
  start2 = selectedRowIndex;
906191
906196
  if (selectedRowIndex >= start2 + capacity)
906192
906197
  start2 = selectedRowIndex - capacity + 1;
906193
- start2 = clamp3(start2, 0, maxStart);
906198
+ start2 = Math.max(0, Math.min(start2, maxStart));
906194
906199
  if (capacity > 1 && start2 > 0 && selectedRowIndex === start2)
906195
906200
  start2 = Math.max(0, start2 - 1);
906196
906201
  if (capacity > 1 && start2 + capacity < allRows.length && selectedRowIndex === start2 + capacity - 1) {
@@ -906199,377 +906204,157 @@ function buildFieldRows(wizard, visibleFields, capacity) {
906199
906204
  rows.push(...allRows.slice(start2, start2 + capacity));
906200
906205
  const firstVisibleRow = rows[0];
906201
906206
  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
- };
906207
+ rows[0] = { kind: "moreAbove", text: `${GLYPHS.navigation.moreAbove} ${start2} more above` };
906206
906208
  }
906207
906209
  const hiddenBelow = Math.max(0, allRows.length - (start2 + capacity));
906208
906210
  const lastVisibleRow = rows[rows.length - 1];
906209
906211
  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
- };
906212
+ rows[rows.length - 1] = { kind: "moreBelow", text: `${GLYPHS.navigation.moreBelow} ${hiddenBelow} more below` };
906214
906213
  }
906215
906214
  while (rows.length < capacity)
906216
906215
  rows.push({ kind: "empty" });
906217
906216
  return rows.slice(0, capacity);
906218
906217
  }
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`;
906218
+ function pushWrapped(rows, text, width, options = {}) {
906219
+ if (text.length === 0) {
906220
+ rows.push({ text: "", kind: "empty" });
906221
+ return;
906224
906222
  }
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.`;
906223
+ for (const line2 of wrapText(text, Math.max(1, width))) {
906224
+ rows.push({ text: line2, ...options });
906229
906225
  }
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
906226
  }
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) {
906227
+ function buildStepRows(wizard, height) {
906228
+ const rendered = wizard.steps.map((step, stepIndex) => {
906229
+ const selected = stepIndex === wizard.stepIndex;
906230
+ const state4 = stepGlyph(wizard, step, stepIndex);
906231
+ const completion = `${wizard.getCompletedFieldCount(stepIndex)}/${wizard.getStepFieldCount(stepIndex)}`;
906270
906232
  return {
906271
- title: "Selected: none",
906272
- hint: "No selectable row is active on this screen."
906233
+ text: `${state4.glyph} ${stepIndex + 1}. ${step.shortLabel} ${completion}`,
906234
+ selected,
906235
+ kind: "item",
906236
+ fg: state4.fg,
906237
+ bold: selected
906273
906238
  };
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
906239
  });
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";
906240
+ const visible = Math.max(1, height);
906241
+ const window3 = stableWindow(rendered.length, wizard.stepIndex, visible);
906242
+ const rows = rendered.slice(window3.start, window3.end);
906243
+ if (window3.start > 0 && rows.length > 0) {
906244
+ rows[0] = { text: `${GLYPHS.navigation.moreAbove} ${window3.start} more step(s) above`, kind: "more", fg: FULLSCREEN_PALETTE.dim, dim: true };
906313
906245
  }
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.";
906246
+ if (window3.end < rendered.length && rows.length > 0) {
906247
+ rows[rows.length - 1] = { text: `${GLYPHS.navigation.moreBelow} ${rendered.length - window3.end} more step(s) below`, kind: "more", fg: FULLSCREEN_PALETTE.dim, dim: true };
906319
906248
  }
906320
- return "Controls: Enter selects, Del clears, Tab moves.";
906249
+ while (rows.length < height)
906250
+ rows.push({ text: "", kind: "empty" });
906251
+ return rows.slice(0, height);
906321
906252
  }
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)
906253
+ function buildContextRows2(wizard, width) {
906254
+ const step = wizard.currentStep;
906255
+ const selected = selectedFieldText(wizard);
906256
+ const rows = [
906257
+ { text: step.title, fg: FULLSCREEN_PALETTE.title, bold: true }
906358
906258
  ];
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
- });
906259
+ const pushSummaryRows = () => {
906260
+ rows.push({ text: "Summary", fg: FULLSCREEN_PALETTE.subtitle, bold: true });
906261
+ rows.push({ text: step.summaryTitle, fg: FULLSCREEN_PALETTE.info, bold: true });
906262
+ for (const line2 of step.summaryLines.slice(0, 4)) {
906263
+ pushWrapped(rows, line2, width, { fg: FULLSCREEN_PALETTE.text });
906458
906264
  }
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);
906265
+ rows.push({
906266
+ text: `Fields ${wizard.getCompletedFieldCount(wizard.stepIndex)}/${wizard.getStepFieldCount(wizard.stepIndex)} complete \xB7 ${changedScreensLabel(wizard)}`,
906267
+ fg: wizard.dirtyStepCount > 0 ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.muted
906268
+ });
906269
+ };
906270
+ const pushSelectedRows = () => {
906271
+ rows.push({ text: selected.title, fg: FULLSCREEN_PALETTE.info, bold: true });
906272
+ pushWrapped(rows, selected.hint, width, { fg: FULLSCREEN_PALETTE.text });
906273
+ pushWrapped(rows, controlsText(wizard), width, { fg: FULLSCREEN_PALETTE.info });
906274
+ };
906275
+ pushWrapped(rows, step.description, width, { fg: FULLSCREEN_PALETTE.text });
906276
+ rows.push({ text: "", kind: "empty" });
906277
+ if (wizard.isEditingTextField()) {
906278
+ pushSelectedRows();
906279
+ rows.push({ text: "", kind: "empty" });
906280
+ pushSummaryRows();
906281
+ } else {
906282
+ pushSummaryRows();
906283
+ rows.push({ text: "", kind: "empty" });
906284
+ pushSelectedRows();
906469
906285
  }
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);
906286
+ if (wizard.hydrationPending || wizard.hydrationError !== null || wizard.applyFeedback !== null) {
906287
+ rows.push({ text: "", kind: "empty" });
906288
+ }
906289
+ if (wizard.hydrationPending) {
906290
+ rows.push({ text: "Loading current settings...", fg: FULLSCREEN_PALETTE.info, bold: true });
906291
+ }
906292
+ if (wizard.hydrationError !== null) {
906293
+ pushWrapped(rows, `Current settings could not load: ${wizard.hydrationError}`, width, { fg: FULLSCREEN_PALETTE.bad, bold: true });
906294
+ }
906295
+ if (wizard.applyFeedback !== null) {
906296
+ const feedbackColor = wizard.applyFeedback.severity === "error" ? FULLSCREEN_PALETTE.bad : wizard.applyFeedback.severity === "warning" ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.info;
906297
+ rows.push({ text: wizard.applyFeedback.title, fg: feedbackColor, bold: true });
906298
+ pushWrapped(rows, wizard.applyFeedback.summary, width, { fg: FULLSCREEN_PALETTE.text });
906299
+ for (const message of wizard.applyFeedback.messages) {
906300
+ pushWrapped(rows, message, width, { fg: FULLSCREEN_PALETTE.muted });
906556
906301
  }
906557
- lines.push(line2);
906558
906302
  }
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
906303
+ return rows;
906304
+ }
906305
+ function formatFieldRowText(wizard, field, selected, width) {
906306
+ const badge = `[${wizard.getFieldValueLabel(field)}]`;
906307
+ const badgeWidth = getDisplayWidth(badge);
906308
+ const labelWidth = Math.max(1, width - badgeWidth - 2);
906309
+ const label = truncateDisplay(`${fieldRowPrefix(wizard, field, selected)}${field.label}`, labelWidth);
906310
+ return `${label}${" ".repeat(Math.max(1, width - getDisplayWidth(label) - badgeWidth))}${badge}`;
906311
+ }
906312
+ function buildControlRows2(wizard, width, height) {
906313
+ const visibleFields = Math.max(1, height);
906314
+ const fieldRows = buildFieldRows(wizard, visibleFields, height);
906315
+ const rows = fieldRows.map((row) => {
906316
+ if (row.kind === "empty")
906317
+ return { text: "", kind: "empty" };
906318
+ if (row.kind === "moreAbove" || row.kind === "moreBelow") {
906319
+ return { text: row.text, kind: "more", fg: FULLSCREEN_PALETTE.dim, dim: true };
906320
+ }
906321
+ const selected = row.absoluteIndex === wizard.getSelectedFieldIndex();
906322
+ return {
906323
+ text: formatFieldRowText(wizard, row.field, selected, width),
906324
+ selected,
906325
+ kind: "item",
906326
+ fg: fieldColor(wizard, row.field, selected),
906327
+ bold: selected || row.field.kind === "action"
906328
+ };
906565
906329
  });
906566
- lines.push(footer);
906567
- return lines.slice(0, viewportHeight);
906330
+ while (rows.length < height)
906331
+ rows.push({ text: "", kind: "empty" });
906332
+ return rows.slice(0, height);
906568
906333
  }
906569
906334
  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);
906335
+ const layoutOptions = {
906336
+ width,
906337
+ height: viewportHeight,
906338
+ leftWidth: width < 90 ? undefined : 30,
906339
+ contextRatio: 0.42,
906340
+ minContextRows: 8
906341
+ };
906342
+ const metrics = getFullscreenWorkspaceMetrics(layoutOptions);
906343
+ return renderFullscreenWorkspace({
906344
+ width,
906345
+ height: viewportHeight,
906346
+ title: "GoodVibes Agent / Onboarding Wizard",
906347
+ stateLabel: `${modeLabel(wizard.mode)} \xB7 ${wizard.stepIndex + 1}/${wizard.steps.length} \xB7 ${changedScreensLabel(wizard)}`,
906348
+ leftHeader: "Steps",
906349
+ mainHeader: wizard.currentStep.title,
906350
+ leftRows: buildStepRows(wizard, metrics.bodyRows),
906351
+ contextRows: buildContextRows2(wizard, metrics.contextWidth),
906352
+ controlRows: buildControlRows2(wizard, metrics.contextWidth, metrics.controlRows),
906353
+ footer: footerText4(wizard),
906354
+ leftWidth: layoutOptions.leftWidth,
906355
+ contextRatio: layoutOptions.contextRatio,
906356
+ minContextRows: layoutOptions.minContextRows
906357
+ });
906573
906358
  }
906574
906359
 
906575
906360
  // src/renderer/conversation-overlays.ts
@@ -906932,6 +906717,33 @@ function handleBlockingShellInput(options) {
906932
906717
  return { handled: false, pendingPermission, recoveryPending };
906933
906718
  }
906934
906719
 
906720
+ // src/shell/onboarding-fullscreen.ts
906721
+ function normalizeFullscreenViewport(lines, width, height) {
906722
+ const viewport = lines.slice(0, height).map((line2) => {
906723
+ if (line2.length === width)
906724
+ return line2;
906725
+ const next = createEmptyLine(width);
906726
+ for (let index = 0;index < Math.min(width, line2.length); index += 1) {
906727
+ next[index] = { ...line2[index] };
906728
+ }
906729
+ return next;
906730
+ });
906731
+ while (viewport.length < height)
906732
+ viewport.push(createEmptyLine(width));
906733
+ return viewport;
906734
+ }
906735
+ function createOnboardingFullscreenComposite(input, width, height) {
906736
+ const viewport = normalizeFullscreenViewport(input.modelPicker.active ? renderModelWorkspace(input.modelPicker, width, height) : renderOnboardingWizard(input.onboardingWizard, width, height), width, height);
906737
+ return {
906738
+ width,
906739
+ height,
906740
+ header: [],
906741
+ viewport,
906742
+ footer: [],
906743
+ panelWidth: 0
906744
+ };
906745
+ }
906746
+
906935
906747
  // src/shell/service-settings-sync.ts
906936
906748
  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
906749
  function syncServiceSettingToPlatform(runtime3, change, _options = {}) {
@@ -909440,6 +909252,13 @@ async function main() {
909440
909252
  const render = () => {
909441
909253
  const width = stdout.columns || 80;
909442
909254
  const height = stdout.rows || 24;
909255
+ if (input.onboardingWizard.active) {
909256
+ input.setPanelMouseLayout(null);
909257
+ activeConversationWidth = width;
909258
+ conversation.setSplashSuppressed(true);
909259
+ compositor.composite(createOnboardingFullscreenComposite(input, width, height));
909260
+ return;
909261
+ }
909443
909262
  const currentModel = providerRegistry.getCurrentModel();
909444
909263
  const sessionSnapshot = uiServices.readModels.session.getSnapshot();
909445
909264
  const headerLines = UIFactory.createHeader(width, currentModel.id, currentModel.provider, conversation.title || undefined);