@pellux/goodvibes-agent 1.0.43 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/package/main.js +250 -232
- package/package.json +1 -1
- package/src/cli/tui-startup.ts +0 -2
- package/src/input/agent-workspace-activation.ts +5 -0
- package/src/input/agent-workspace-categories.ts +11 -0
- package/src/input/agent-workspace-types.ts +2 -1
- package/src/input/agent-workspace.ts +41 -0
- package/src/renderer/agent-workspace.ts +115 -275
- package/src/version.ts +1 -1
|
@@ -5,9 +5,9 @@ import type {
|
|
|
5
5
|
AgentWorkspaceLocalEditor,
|
|
6
6
|
AgentWorkspaceRuntimeSnapshot,
|
|
7
7
|
} from '../input/agent-workspace.ts';
|
|
8
|
-
import { formatAgentRecordReviewState
|
|
8
|
+
import { formatAgentRecordReviewState } from '../agent/record-labels.ts';
|
|
9
9
|
import type { Line } from '../types/grid.ts';
|
|
10
|
-
import { wrapText } from '../utils/terminal-width.ts';
|
|
10
|
+
import { truncateDisplay, wrapText } from '../utils/terminal-width.ts';
|
|
11
11
|
import { GLYPHS } from './ui-primitives.ts';
|
|
12
12
|
import {
|
|
13
13
|
getFullscreenWorkspaceMetrics,
|
|
@@ -81,6 +81,21 @@ function setupStatusLabel(status: AgentWorkspaceRuntimeSnapshot['setupChecklist'
|
|
|
81
81
|
: 'Optional';
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
function compactText(text: string, maxWidth = 104): string {
|
|
85
|
+
const normalized = text.replace(/\s+/g, ' ').trim();
|
|
86
|
+
if (normalized.length === 0) return '';
|
|
87
|
+
const firstSentence = normalized.match(/^.*?[.!?](?:\s|$)/)?.[0]?.trim();
|
|
88
|
+
const source = firstSentence && firstSentence.length <= maxWidth ? firstSentence : normalized;
|
|
89
|
+
return truncateDisplay(source, maxWidth, '...');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function actionMetaLine(action: AgentWorkspaceAction): ContextLine {
|
|
93
|
+
return {
|
|
94
|
+
text: `${actionCommand(action)}; ${action.safety}`,
|
|
95
|
+
fg: action.kind === 'command' ? PALETTE.info : safetyColor(action),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
84
99
|
function setupAttentionItems(snapshot: AgentWorkspaceRuntimeSnapshot, limit: number): AgentWorkspaceRuntimeSnapshot['setupChecklist'] {
|
|
85
100
|
return [
|
|
86
101
|
...snapshot.setupChecklist.filter((item) => item.status === 'blocked'),
|
|
@@ -145,54 +160,41 @@ function companionAccessLine(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLi
|
|
|
145
160
|
: 'missing';
|
|
146
161
|
const error = access.tokenError ? `; token read error ${access.tokenError}` : '';
|
|
147
162
|
return {
|
|
148
|
-
text: `Companion: ${access.surface}; token ${tokenState}; QR ${access.qrCommand}
|
|
163
|
+
text: `Companion: ${access.surface}; token ${tokenState}; QR ${access.qrCommand}${error}.`,
|
|
149
164
|
fg: access.pairingReady ? PALETTE.good : PALETTE.warn,
|
|
150
165
|
};
|
|
151
166
|
}
|
|
152
167
|
|
|
153
|
-
function
|
|
168
|
+
function compactLocalLibraryLines(
|
|
154
169
|
title: string,
|
|
155
170
|
items: readonly AgentWorkspaceRuntimeSnapshot['localPersonas'][number][],
|
|
156
171
|
emptyText: string,
|
|
157
172
|
selectedId: string | null,
|
|
158
173
|
): ContextLine[] {
|
|
159
|
-
const lines: ContextLine[] = [
|
|
160
|
-
{ text: title, fg: PALETTE.title, bold: true },
|
|
161
|
-
];
|
|
174
|
+
const lines: ContextLine[] = [];
|
|
162
175
|
if (items.length === 0) {
|
|
163
|
-
lines.push({ text: emptyText
|
|
176
|
+
lines.push({ text: `${title}: 0. ${emptyText}`, fg: PALETTE.warn });
|
|
164
177
|
return lines;
|
|
165
178
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
lines.push({
|
|
185
|
-
text: `${marker}${item.id}: ${item.name} (${status})`,
|
|
186
|
-
fg: item.reviewState === 'stale' ? PALETTE.warn : PALETTE.info,
|
|
187
|
-
bold: selected || item.active === true,
|
|
188
|
-
});
|
|
189
|
-
lines.push({ text: ` ${item.description}${tags}${triggers}`, fg: PALETTE.muted });
|
|
190
|
-
if (item.missingRequirements && item.missingRequirements.length > 0) {
|
|
191
|
-
lines.push({ text: ` missing setup: ${item.missingRequirements.join(', ')}`, fg: PALETTE.warn });
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
if (items.length > 8) {
|
|
195
|
-
lines.push({ text: `${items.length - 8} more item(s). Open the library command for the full list.`, fg: PALETTE.dim });
|
|
179
|
+
const selected = items.find((item) => item.id === selectedId) ?? items[0]!;
|
|
180
|
+
const status = [
|
|
181
|
+
selected.active ? 'active' : '',
|
|
182
|
+
selected.enabled === true ? 'enabled' : selected.enabled === false ? 'disabled' : '',
|
|
183
|
+
selected.scope && selected.cls ? `${selected.scope}/${selected.cls}` : '',
|
|
184
|
+
selected.confidence !== undefined ? `${selected.confidence}%` : '',
|
|
185
|
+
selected.requirementCount !== undefined && selected.requirementCount > 0
|
|
186
|
+
? (selected.missingRequirementCount && selected.missingRequirementCount > 0 ? `needs ${selected.missingRequirementCount}/${selected.requirementCount}` : `ready ${selected.requirementCount}/${selected.requirementCount}`)
|
|
187
|
+
: '',
|
|
188
|
+
formatAgentRecordReviewState(selected.reviewState),
|
|
189
|
+
selected.startCount !== undefined ? `starts ${selected.startCount}` : '',
|
|
190
|
+
].filter(Boolean).join(', ');
|
|
191
|
+
lines.push({
|
|
192
|
+
text: `${title}: ${items.length}; selected ${selected.name}${status ? ` (${status})` : ''}.`,
|
|
193
|
+
fg: selected.reviewState === 'stale' ? PALETTE.warn : PALETTE.info,
|
|
194
|
+
bold: selected.active === true,
|
|
195
|
+
});
|
|
196
|
+
if (selected.missingRequirements && selected.missingRequirements.length > 0) {
|
|
197
|
+
lines.push({ text: `Missing setup: ${selected.missingRequirements.join(', ')}`, fg: PALETTE.warn });
|
|
196
198
|
}
|
|
197
199
|
return lines;
|
|
198
200
|
}
|
|
@@ -239,23 +241,18 @@ function routineNextActionLine(snapshot: AgentWorkspaceRuntimeSnapshot): Context
|
|
|
239
241
|
return { text: 'Next routine action: Start selected in the main conversation, inspect receipts, or reconcile connected schedules.', fg: PALETTE.info, bold: true };
|
|
240
242
|
}
|
|
241
243
|
|
|
242
|
-
function
|
|
244
|
+
function compactRoutineReceiptLine(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine {
|
|
243
245
|
const latest = snapshot.latestRoutineScheduleReceipt;
|
|
244
|
-
|
|
245
|
-
{
|
|
246
|
-
text: `Promotion receipts: ${snapshot.routineScheduleReceiptCount}; created
|
|
247
|
-
fg:
|
|
248
|
-
}
|
|
249
|
-
];
|
|
250
|
-
if (latest) {
|
|
251
|
-
lines.push({
|
|
252
|
-
text: `Latest receipt: ${latest.id} ${latest.status} routine=${latest.routineId} schedule="${latest.scheduleName}" ${latest.scheduleKind} ${latest.scheduleValue}`,
|
|
253
|
-
fg: latest.status === 'failed' ? PALETTE.warn : PALETTE.good,
|
|
254
|
-
});
|
|
255
|
-
} else {
|
|
256
|
-
lines.push({ text: 'No schedule promotion receipts yet. Confirm a routine promotion from Automation when ready.', fg: PALETTE.muted });
|
|
246
|
+
if (!latest) {
|
|
247
|
+
return {
|
|
248
|
+
text: `Promotion receipts: ${snapshot.routineScheduleReceiptCount}; none created yet.`,
|
|
249
|
+
fg: PALETTE.muted,
|
|
250
|
+
};
|
|
257
251
|
}
|
|
258
|
-
return
|
|
252
|
+
return {
|
|
253
|
+
text: `Promotion receipts: ${snapshot.routineScheduleReceiptCount}; latest ${latest.status} ${latest.routineId}.`,
|
|
254
|
+
fg: latest.status === 'failed' ? PALETTE.warn : PALETTE.good,
|
|
255
|
+
};
|
|
259
256
|
}
|
|
260
257
|
|
|
261
258
|
function automationNextActionLine(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine {
|
|
@@ -277,57 +274,6 @@ function automationNextActionLine(snapshot: AgentWorkspaceRuntimeSnapshot): Cont
|
|
|
277
274
|
return { text: 'Next automation action: Create a reminder, or create/import a routine before recurring workflow promotion.', fg: PALETTE.warn, bold: true };
|
|
278
275
|
}
|
|
279
276
|
|
|
280
|
-
function profileLines(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine[] {
|
|
281
|
-
const lines: ContextLine[] = [
|
|
282
|
-
{ text: 'Agent Profiles', fg: PALETTE.title, bold: true },
|
|
283
|
-
];
|
|
284
|
-
if (snapshot.runtimeProfiles.length === 0) {
|
|
285
|
-
lines.push({ text: 'No isolated Agent profiles yet. Use Create Agent profile in this workspace.', fg: PALETTE.warn });
|
|
286
|
-
return lines;
|
|
287
|
-
}
|
|
288
|
-
for (const profile of snapshot.runtimeProfiles.slice(0, 6)) {
|
|
289
|
-
const starter = profile.starterTemplateId ? ` starter=${profile.starterTemplateId}` : ' starter=none';
|
|
290
|
-
const created = profile.createdAt ? ` created ${profile.createdAt.slice(0, 10)}` : '';
|
|
291
|
-
const states = [
|
|
292
|
-
profile.id === snapshot.activeRuntimeProfile ? 'active' : '',
|
|
293
|
-
profile.id === snapshot.selectedRuntimeProfile ? 'default' : '',
|
|
294
|
-
].filter(Boolean).join(', ');
|
|
295
|
-
const stateText = states ? ` [${states}]` : '';
|
|
296
|
-
lines.push({
|
|
297
|
-
text: `${profile.id}${stateText}${starter}${created}`,
|
|
298
|
-
fg: profile.id === snapshot.selectedRuntimeProfile ? PALETTE.good : PALETTE.info,
|
|
299
|
-
bold: profile.id === snapshot.activeRuntimeProfile || profile.id === snapshot.selectedRuntimeProfile,
|
|
300
|
-
});
|
|
301
|
-
lines.push({ text: ` home: ${profile.homeDirectory}`, fg: PALETTE.muted });
|
|
302
|
-
}
|
|
303
|
-
if (snapshot.runtimeProfiles.length > 6) {
|
|
304
|
-
lines.push({ text: `${snapshot.runtimeProfiles.length - 6} more profile(s).`, fg: PALETTE.dim });
|
|
305
|
-
}
|
|
306
|
-
return lines;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
function starterTemplateLines(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine[] {
|
|
310
|
-
const lines: ContextLine[] = [
|
|
311
|
-
{ text: 'Starter Templates', fg: PALETTE.title, bold: true },
|
|
312
|
-
];
|
|
313
|
-
for (const template of snapshot.runtimeStarterTemplates.slice(0, 6)) {
|
|
314
|
-
const origin = template.source === 'local' ? 'Local' : formatAgentRecordSource(template.source);
|
|
315
|
-
lines.push({
|
|
316
|
-
text: `${template.id}: ${template.name} [${origin}]`,
|
|
317
|
-
fg: template.source === 'local' ? PALETTE.good : PALETTE.info,
|
|
318
|
-
bold: template.id === 'research',
|
|
319
|
-
});
|
|
320
|
-
lines.push({
|
|
321
|
-
text: ` ${template.description} Persona ${template.personaName}; skills ${template.skillNames.join(', ')}; routines ${template.routineNames.join(', ')}.`,
|
|
322
|
-
fg: PALETTE.muted,
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
if (snapshot.runtimeStarterTemplates.length > 6) {
|
|
326
|
-
lines.push({ text: `${snapshot.runtimeStarterTemplates.length - 6} more starter template(s).`, fg: PALETTE.dim });
|
|
327
|
-
}
|
|
328
|
-
return lines;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
277
|
function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCategory, snapshot: AgentWorkspaceRuntimeSnapshot | null): ContextLine[] {
|
|
332
278
|
if (!snapshot) return [{ text: 'Runtime context is not loaded yet.', fg: PALETTE.warn }];
|
|
333
279
|
const base: ContextLine[] = [];
|
|
@@ -346,175 +292,89 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
|
|
|
346
292
|
} else if (category.id === 'artifacts') {
|
|
347
293
|
const mediaReady = snapshot.voiceMediaReadiness.readyMediaProviderCount;
|
|
348
294
|
base.push(
|
|
349
|
-
{ text: `Chat
|
|
350
|
-
{ text: `
|
|
351
|
-
{ text:
|
|
352
|
-
{ text: '
|
|
353
|
-
{ text: 'Agent Knowledge ingest writes only to the isolated Agent segment. Default knowledge and non-Agent routes are not fallback storage.', fg: PALETTE.warn },
|
|
354
|
-
{ text: 'Generated media is stored as artifacts and referenced by id; the TUI should not print inline base64.', fg: PALETTE.muted },
|
|
355
|
-
{ text: `Workspace path: ${snapshot.workingDirectory}`, fg: PALETTE.muted },
|
|
295
|
+
{ text: `Chat: ${snapshot.provider} / ${snapshot.modelDisplayName}; Knowledge: ${snapshot.knowledgeRoute}`, fg: PALETTE.info },
|
|
296
|
+
{ text: `Media: ${mediaReady}/${snapshot.mediaProviderCount} ready; generation ${snapshot.mediaGenerationProviderCount}.`, fg: mediaReady > 0 ? PALETTE.good : PALETTE.warn },
|
|
297
|
+
{ text: 'Files: attach, export, inspect, ingest reviewed sources, or generate media.', fg: PALETTE.good },
|
|
298
|
+
{ text: 'Knowledge ingest and media generation require explicit actions.', fg: PALETTE.warn },
|
|
356
299
|
);
|
|
357
300
|
} else if (category.id === 'channels') {
|
|
358
301
|
const enabledCount = snapshot.channels.filter((channel) => channel.enabled).length;
|
|
359
302
|
const readyCount = snapshot.channels.filter((channel) => channel.ready).length;
|
|
360
303
|
const configuredDefaults = snapshot.channels.filter((channel) => channel.defaultTarget === 'configured').length;
|
|
361
|
-
const readyChannels = snapshot.channels.filter((channel) => channel.ready).map((channel) => channel.label);
|
|
362
304
|
const needsTarget = snapshot.channels.filter((channel) => channel.setupState === 'needs-target');
|
|
363
305
|
const needsConfig = snapshot.channels.filter((channel) => channel.setupState === 'needs-config');
|
|
364
306
|
const nextAttentionChannel = needsConfig[0] ?? needsTarget[0] ?? snapshot.channels.find((channel) => !channel.enabled);
|
|
365
|
-
const disabledChannels = snapshot.channels.filter((channel) => !channel.enabled).map((channel) => channel.label);
|
|
366
|
-
const disabledPreview = disabledChannels.slice(0, 6).join(', ');
|
|
367
|
-
const disabledSuffix = disabledChannels.length > 6 ? `, +${disabledChannels.length - 6} more` : '';
|
|
368
|
-
const orderedChannels = [
|
|
369
|
-
...snapshot.channels.filter((channel) => channel.enabled),
|
|
370
|
-
...snapshot.channels.filter((channel) => !channel.enabled),
|
|
371
|
-
].slice(0, 3);
|
|
372
307
|
base.push(
|
|
373
|
-
{ text: `
|
|
308
|
+
{ text: `API: ${snapshot.runtimeBaseUrl}`, fg: PALETTE.info },
|
|
374
309
|
companionAccessLine(snapshot),
|
|
375
|
-
{ text: `
|
|
376
|
-
{ text:
|
|
377
|
-
{ text:
|
|
378
|
-
{ text: `Ready channels: ${readyChannels.join(', ') || 'none'}.`, fg: readyChannels.length > 0 ? PALETTE.good : PALETTE.warn },
|
|
379
|
-
{ text: `Needs default target: ${needsTarget.map((channel) => `${channel.label} -> ${channel.defaultTargetKeys.join('|')}`).join(', ') || 'none'}.`, fg: needsTarget.length > 0 ? PALETTE.warn : PALETTE.muted },
|
|
380
|
-
{ text: `Needs config: ${needsConfig.map((channel) => `${channel.label} -> ${channel.missingRequiredKeys.join('|')}`).join(', ') || 'none'}.`, fg: needsConfig.length > 0 ? PALETTE.warn : PALETTE.muted },
|
|
381
|
-
{ text: `Disabled channels: ${disabledPreview || 'none'}${disabledSuffix}.`, fg: PALETTE.dim },
|
|
382
|
-
{ text: 'Safety: no secret values; sends and public exposure require explicit user action and Agent policy.', fg: PALETTE.warn },
|
|
310
|
+
{ text: `Channels: ${readyCount}/${snapshot.channels.length} ready; ${enabledCount} enabled; ${configuredDefaults} target(s).`, fg: PALETTE.info },
|
|
311
|
+
{ text: `Next: ${nextAttentionChannel ? `${nextAttentionChannel.label} - ${compactText(nextAttentionChannel.nextStep)}` : 'All enabled channels ready.'}`, fg: nextAttentionChannel ? PALETTE.warn : PALETTE.good },
|
|
312
|
+
{ text: 'Safety: secrets hidden; sends require explicit action.', fg: PALETTE.warn },
|
|
383
313
|
);
|
|
384
|
-
for (const channel of orderedChannels) {
|
|
385
|
-
const ready = channel.ready ? 'ready' : `${channel.missingConfigCount} missing`;
|
|
386
|
-
base.push({
|
|
387
|
-
text: `${channel.label}: ${channel.setupState}; ${ready}; target ${channel.defaultTarget}; delivery ${channel.delivery}; risk ${channel.risk}.`,
|
|
388
|
-
fg: channel.ready ? PALETTE.good : channel.enabled ? PALETTE.warn : PALETTE.dim,
|
|
389
|
-
});
|
|
390
|
-
}
|
|
391
314
|
} else if (category.id === 'knowledge') {
|
|
392
315
|
base.push(
|
|
393
|
-
{ text: `Route
|
|
394
|
-
{ text:
|
|
395
|
-
{ text: 'Ingest
|
|
396
|
-
{ text: 'Review: queue, issues, candidates, reports, reindex, and consolidation stay inside the Agent segment.', fg: PALETTE.muted },
|
|
397
|
-
{ text: 'Agent-owned content appears here only after explicit Agent knowledge ingestion.', fg: PALETTE.muted },
|
|
316
|
+
{ text: `Route: ${snapshot.knowledgeRoute}; isolation ${snapshot.knowledgeIsolation}.`, fg: PALETTE.info },
|
|
317
|
+
{ text: 'Ask/search, ingest, review, reindex, and reports stay Agent-owned.', fg: PALETTE.good },
|
|
318
|
+
{ text: 'Ingest requires explicit confirmation.', fg: PALETTE.warn },
|
|
398
319
|
);
|
|
399
320
|
} else if (category.id === 'research') {
|
|
400
321
|
base.push(
|
|
401
|
-
{ text: `Chat
|
|
402
|
-
{ text: `
|
|
403
|
-
{ text:
|
|
404
|
-
{ text: snapshot.voiceMediaReadiness.browserToolNextStep, fg: PALETTE.muted },
|
|
405
|
-
{ text: 'Research requests are submitted to the main conversation. Agent may use connected read-only web tools when the user asks.', fg: PALETTE.good },
|
|
406
|
-
{ text: 'URL references and web research do not ingest into Agent Knowledge. Ingestion is a separate confirmed Agent Knowledge action.', fg: PALETTE.warn },
|
|
407
|
-
{ text: 'Use Agent Knowledge ask/search first for known source-backed context; use web research for current or external sources.', fg: PALETTE.info },
|
|
408
|
-
{ text: 'External sends, browser-side effects, package installs, and connected-host mutations are outside this read-only research lane.', fg: PALETTE.warn },
|
|
322
|
+
{ text: `Chat: ${snapshot.provider} / ${snapshot.modelDisplayName}; Knowledge: ${snapshot.knowledgeRoute}`, fg: PALETTE.info },
|
|
323
|
+
{ text: `Browser: ${snapshot.voiceMediaReadiness.browserToolState}; public URL ${snapshot.browserToolPublicBaseUrl}.`, fg: snapshot.browserToolExposureEnabled ? PALETTE.warn : PALETTE.muted },
|
|
324
|
+
{ text: 'Research is read-only. Knowledge ingest is a separate confirmed action.', fg: PALETTE.good },
|
|
325
|
+
{ text: compactText(snapshot.voiceMediaReadiness.browserToolNextStep), fg: PALETTE.muted },
|
|
409
326
|
);
|
|
410
327
|
} else if (category.id === 'tools') {
|
|
411
328
|
base.push(
|
|
412
329
|
{ text: `MCP servers: ${snapshot.mcpConnectedServerCount}/${snapshot.mcpServerCount} connected; quarantined ${snapshot.mcpQuarantinedServerCount}; allow-all ${snapshot.mcpAllowAllServerCount}.`, fg: snapshot.mcpQuarantinedServerCount > 0 || snapshot.mcpAllowAllServerCount > 0 ? PALETTE.warn : PALETTE.info },
|
|
413
|
-
{ text: '
|
|
414
|
-
{ text: '
|
|
415
|
-
{ text: 'Trust changes remain explicit; allow-all is kept behind the settings workspace.', fg: PALETTE.warn },
|
|
416
|
-
{ text: 'Useful first actions: /mcp review, /mcp tools, /mcp config, and Add MCP server.', fg: PALETTE.muted },
|
|
417
|
-
{ text: 'Normal assistant chat can use tools serially when policy allows; onboarding does not start hidden tool work.', fg: PALETTE.muted },
|
|
330
|
+
{ text: 'Add/update/reload and trust changes require confirmation.', fg: PALETTE.good },
|
|
331
|
+
{ text: 'Start: /mcp review, /mcp tools, /mcp config, Add MCP server.', fg: PALETTE.muted },
|
|
418
332
|
);
|
|
419
333
|
} else if (category.id === 'voice-media') {
|
|
420
334
|
const readiness = snapshot.voiceMediaReadiness;
|
|
421
|
-
const voiceRows = readiness.voiceProviders.slice(0, 6);
|
|
422
|
-
const mediaRows = readiness.mediaProviders.slice(0, 6);
|
|
423
|
-
base.push(
|
|
424
|
-
{ text: `Voice providers: ${snapshot.voiceProviderCount}; streaming TTS: ${snapshot.voiceStreamingProviderCount}; STT: ${snapshot.voiceSttProviderCount}; realtime: ${snapshot.voiceRealtimeProviderCount}.`, fg: PALETTE.info },
|
|
425
|
-
{ text: `Voice interaction: ${snapshot.voiceSurfaceEnabled ? 'enabled' : 'disabled'}; ready providers ${readiness.readyVoiceProviderCount}/${snapshot.voiceProviderCount}.`, fg: snapshot.voiceSurfaceEnabled ? PALETTE.warn : PALETTE.muted },
|
|
426
|
-
{ text: `TTS config: provider ${snapshot.ttsProvider}; voice ${snapshot.ttsVoice}; response model ${snapshot.ttsResponseModel}.`, fg: PALETTE.info },
|
|
427
|
-
{ text: `Selected TTS readiness: ${readiness.selectedTtsProviderLabel} -> ${readiness.selectedTtsProviderStatus}; voice ${readiness.ttsVoiceConfigured ? 'configured' : 'default'}; response route ${readiness.ttsResponseRouteConfigured ? 'configured' : 'chat route'}.`, fg: readiness.selectedTtsProviderStatus === 'ready' ? PALETTE.good : PALETTE.warn },
|
|
428
|
-
{ text: `Media providers: ${snapshot.mediaProviderCount}; understanding: ${snapshot.mediaUnderstandingProviderCount}; generation: ${snapshot.mediaGenerationProviderCount}.`, fg: PALETTE.info },
|
|
429
|
-
{ text: `Ready media providers: ${readiness.readyMediaProviderCount}/${snapshot.mediaProviderCount}.`, fg: readiness.readyMediaProviderCount > 0 ? PALETTE.good : PALETTE.warn },
|
|
430
|
-
{ text: `Browser tools: ${readiness.browserToolState}; public base URL ${snapshot.browserToolPublicBaseUrl}.`, fg: snapshot.browserToolExposureEnabled ? PALETTE.warn : PALETTE.muted },
|
|
431
|
-
{ text: readiness.browserToolNextStep, fg: PALETTE.muted },
|
|
432
|
-
{ text: 'Voice provider readiness', fg: PALETTE.title, bold: true },
|
|
433
|
-
);
|
|
434
|
-
for (const provider of voiceRows) {
|
|
435
|
-
const selected = provider.selected ? 'selected; ' : '';
|
|
436
|
-
const missing = provider.missingSecretKeyOptions.length > 0 ? `; needs ${provider.missingSecretKeyOptions.join('|')}` : '';
|
|
437
|
-
base.push({
|
|
438
|
-
text: `${provider.label}: ${selected}${provider.setupState}; ${provider.features.join(', ') || 'registered'}${missing}.`,
|
|
439
|
-
fg: provider.setupState === 'ready' ? PALETTE.good : provider.setupState === 'needs-secret' ? PALETTE.warn : PALETTE.muted,
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
if (snapshot.voiceProviderCount > voiceRows.length) base.push({ text: `${snapshot.voiceProviderCount - voiceRows.length} more voice provider(s).`, fg: PALETTE.dim });
|
|
443
|
-
base.push({ text: 'Media provider readiness', fg: PALETTE.title, bold: true });
|
|
444
|
-
for (const provider of mediaRows) {
|
|
445
|
-
const missing = provider.missingSecretKeyOptions.length > 0 ? `; needs ${provider.missingSecretKeyOptions.join('|')}` : '';
|
|
446
|
-
base.push({
|
|
447
|
-
text: `${provider.label}: ${provider.setupState}; ${provider.features.join(', ') || 'registered'}${missing}.`,
|
|
448
|
-
fg: provider.setupState === 'ready' ? PALETTE.good : provider.setupState === 'needs-secret' ? PALETTE.warn : PALETTE.muted,
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
if (snapshot.mediaProviderCount > mediaRows.length) base.push({ text: `${snapshot.mediaProviderCount - mediaRows.length} more media provider(s).`, fg: PALETTE.dim });
|
|
452
|
-
for (const step of readiness.nextSteps.slice(0, 4)) base.push({ text: `Next: ${step}`, fg: PALETTE.info });
|
|
453
335
|
base.push(
|
|
454
|
-
{ text:
|
|
455
|
-
{ text:
|
|
336
|
+
{ text: `Voice: ${readiness.readyVoiceProviderCount}/${snapshot.voiceProviderCount} ready; TTS ${snapshot.ttsProvider}; voice ${snapshot.ttsVoice}.`, fg: readiness.readyVoiceProviderCount > 0 ? PALETTE.good : PALETTE.warn },
|
|
337
|
+
{ text: `Media: ${readiness.readyMediaProviderCount}/${snapshot.mediaProviderCount} ready; generation ${snapshot.mediaGenerationProviderCount}.`, fg: readiness.readyMediaProviderCount > 0 ? PALETTE.good : PALETTE.warn },
|
|
338
|
+
{ text: `Browser: ${readiness.browserToolState}; public URL ${snapshot.browserToolPublicBaseUrl}.`, fg: snapshot.browserToolExposureEnabled ? PALETTE.warn : PALETTE.muted },
|
|
339
|
+
{ text: readiness.nextSteps[0] ? `Next: ${compactText(readiness.nextSteps[0])}` : 'Next: voice/media setup is ready.', fg: readiness.nextSteps.length > 0 ? PALETTE.info : PALETTE.good },
|
|
340
|
+
{ text: 'Secrets hidden; voice, browser, and media side effects require explicit action.', fg: PALETTE.warn },
|
|
456
341
|
);
|
|
457
342
|
} else if (category.id === 'profiles') {
|
|
458
343
|
const defaultProfile = snapshot.selectedRuntimeProfile
|
|
459
344
|
? `${snapshot.selectedRuntimeProfile}${snapshot.selectedRuntimeProfileExists ? '' : ' (missing)'}`
|
|
460
345
|
: '(base Agent home)';
|
|
461
346
|
base.push(
|
|
462
|
-
{ text: `
|
|
463
|
-
{ text: `
|
|
464
|
-
{ text: `
|
|
465
|
-
{ text:
|
|
466
|
-
{ text: `Starter ids: ${snapshot.runtimeStarterTemplates.map((template) => template.id).join(', ') || 'none'}`, fg: PALETTE.info },
|
|
467
|
-
{ text: 'Starter Templates', fg: PALETTE.title, bold: true },
|
|
468
|
-
{ text: `Agent profile root: ${snapshot.runtimeProfileRoot}`, fg: PALETTE.muted },
|
|
469
|
-
{ text: '' },
|
|
470
|
-
...profileLines(snapshot),
|
|
471
|
-
{ text: '' },
|
|
472
|
-
...starterTemplateLines(snapshot),
|
|
473
|
-
{ text: '' },
|
|
474
|
-
{ text: 'Named Agent profiles isolate local config, sessions, memory, personas, skills, routines, setup, and bundles.', fg: PALETTE.good },
|
|
475
|
-
{ text: 'Starter authoring: browse, export, edit, import, and create Agent profiles from inside this workspace.', fg: PALETTE.info },
|
|
476
|
-
{ text: 'The connected GoodVibes host stays shared unless that host is configured separately.', fg: PALETTE.warn },
|
|
477
|
-
{ text: 'Portable bundles require explicit export/import commands with real paths and --yes.', fg: PALETTE.muted },
|
|
347
|
+
{ text: `Profiles: active ${snapshot.activeRuntimeProfile}; default ${defaultProfile}.`, fg: snapshot.selectedRuntimeProfileExists || !snapshot.selectedRuntimeProfile ? PALETTE.info : PALETTE.warn },
|
|
348
|
+
{ text: `Local profiles: ${snapshot.runtimeProfileCount}; starters ${snapshot.runtimeStarterTemplateCount}; custom ${snapshot.localStarterTemplateCount}.`, fg: PALETTE.info },
|
|
349
|
+
{ text: `Starter ids: ${truncateDisplay(snapshot.runtimeStarterTemplates.map((template) => template.id).join(', ') || 'none', 96, '...')}`, fg: PALETTE.muted },
|
|
350
|
+
{ text: 'Profiles isolate local Agent config, sessions, memory, personas, skills, routines, setup, and bundles.', fg: PALETTE.good },
|
|
478
351
|
);
|
|
479
352
|
} else if (category.id === 'memory') {
|
|
480
353
|
base.push(
|
|
481
|
-
{ text: `
|
|
482
|
-
{ text: `
|
|
483
|
-
{ text: `
|
|
484
|
-
|
|
485
|
-
{ text:
|
|
486
|
-
{ text: `Local personas: ${snapshot.localPersonaCount}; active: ${snapshot.activePersonaName}`, fg: PALETTE.info },
|
|
487
|
-
{ text: 'Durable memory, scratchpad notes, routines, skills, and personas remain Agent-local until shared registry contracts exist.', fg: PALETTE.good },
|
|
488
|
-
{ text: 'Secrets are rejected/redacted; store secret references instead of secret values.', fg: PALETTE.warn },
|
|
489
|
-
{ text: '' },
|
|
490
|
-
...localLibraryLines('Agent Memory', snapshot.localMemories, 'No Agent memory yet. Create one here with Create memory.', workspace.selectedLocalLibraryItem('memory')?.id ?? null),
|
|
354
|
+
{ text: `Memory: ${snapshot.localMemoryCount}; prompt ${snapshot.localMemoryPromptActiveCount}; queue ${snapshot.localMemoryReviewQueueCount}; session ${snapshot.sessionMemoryCount}.`, fg: PALETTE.info },
|
|
355
|
+
{ text: `Notes: ${snapshot.localNoteCount}; skills ${snapshot.localSkillCount}/${snapshot.enabledSkillCount}; routines ${snapshot.localRoutineCount}/${snapshot.enabledRoutineCount}; personas ${snapshot.localPersonaCount}.`, fg: PALETTE.info },
|
|
356
|
+
{ text: `Active persona: ${snapshot.activePersonaName}.`, fg: PALETTE.info },
|
|
357
|
+
...compactLocalLibraryLines('Agent Memory', snapshot.localMemories, 'Create one with Create memory.', workspace.selectedLocalLibraryItem('memory')?.id ?? null),
|
|
358
|
+
{ text: 'Secrets are rejected or redacted; use secret references.', fg: PALETTE.warn },
|
|
491
359
|
);
|
|
492
360
|
} else if (category.id === 'notes') {
|
|
493
361
|
base.push(
|
|
494
362
|
{ text: `Scratchpad notes: ${snapshot.localNoteCount}; review queue: ${snapshot.localNoteReviewQueueCount}`, fg: PALETTE.info },
|
|
495
|
-
|
|
496
|
-
{ text: 'Notes
|
|
497
|
-
{ text: 'Use reviewed notes to prefill durable memory, skills, routines, or personas, or to decide that a reviewed source deserves Agent Knowledge ingest.', fg: PALETTE.muted },
|
|
498
|
-
{ text: '' },
|
|
499
|
-
...localLibraryLines('Scratchpad Notes', snapshot.localNotes, 'No local notes yet. Create one here with Create note.', workspace.selectedLocalLibraryItem('note')?.id ?? null),
|
|
363
|
+
...compactLocalLibraryLines('Scratchpad Notes', snapshot.localNotes, 'Create one with Create note.', workspace.selectedLocalLibraryItem('note')?.id ?? null),
|
|
364
|
+
{ text: 'Notes stay local unless promoted by explicit action.', fg: PALETTE.warn },
|
|
500
365
|
);
|
|
501
366
|
} else if (category.id === 'personas') {
|
|
502
367
|
base.push(
|
|
503
368
|
{ text: `Personas: ${snapshot.localPersonaCount}; active: ${snapshot.activePersonaName}`, fg: PALETTE.info },
|
|
504
|
-
|
|
505
|
-
{ text: '
|
|
506
|
-
{ text: '' },
|
|
507
|
-
...localLibraryLines('Persona Library', snapshot.localPersonas, 'No local personas yet. Create one here with Create persona.', workspace.selectedLocalLibraryItem('persona')?.id ?? null),
|
|
369
|
+
...compactLocalLibraryLines('Persona Library', snapshot.localPersonas, 'Create one with Create persona.', workspace.selectedLocalLibraryItem('persona')?.id ?? null),
|
|
370
|
+
{ text: 'Personas shape the serial main-conversation assistant.', fg: PALETTE.good },
|
|
508
371
|
);
|
|
509
372
|
} else if (category.id === 'skills') {
|
|
510
373
|
base.push(
|
|
511
374
|
{ text: `Skills: ${snapshot.localSkillCount}; enabled: ${snapshot.enabledSkillCount}; bundles: ${snapshot.localSkillBundleCount}; enabled bundles: ${snapshot.enabledSkillBundleCount}; active skills: ${snapshot.activeSkillCount}`, fg: PALETTE.info },
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
{ text: '' },
|
|
515
|
-
...localLibraryLines('Skill Library', snapshot.localSkills, 'No local skills yet. Create one here with Create skill.', workspace.selectedLocalLibraryItem('skill')?.id ?? null),
|
|
516
|
-
{ text: '' },
|
|
517
|
-
...localLibraryLines('Skill Bundles', snapshot.localSkillBundles, 'No local skill bundles yet. Use Skill bundles and Create bundle after creating skills.', null),
|
|
375
|
+
...compactLocalLibraryLines('Skill Library', snapshot.localSkills, 'Create one with Create skill.', workspace.selectedLocalLibraryItem('skill')?.id ?? null),
|
|
376
|
+
...compactLocalLibraryLines('Skill Bundles', snapshot.localSkillBundles, 'Create one after adding skills.', null),
|
|
377
|
+
{ text: 'Enabled skills/bundles become operating guidance; secrets are rejected.', fg: PALETTE.warn },
|
|
518
378
|
);
|
|
519
379
|
} else if (category.id === 'routines') {
|
|
520
380
|
const ready = readyRoutineItems(snapshot);
|
|
@@ -523,42 +383,40 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
|
|
|
523
383
|
base.push(
|
|
524
384
|
{ text: `Routines: ${snapshot.localRoutineCount}; enabled: ${snapshot.enabledRoutineCount}`, fg: PALETTE.info },
|
|
525
385
|
{ text: `Schedule-ready routines: ${ready.length}; setup gaps: ${needsSetup.length}; review needed: ${needsReview.length}`, fg: needsSetup.length > 0 || needsReview.length > 0 ? PALETTE.warn : PALETTE.good },
|
|
526
|
-
{ text: 'Routines are repeatable main-conversation workflows. Starting one does not create hidden jobs.', fg: PALETTE.good },
|
|
527
|
-
{ text: 'Scheduling a reviewed routine is explicit and requires a confirmed schedule command.', fg: PALETTE.warn },
|
|
528
386
|
routineNextActionLine(snapshot),
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
387
|
+
compactRoutineReceiptLine(snapshot),
|
|
388
|
+
...compactLocalLibraryLines('Routine Library', snapshot.localRoutines, 'Create one with Create routine.', workspace.selectedLocalLibraryItem('routine')?.id ?? null),
|
|
389
|
+
{ text: 'Scheduling requires a confirmed action.', fg: PALETTE.warn },
|
|
532
390
|
);
|
|
533
391
|
} else if (category.id === 'work') {
|
|
534
392
|
base.push(
|
|
535
|
-
{ text: 'Work
|
|
536
|
-
{ text: '
|
|
537
|
-
{ text: '
|
|
393
|
+
{ text: 'Work plans and approvals are read or explicitly confirmed.', fg: PALETTE.info },
|
|
394
|
+
{ text: 'Selection alone does not approve, deny, cancel, or mutate requests.', fg: PALETTE.good },
|
|
395
|
+
{ text: 'Approval actions require id plus typed confirmation.', fg: PALETTE.warn },
|
|
538
396
|
);
|
|
539
397
|
} else if (category.id === 'automation') {
|
|
540
398
|
const ready = readyRoutineItems(snapshot);
|
|
541
399
|
base.push(
|
|
542
|
-
{ text:
|
|
543
|
-
{ text: 'Confirmed reminders and routine promotion use connected schedules only.', fg: PALETTE.info },
|
|
544
|
-
{ text: 'Local scheduler mutation controls remain blocked; job/run/schedule controls go through the connected host.', fg: PALETTE.warn },
|
|
545
|
-
{ text: 'Reminder path: Create reminder -> choose at/every/cron -> optional delivery target -> confirm yes.', fg: PALETTE.good },
|
|
546
|
-
{ text: 'Operator path: choose job/run/schedule action -> enter id -> type yes -> dispatch once.', fg: PALETTE.good },
|
|
547
|
-
{ text: 'Routine path: Routines -> resolve setup -> review selected -> Promote routine -> Reconcile schedules.', fg: PALETTE.good },
|
|
548
|
-
{ text: `Schedule-ready routines: ${ready.length}; local promotion receipts: ${snapshot.routineScheduleReceiptCount}`, fg: ready.length > 0 ? PALETTE.good : PALETTE.warn },
|
|
400
|
+
{ text: `Automation: ${ready.length} schedule-ready routine(s); receipts ${snapshot.routineScheduleReceiptCount}.`, fg: ready.length > 0 ? PALETTE.good : PALETTE.warn },
|
|
549
401
|
automationNextActionLine(snapshot),
|
|
550
|
-
|
|
402
|
+
compactRoutineReceiptLine(snapshot),
|
|
403
|
+
{ text: 'Reminders and routine promotion require confirmation.', fg: PALETTE.warn },
|
|
551
404
|
);
|
|
552
405
|
} else if (category.id === 'delegate') {
|
|
553
406
|
base.push(
|
|
554
|
-
{ text: 'Build/fix/review work is handed to GoodVibes TUI
|
|
407
|
+
{ text: 'Build/fix/review work is handed to GoodVibes TUI.', fg: PALETTE.info },
|
|
555
408
|
{ text: `Delegated review policy: ${snapshot.delegatedReviewPolicy}`, fg: PALETTE.warn },
|
|
556
|
-
{ text: '
|
|
409
|
+
{ text: 'No coding-role Agent jobs are created here.', fg: PALETTE.good },
|
|
410
|
+
);
|
|
411
|
+
} else if (category.id === 'finish') {
|
|
412
|
+
base.push(
|
|
413
|
+
{ text: 'Apply & close marks onboarding finished for this user.', fg: PALETTE.good },
|
|
414
|
+
{ text: 'Future normal launches start in the main conversation.', fg: PALETTE.info },
|
|
415
|
+
{ text: 'Use /agent, /setup, or /onboarding to reopen this workspace later.', fg: PALETTE.muted },
|
|
557
416
|
);
|
|
558
417
|
}
|
|
559
418
|
if (snapshot.warnings.length > 0) {
|
|
560
|
-
base.push({ text:
|
|
561
|
-
for (const warning of snapshot.warnings) base.push({ text: warning, fg: PALETTE.warn });
|
|
419
|
+
base.push({ text: `Warnings: ${snapshot.warnings.map((warning) => compactText(warning, 60)).join('; ')}`, fg: PALETTE.warn });
|
|
562
420
|
}
|
|
563
421
|
return base;
|
|
564
422
|
}
|
|
@@ -567,30 +425,23 @@ function editorContextLines(editor: AgentWorkspaceLocalEditor): ContextLine[] {
|
|
|
567
425
|
const selected = editor.fields[editor.selectedFieldIndex];
|
|
568
426
|
const lines: ContextLine[] = [
|
|
569
427
|
{ text: editor.title, fg: PALETTE.title, bold: true },
|
|
570
|
-
{ text: editor.message, fg: editor.message.includes('required') || editor.message.includes('cannot') || editor.message.includes('Cannot') ? PALETTE.warn : PALETTE.info },
|
|
571
|
-
{ text: 'Enter
|
|
428
|
+
{ text: compactText(editor.message), fg: editor.message.includes('required') || editor.message.includes('cannot') || editor.message.includes('Cannot') ? PALETTE.warn : PALETTE.info },
|
|
429
|
+
{ text: 'Enter next/save; Ctrl-J newline; Esc cancel.', fg: PALETTE.muted },
|
|
572
430
|
];
|
|
573
431
|
if (selected) {
|
|
574
432
|
lines.push(
|
|
575
|
-
{ text: '' },
|
|
576
433
|
{ text: `Editing: ${selected.label}${selected.required ? ' (required)' : ''}`, fg: PALETTE.title, bold: true },
|
|
577
|
-
{ text: selected.hint, fg: PALETTE.muted },
|
|
434
|
+
{ text: compactText(selected.hint), fg: PALETTE.muted },
|
|
578
435
|
);
|
|
579
436
|
}
|
|
580
437
|
return lines;
|
|
581
438
|
}
|
|
582
439
|
|
|
583
440
|
function buildContextRows(workspace: AgentWorkspace, category: AgentWorkspaceCategory, action: AgentWorkspaceAction | null, width: number): WorkspaceRow[] {
|
|
584
|
-
const compactPrimarySurface = category.id === 'home' || category.id === 'setup';
|
|
585
441
|
const lines: ContextLine[] = [
|
|
586
442
|
{ text: category.label, fg: PALETTE.title, bold: true },
|
|
587
443
|
{ text: category.summary, fg: PALETTE.subtitle },
|
|
588
|
-
...(compactPrimarySurface ? [] : [
|
|
589
|
-
{ text: '' },
|
|
590
|
-
{ text: category.detail, fg: PALETTE.text },
|
|
591
|
-
] satisfies ContextLine[]),
|
|
592
444
|
...(workspace.actionSearchActive ? [
|
|
593
|
-
{ text: '' },
|
|
594
445
|
{ text: 'Action Search', fg: PALETTE.title, bold: true },
|
|
595
446
|
{
|
|
596
447
|
text: workspace.actionSearchQuery.length > 0
|
|
@@ -598,35 +449,25 @@ function buildContextRows(workspace: AgentWorkspace, category: AgentWorkspaceCat
|
|
|
598
449
|
: 'Type to search every Agent workspace action.',
|
|
599
450
|
fg: workspace.actionSearchQuery.length > 0 && workspace.actionSearchResults.length === 0 ? PALETTE.warn : PALETTE.info,
|
|
600
451
|
},
|
|
601
|
-
{ text: 'Enter opens
|
|
602
|
-
{ text: '' },
|
|
452
|
+
{ text: 'Enter opens; Esc clears.', fg: PALETTE.muted },
|
|
603
453
|
] satisfies ContextLine[] : []),
|
|
604
454
|
...(workspace.localEditor ? editorContextLines(workspace.localEditor) : []),
|
|
605
|
-
...(workspace.localEditor ? [{ text: '' }] : []),
|
|
606
455
|
];
|
|
607
456
|
|
|
608
457
|
const selectedActionLines: ContextLine[] = action
|
|
609
458
|
? [
|
|
610
|
-
{ text: '' },
|
|
611
459
|
{ text: `Selected: ${action.label}`, fg: PALETTE.title, bold: true },
|
|
612
|
-
|
|
613
|
-
{ text: `Command: ${actionCommand(action)}`, fg: action.kind === 'command' ? PALETTE.info : PALETTE.muted },
|
|
614
|
-
{ text: `Safety: ${action.safety}`, fg: safetyColor(action) },
|
|
460
|
+
actionMetaLine(action),
|
|
615
461
|
]
|
|
616
462
|
: [];
|
|
617
|
-
const snapshotContextLines
|
|
618
|
-
|
|
619
|
-
...snapshotLines(workspace, category, workspace.runtimeSnapshot),
|
|
620
|
-
];
|
|
621
|
-
if (compactPrimarySurface) lines.push(...selectedActionLines, ...snapshotContextLines);
|
|
622
|
-
else lines.push(...snapshotContextLines, ...selectedActionLines);
|
|
463
|
+
const snapshotContextLines = snapshotLines(workspace, category, workspace.runtimeSnapshot);
|
|
464
|
+
lines.push(...selectedActionLines, ...snapshotContextLines);
|
|
623
465
|
|
|
624
466
|
if (workspace.lastActionResult) {
|
|
625
467
|
lines.push(
|
|
626
|
-
{ text: '' },
|
|
627
468
|
{ text: 'Action Result', fg: PALETTE.title, bold: true },
|
|
628
469
|
{ text: workspace.lastActionResult.title, fg: actionResultColor(workspace.lastActionResult), bold: true },
|
|
629
|
-
{ text: workspace.lastActionResult.detail, fg: PALETTE.text },
|
|
470
|
+
{ text: compactText(workspace.lastActionResult.detail), fg: PALETTE.text },
|
|
630
471
|
);
|
|
631
472
|
if (workspace.lastActionResult.command) {
|
|
632
473
|
lines.push({ text: `Command: ${workspace.lastActionResult.command}`, fg: PALETTE.muted });
|
|
@@ -762,12 +603,11 @@ function footerText(workspace: AgentWorkspace): string {
|
|
|
762
603
|
export function renderAgentWorkspace(workspace: AgentWorkspace, width: number, height: number): Line[] {
|
|
763
604
|
const category = workspace.selectedActionCategory;
|
|
764
605
|
const action = workspace.selectedAction;
|
|
765
|
-
const compactPrimarySurface = category.id === 'home' || category.id === 'setup';
|
|
766
606
|
const layoutOptions = {
|
|
767
607
|
width,
|
|
768
608
|
height,
|
|
769
609
|
leftWidth: width < 90 ? undefined : 30,
|
|
770
|
-
contextRatio:
|
|
610
|
+
contextRatio: 0.4,
|
|
771
611
|
minContextRows: 10,
|
|
772
612
|
};
|
|
773
613
|
const metrics = getFullscreenWorkspaceMetrics(layoutOptions);
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '1.0
|
|
9
|
+
let _version = '1.1.0';
|
|
10
10
|
try {
|
|
11
11
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|
|
12
12
|
readonly version?: unknown;
|