@pellux/goodvibes-agent 1.0.36 → 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.36";
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,
@@ -887350,7 +887298,7 @@ function handleGuidanceOrWorkspaceAction(workspace, action2) {
887350
887298
  var AGENT_WORKSPACE_CATEGORIES = [
887351
887299
  {
887352
887300
  id: "home",
887353
- group: "HOME",
887301
+ group: "START",
887354
887302
  label: "Home",
887355
887303
  summary: "Main operator workspace for normal assistant work.",
887356
887304
  detail: "Use this as the primary Agent workspace: chat in the main conversation, inspect state, choose model/provider, and open setup without switching modes.",
@@ -887382,7 +887330,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887382
887330
  },
887383
887331
  {
887384
887332
  id: "setup",
887385
- group: "CONFIGURE",
887333
+ group: "START",
887386
887334
  label: "Setup",
887387
887335
  summary: "Configuration, auth, provider, and onboarding workspaces.",
887388
887336
  detail: "Use this to configure the assistant: provider/model, setup checklist, Agent Knowledge, local behavior, channels, and voice/media. Changes here stay Agent-owned.",
@@ -887441,7 +887389,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887441
887389
  },
887442
887390
  {
887443
887391
  id: "research",
887444
- group: "RESEARCH",
887392
+ group: "DAY-TO-DAY",
887445
887393
  label: "Research",
887446
887394
  summary: "Read-only web research and source triage in the main conversation.",
887447
887395
  detail: "Use this workspace to ask Agent to search, inspect URLs, compare sources, and decide what belongs in isolated Agent Knowledge. Research requests run in the normal conversation; source ingestion is explicit.",
@@ -887460,7 +887408,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887460
887408
  },
887461
887409
  {
887462
887410
  id: "artifacts",
887463
- group: "ARTIFACTS",
887411
+ group: "DAY-TO-DAY",
887464
887412
  label: "Artifacts",
887465
887413
  summary: "Files, attachments, exports, source ingest, and generated media.",
887466
887414
  detail: "Use this workspace to handle concrete user-visible artifacts: attach images, export conversations, ingest source files into Agent Knowledge, inspect source libraries, and generate media with explicit confirmation.",
@@ -887483,7 +887431,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887483
887431
  },
887484
887432
  {
887485
887433
  id: "conversation",
887486
- group: "CONVERSATION",
887434
+ group: "DAY-TO-DAY",
887487
887435
  label: "Conversation",
887488
887436
  summary: "Transcript, prompt, context, and session controls.",
887489
887437
  detail: "Use this workspace for the main TUI conversation: context review, compaction, prompt helpers, transcript navigation, session continuity, title, export, undo, redo, and retry.",
@@ -887528,7 +887476,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887528
887476
  },
887529
887477
  {
887530
887478
  id: "channels",
887531
- group: "CHANNELS",
887479
+ group: "CAPABILITIES",
887532
887480
  label: "Channels",
887533
887481
  summary: "Companion pairing, channel posture, and delivery safety.",
887534
887482
  detail: "Agent uses connected channel accounts. Pairing, account inspection, and readiness checks are visible here; inbound delivery and public channel exposure stay policy-gated.",
@@ -887556,7 +887504,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887556
887504
  },
887557
887505
  {
887558
887506
  id: "tools",
887559
- group: "TOOLS",
887507
+ group: "CAPABILITIES",
887560
887508
  label: "Tools & MCP",
887561
887509
  summary: "MCP server setup, trust review, and tool inventory.",
887562
887510
  detail: "Configure and inspect task tools from the Agent TUI. Adding or changing tools requires typed confirmation; normal chat still chooses tools serially in the main conversation.",
@@ -887587,7 +887535,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887587
887535
  },
887588
887536
  {
887589
887537
  id: "knowledge",
887590
- group: "KNOWLEDGE",
887538
+ group: "CAPABILITIES",
887591
887539
  label: "Knowledge",
887592
887540
  summary: "Agent Knowledge and source-backed lookup.",
887593
887541
  detail: "Agent knowledge calls use the isolated Agent Knowledge route family only. Default knowledge and non-Agent knowledge segments are not the Agent knowledge environment.",
@@ -887623,7 +887571,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887623
887571
  },
887624
887572
  {
887625
887573
  id: "voice-media",
887626
- group: "VOICE & MEDIA",
887574
+ group: "CAPABILITIES",
887627
887575
  label: "Voice & Media",
887628
887576
  summary: "Voice, TTS, image input, browser tools, and media providers.",
887629
887577
  detail: "Voice, media, browser tools, and image-capable flows are first-class Agent tools. Connected-host administration stays outside Agent and side effects stay explicit.",
@@ -887649,7 +887597,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887649
887597
  },
887650
887598
  {
887651
887599
  id: "profiles",
887652
- group: "PROFILES",
887600
+ group: "LOCAL BEHAVIOR",
887653
887601
  label: "Profiles",
887654
887602
  summary: "Isolated Agent homes, starter templates, and setup bundles.",
887655
887603
  detail: "Agent profiles isolate Agent state. Named homes and starter templates let one install behave like separate assistants for household, research, travel, operations, or personal workflows.",
@@ -887672,7 +887620,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887672
887620
  },
887673
887621
  {
887674
887622
  id: "memory",
887675
- group: "MEMORY",
887623
+ group: "LOCAL BEHAVIOR",
887676
887624
  label: "Memory & Skills",
887677
887625
  summary: "Local assistant memory, notes, routines, skills, and reusable behavior.",
887678
887626
  detail: "Memory, notes, routines, skills, and personas stay Agent-local until stable shared registry contracts exist. Secrets must not be stored as memory or notes.",
@@ -887709,7 +887657,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887709
887657
  },
887710
887658
  {
887711
887659
  id: "notes",
887712
- group: "NOTES",
887660
+ group: "LOCAL BEHAVIOR",
887713
887661
  label: "Notes",
887714
887662
  summary: "Agent-local scratchpad for source triage and temporary context.",
887715
887663
  detail: "Notes are local working context. They are useful for research notes, decisions in progress, and handoff notes, but they are not memory and are not Agent Knowledge.",
@@ -887732,7 +887680,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887732
887680
  },
887733
887681
  {
887734
887682
  id: "personas",
887735
- group: "PERSONAS",
887683
+ group: "LOCAL BEHAVIOR",
887736
887684
  label: "Personas",
887737
887685
  summary: "Local behavior profiles for the main assistant.",
887738
887686
  detail: "Personas shape the serial Agent in the main conversation. They are local behavior profiles, not separate Agent identities.",
@@ -887755,7 +887703,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887755
887703
  },
887756
887704
  {
887757
887705
  id: "skills",
887758
- group: "SKILLS",
887706
+ group: "LOCAL BEHAVIOR",
887759
887707
  label: "Skills",
887760
887708
  summary: "Reusable local procedures with setup readiness.",
887761
887709
  detail: "Skills are local, reviewable procedures with optional env/command requirements. Enabled skills inform the main conversation; secret-looking content is rejected.",
@@ -887790,7 +887738,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887790
887738
  },
887791
887739
  {
887792
887740
  id: "routines",
887793
- group: "ROUTINES",
887741
+ group: "LOCAL BEHAVIOR",
887794
887742
  label: "Routines",
887795
887743
  summary: "Repeatable workflows with setup readiness.",
887796
887744
  detail: "Routines run in the main conversation by default and can declare env/command requirements. Promotion to a connected schedule requires a real schedule command and --yes.",
@@ -887820,7 +887768,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887820
887768
  },
887821
887769
  {
887822
887770
  id: "work",
887823
- group: "WORK",
887771
+ group: "OPERATIONS",
887824
887772
  label: "Work & Approvals",
887825
887773
  summary: "Visible task state, work plan, and approval posture.",
887826
887774
  detail: "Use this workspace to inspect active operator state and update visible work-plan items from confirmed TUI forms.",
@@ -887874,7 +887822,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887874
887822
  },
887875
887823
  {
887876
887824
  id: "host",
887877
- group: "HOST",
887825
+ group: "OPERATIONS",
887878
887826
  label: "Connected Host",
887879
887827
  summary: "Connected-host health, tasks, sessions, channels, and automation.",
887880
887828
  detail: "Use this workspace to inspect the GoodVibes host surfaces that Agent can see: system health, remote routes, host tasks, sessions, channels, schedules, knowledge, media, MCP, provider auth, support bundles, and telemetry/config posture.",
@@ -887918,7 +887866,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887918
887866
  },
887919
887867
  {
887920
887868
  id: "automation",
887921
- group: "AUTOMATION",
887869
+ group: "OPERATIONS",
887922
887870
  label: "Automation",
887923
887871
  summary: "Reminders, schedule observability, and explicit routine promotion.",
887924
887872
  detail: "Agent does not create hidden local automation jobs. Confirmed reminders, reviewed routine promotion, and explicit run/pause/resume controls go through the connected host with confirmation.",
@@ -887945,7 +887893,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
887945
887893
  },
887946
887894
  {
887947
887895
  id: "delegate",
887948
- group: "DELEGATE",
887896
+ group: "OPERATIONS",
887949
887897
  label: "Build Delegation",
887950
887898
  summary: "Explicit handoff to GoodVibes TUI for code work.",
887951
887899
  detail: "Agent does not become the coding TUI. Build, implement, fix, patch, and review work must be handed to GoodVibes TUI with the full original ask and delegated review only when explicitly requested.",
@@ -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,378 +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 margin = width >= 64 ? 1 : 0;
906571
- const layout = createOverlayBoxLayout(width, margin, Math.max(20, width - margin * 2));
906572
- const collapsed = layout.innerWidth < 86;
906573
- 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
+ });
906574
906358
  }
906575
906359
 
906576
906360
  // src/renderer/conversation-overlays.ts
@@ -906933,6 +906717,33 @@ function handleBlockingShellInput(options) {
906933
906717
  return { handled: false, pendingPermission, recoveryPending };
906934
906718
  }
906935
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
+
906936
906747
  // src/shell/service-settings-sync.ts
906937
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.";
906938
906749
  function syncServiceSettingToPlatform(runtime3, change, _options = {}) {
@@ -909441,6 +909252,13 @@ async function main() {
909441
909252
  const render = () => {
909442
909253
  const width = stdout.columns || 80;
909443
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
+ }
909444
909262
  const currentModel = providerRegistry.getCurrentModel();
909445
909263
  const sessionSnapshot = uiServices.readModels.session.getSnapshot();
909446
909264
  const headerLines = UIFactory.createHeader(width, currentModel.id, currentModel.provider, conversation.title || undefined);