@pellux/goodvibes-agent 1.3.0 → 1.4.1
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 +35 -0
- package/dist/package/{ast-grep-napi.linux-x64-gnu-swtppvy9.node → ast-grep-napi.linux-x64-gnu-mkk8xwww.node} +0 -0
- package/dist/package/{ast-grep-napi.linux-x64-musl-ttfcdtap.node → ast-grep-napi.linux-x64-musl-ryqtgdv6.node} +0 -0
- package/dist/package/main.js +56050 -53798
- package/package.json +1 -1
- package/release/release-notes.md +15 -156
- package/src/agent/competitive-feature-inventory.ts +1 -1
- package/src/agent/setup-wizard.ts +28 -21
- package/src/cli/tui-startup.ts +2 -2
- package/src/input/agent-workspace-activation.ts +2 -2
- package/src/input/agent-workspace-onboarding-finish.ts +21 -0
- package/src/input/agent-workspace-settings.ts +14 -19
- package/src/input/agent-workspace-setup-snapshot.ts +2 -10
- package/src/input/agent-workspace-setup.ts +14 -47
- package/src/input/agent-workspace-snapshot.ts +0 -7
- package/src/input/agent-workspace-types.ts +5 -2
- package/src/input/agent-workspace.ts +19 -8
- package/src/input/handler.ts +67 -5
- package/src/renderer/agent-workspace-context-lines.ts +11 -42
- package/src/renderer/agent-workspace.ts +408 -31
- package/src/tools/agent-harness-setup-posture.ts +7 -7
- package/src/version.ts +1 -1
|
@@ -5,6 +5,8 @@ import type {
|
|
|
5
5
|
AgentWorkspaceLocalEditor,
|
|
6
6
|
AgentWorkspaceRuntimeSnapshot,
|
|
7
7
|
} from '../input/agent-workspace.ts';
|
|
8
|
+
import type { AgentWorkspaceEditorKind } from '../input/agent-workspace-types.ts';
|
|
9
|
+
import type { AgentWorkspaceSetupChecklistItem } from '../input/agent-workspace-setup.ts';
|
|
8
10
|
import type { Line } from '../types/grid.ts';
|
|
9
11
|
import { wrapText } from '../utils/terminal-width.ts';
|
|
10
12
|
import { GLYPHS } from './ui-primitives.ts';
|
|
@@ -18,11 +20,36 @@ import {
|
|
|
18
20
|
} from './fullscreen-workspace.ts';
|
|
19
21
|
import { actionResultColor, type AgentWorkspaceContextLine as ContextLine } from './agent-workspace-style.ts';
|
|
20
22
|
import { compactText, reviewerReadinessContextLines, snapshotLines } from './agent-workspace-context-lines.ts';
|
|
23
|
+
import { ONBOARDING_COMPLETE_SYNTHETIC_ACTION, ONBOARDING_CRITICAL_STEP_IDS } from '../input/agent-workspace-onboarding-finish.ts';
|
|
24
|
+
|
|
25
|
+
function onboardingCategoryReadiness(
|
|
26
|
+
category: AgentWorkspaceCategory,
|
|
27
|
+
checklist: readonly AgentWorkspaceSetupChecklistItem[],
|
|
28
|
+
): 'ready' | 'attention' | 'optional' {
|
|
29
|
+
const CATEGORY_CHECKLIST_MAP: Record<string, readonly string[]> = {
|
|
30
|
+
'setup': ['provider-model', 'connected-host-auth', 'runtime'],
|
|
31
|
+
'account-model': ['provider-model', 'subscriptions'],
|
|
32
|
+
'assistant-behavior': [],
|
|
33
|
+
'tools-permissions': [],
|
|
34
|
+
'onboarding-display': [],
|
|
35
|
+
'onboarding-channels': ['channels'],
|
|
36
|
+
'onboarding-voice-media': ['voice-media'],
|
|
37
|
+
'onboarding-context': ['agent-knowledge', 'persona', 'skills', 'routines', 'memory', 'notes', 'profile'],
|
|
38
|
+
'onboarding-automation': [],
|
|
39
|
+
};
|
|
40
|
+
const itemIds = CATEGORY_CHECKLIST_MAP[category.id];
|
|
41
|
+
if (!itemIds || itemIds.length === 0) return 'optional';
|
|
42
|
+
const mapped = itemIds.map((id) => checklist.find((item) => item.id === id));
|
|
43
|
+
if (mapped.every((item) => item?.status === 'ready')) return 'ready';
|
|
44
|
+
if (mapped.some((item) => item?.status === 'blocked' || item?.status === 'recommended')) return 'attention';
|
|
45
|
+
return 'optional';
|
|
46
|
+
}
|
|
21
47
|
|
|
22
48
|
function buildLeftRows(workspace: AgentWorkspace, height: number): WorkspaceRow[] {
|
|
23
49
|
const rows: WorkspaceRow[] = [];
|
|
24
50
|
let selectedRenderedIndex = 0;
|
|
25
51
|
let lastGroup = '';
|
|
52
|
+
const checklist = workspace.runtimeSnapshot?.setupChecklist ?? [];
|
|
26
53
|
|
|
27
54
|
workspace.categories.forEach((category, index) => {
|
|
28
55
|
if (category.group !== lastGroup) {
|
|
@@ -32,11 +59,24 @@ function buildLeftRows(workspace: AgentWorkspace, height: number): WorkspaceRow[
|
|
|
32
59
|
const selected = index === workspace.selectedCategoryIndex;
|
|
33
60
|
if (selected) selectedRenderedIndex = rows.length;
|
|
34
61
|
const marker = selected ? GLYPHS.navigation.selected : ' ';
|
|
62
|
+
let readinessGlyph = '';
|
|
63
|
+
let readinessFg: string | undefined;
|
|
64
|
+
if (isOnboardingCategory(category)) {
|
|
65
|
+
const readiness = onboardingCategoryReadiness(category, checklist);
|
|
66
|
+
if (readiness === 'ready') {
|
|
67
|
+
readinessGlyph = GLYPHS.status.success;
|
|
68
|
+
readinessFg = PALETTE.good;
|
|
69
|
+
} else if (readiness === 'attention') {
|
|
70
|
+
readinessGlyph = '!';
|
|
71
|
+
readinessFg = PALETTE.warn;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const readinessMark = readinessGlyph ? `${readinessGlyph} ` : ' ';
|
|
35
75
|
rows.push({
|
|
36
|
-
text: ` ${marker} ${category.label}`,
|
|
76
|
+
text: ` ${marker} ${readinessMark}${category.label}`,
|
|
37
77
|
selected: selected && workspace.focusPane === 'categories',
|
|
38
78
|
kind: 'item',
|
|
39
|
-
fg: selected ? PALETTE.text : PALETTE.muted,
|
|
79
|
+
fg: selected ? PALETTE.text : readinessFg ?? PALETTE.muted,
|
|
40
80
|
bold: selected,
|
|
41
81
|
});
|
|
42
82
|
});
|
|
@@ -72,41 +112,317 @@ function isOnboardingCategory(category: AgentWorkspaceCategory): boolean {
|
|
|
72
112
|
return category.group === 'ONBOARDING';
|
|
73
113
|
}
|
|
74
114
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
115
|
+
interface OnboardingActionColumns {
|
|
116
|
+
readonly setting: string;
|
|
117
|
+
readonly defaultValue: string;
|
|
118
|
+
readonly currentValue: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function editorPurposeLabel(editorKind: AgentWorkspaceEditorKind): string {
|
|
122
|
+
switch (editorKind) {
|
|
123
|
+
case 'mcp-server': return 'Edit MCP server';
|
|
124
|
+
case 'mcp-tools-server': return 'Edit MCP tools server';
|
|
125
|
+
case 'mcp-repair': return 'Repair MCP connection';
|
|
126
|
+
case 'secret-link': return 'Link secret reference';
|
|
127
|
+
case 'secret-set': return 'Store secret';
|
|
128
|
+
case 'secret-test': return 'Test secret reference';
|
|
129
|
+
case 'secret-delete': return 'Delete secret';
|
|
130
|
+
case 'subscription-login-start': return 'Sign in to provider';
|
|
131
|
+
case 'subscription-login-finish': return 'Finish provider sign-in';
|
|
132
|
+
case 'subscription-logout': return 'Sign out of provider';
|
|
133
|
+
case 'subscription-inspect': return 'Inspect subscription';
|
|
134
|
+
case 'provider-add': return 'Add custom provider';
|
|
135
|
+
case 'provider-remove': return 'Remove custom provider';
|
|
136
|
+
case 'provider-use': return 'Choose provider';
|
|
137
|
+
case 'provider-inspect': return 'Inspect provider';
|
|
138
|
+
case 'provider-routes': return 'Edit provider routes';
|
|
139
|
+
case 'provider-account-repair': return 'Repair provider account';
|
|
140
|
+
case 'memory': return 'Edit memory';
|
|
141
|
+
case 'memory-search': return 'Search memory';
|
|
142
|
+
case 'memory-get': return 'Get memory record';
|
|
143
|
+
case 'memory-explain': return 'Explain memory';
|
|
144
|
+
case 'memory-promote': return 'Promote memory';
|
|
145
|
+
case 'memory-link': return 'Link memory';
|
|
146
|
+
case 'memory-export': return 'Export memory';
|
|
147
|
+
case 'memory-import': return 'Import memory';
|
|
148
|
+
case 'memory-handoff-export': return 'Export memory handoff';
|
|
149
|
+
case 'memory-handoff-inspect': return 'Inspect memory handoff';
|
|
150
|
+
case 'memory-handoff-import': return 'Import memory handoff';
|
|
151
|
+
case 'memory-vector-rebuild': return 'Rebuild memory vectors';
|
|
152
|
+
case 'note': return 'Edit note';
|
|
153
|
+
case 'persona': return 'Edit persona';
|
|
154
|
+
case 'persona-search': return 'Search personas';
|
|
155
|
+
case 'persona-show': return 'Show persona';
|
|
156
|
+
case 'persona-discovery-import': return 'Import persona files';
|
|
157
|
+
case 'skill': return 'Edit skill';
|
|
158
|
+
case 'skill-search': return 'Search skills';
|
|
159
|
+
case 'skill-show': return 'Show skill';
|
|
160
|
+
case 'skill-discovery-import': return 'Import skill files';
|
|
161
|
+
case 'routine': return 'Edit routine';
|
|
162
|
+
case 'routine-search': return 'Search routines';
|
|
163
|
+
case 'routine-show': return 'Show routine';
|
|
164
|
+
case 'routine-discovery-import': return 'Import routine files';
|
|
165
|
+
case 'profile': return 'Edit profile';
|
|
166
|
+
case 'profile-from-discovered': return 'Create profile from files';
|
|
167
|
+
case 'profile-show': return 'Show profile';
|
|
168
|
+
case 'profile-default': return 'Set default profile';
|
|
169
|
+
case 'profile-default-clear': return 'Clear default profile';
|
|
170
|
+
case 'profile-delete': return 'Delete profile';
|
|
171
|
+
case 'profile-template-export': return 'Export profile template';
|
|
172
|
+
case 'profile-template-import': return 'Import profile template';
|
|
173
|
+
case 'profile-template-show': return 'Show profile template';
|
|
174
|
+
case 'profile-template-from-discovered': return 'Create template from files';
|
|
175
|
+
case 'knowledge-url': return 'Ingest URL';
|
|
176
|
+
case 'knowledge-urls': return 'Ingest URLs';
|
|
177
|
+
case 'knowledge-file': return 'Ingest file';
|
|
178
|
+
case 'knowledge-bookmarks': return 'Import bookmarks';
|
|
179
|
+
case 'knowledge-browser-history': return 'Import browser history';
|
|
180
|
+
case 'knowledge-connector-ingest': return 'Run connector ingest';
|
|
181
|
+
case 'knowledge-connector-show': return 'Show connector';
|
|
182
|
+
case 'knowledge-connector-doctor': return 'Check connector health';
|
|
183
|
+
case 'knowledge-reindex': return 'Reindex knowledge';
|
|
184
|
+
case 'knowledge-search': return 'Search knowledge';
|
|
185
|
+
case 'knowledge-ask': return 'Ask knowledge';
|
|
186
|
+
case 'knowledge-get': return 'Get knowledge record';
|
|
187
|
+
case 'knowledge-map': return 'Map knowledge';
|
|
188
|
+
case 'knowledge-review-issue': return 'Review knowledge issue';
|
|
189
|
+
case 'knowledge-consolidate': return 'Consolidate knowledge';
|
|
190
|
+
case 'knowledge-packet': return 'Build knowledge packet';
|
|
191
|
+
case 'knowledge-explain': return 'Explain knowledge';
|
|
192
|
+
case 'delegate-task': return 'Delegate build task';
|
|
193
|
+
case 'document-browse': return 'Browse documents';
|
|
194
|
+
case 'document-show': return 'Show document';
|
|
195
|
+
case 'document-create': return 'Create document';
|
|
196
|
+
case 'document-update': return 'Revise document';
|
|
197
|
+
case 'document-review': return 'Review document';
|
|
198
|
+
case 'document-comment': return 'Add comment';
|
|
199
|
+
case 'document-resolve-comment': return 'Resolve comment';
|
|
200
|
+
case 'document-suggest': return 'Propose suggestion';
|
|
201
|
+
case 'document-accept-suggestion': return 'Accept suggestion';
|
|
202
|
+
case 'document-reject-suggestion': return 'Reject suggestion';
|
|
203
|
+
case 'document-insert-artifact': return 'Insert artifact';
|
|
204
|
+
case 'document-attach-artifact': return 'Attach artifact';
|
|
205
|
+
case 'document-export': return 'Export document';
|
|
206
|
+
case 'document-reviewer-readiness': return 'Review readiness preflight';
|
|
207
|
+
case 'document-review-packet-wizard': return 'Run packet wizard';
|
|
208
|
+
case 'document-review-packet-preset': return 'Save packet preset';
|
|
209
|
+
case 'document-review-packet-preset-refresh': return 'Refresh packet preset';
|
|
210
|
+
case 'document-review-packet-share': return 'Share review packet';
|
|
211
|
+
case 'model-compare': return 'Compare models';
|
|
212
|
+
case 'model-compare-review': return 'Review comparison';
|
|
213
|
+
case 'model-compare-handoff-diff': return 'Diff reviewer handoffs';
|
|
214
|
+
case 'model-compare-judge': return 'Judge comparison';
|
|
215
|
+
case 'model-compare-apply': return 'Apply comparison winner';
|
|
216
|
+
case 'model-compare-route-decision': return 'Record route decision';
|
|
217
|
+
case 'model-compare-export': return 'Export comparison';
|
|
218
|
+
case 'model-compare-analytics': return 'View comparison analytics';
|
|
219
|
+
case 'local-model-benchmark': return 'Run local benchmark';
|
|
220
|
+
case 'auth-show': return 'Show auth status';
|
|
221
|
+
case 'auth-repair': return 'Repair auth';
|
|
222
|
+
case 'auth-bundle-export': return 'Export auth bundle';
|
|
223
|
+
case 'auth-bundle-inspect': return 'Inspect auth bundle';
|
|
224
|
+
case 'trust-bundle-export': return 'Export trust bundle';
|
|
225
|
+
case 'trust-bundle-inspect': return 'Inspect trust bundle';
|
|
226
|
+
case 'support-bundle-export': return 'Export support bundle';
|
|
227
|
+
case 'support-bundle-inspect': return 'Inspect support bundle';
|
|
228
|
+
case 'support-bundle-import': return 'Import support bundle';
|
|
229
|
+
case 'subscription-bundle-export': return 'Export subscription bundle';
|
|
230
|
+
case 'subscription-bundle-inspect': return 'Inspect subscription bundle';
|
|
231
|
+
case 'voice-enable': return 'Enable voice';
|
|
232
|
+
case 'voice-disable': return 'Disable voice';
|
|
233
|
+
case 'voice-bundle-export': return 'Export voice bundle';
|
|
234
|
+
case 'voice-bundle-inspect': return 'Inspect voice bundle';
|
|
235
|
+
case 'tts-prompt': return 'Test TTS prompt';
|
|
236
|
+
case 'image-input': return 'Attach image';
|
|
237
|
+
case 'artifact-browser': return 'Browse artifacts';
|
|
238
|
+
case 'artifact-show': return 'Show artifact';
|
|
239
|
+
case 'artifact-export-file': return 'Export artifact to file';
|
|
240
|
+
case 'artifact-export-package': return 'Export artifact package';
|
|
241
|
+
case 'artifact-promote-knowledge': return 'Promote artifact to knowledge';
|
|
242
|
+
case 'media-generate': return 'Generate media';
|
|
243
|
+
case 'conversation-export': return 'Export conversation';
|
|
244
|
+
case 'conversation-events': return 'Show conversation events';
|
|
245
|
+
case 'conversation-groups': return 'Show conversation groups';
|
|
246
|
+
case 'conversation-find': return 'Find conversation';
|
|
247
|
+
case 'effort-level': return 'Set effort level';
|
|
248
|
+
case 'channel-show': return 'Show channel';
|
|
249
|
+
case 'channel-doctor': return 'Check channel health';
|
|
250
|
+
case 'channel-setup': return 'Set up channel';
|
|
251
|
+
case 'channel-send': return 'Send to channel';
|
|
252
|
+
case 'session-save': return 'Save session';
|
|
253
|
+
case 'session-load': return 'Load session';
|
|
254
|
+
case 'session-rename': return 'Rename session';
|
|
255
|
+
case 'session-resume': return 'Resume session';
|
|
256
|
+
case 'session-info': return 'Inspect session';
|
|
257
|
+
case 'session-export-saved': return 'Export saved session';
|
|
258
|
+
case 'session-search': return 'Search sessions';
|
|
259
|
+
case 'session-delete': return 'Delete session';
|
|
260
|
+
case 'session-fork': return 'Fork session';
|
|
261
|
+
case 'session-graph': return 'Inspect session graph';
|
|
262
|
+
case 'task-list-filter': return 'Filter task list';
|
|
263
|
+
case 'task-show': return 'Show task';
|
|
264
|
+
case 'task-output': return 'View task output';
|
|
265
|
+
case 'plan-seed': return 'Seed plan';
|
|
266
|
+
case 'plan-show': return 'Show plan';
|
|
267
|
+
case 'plan-approve': return 'Approve plan';
|
|
268
|
+
case 'plan-override': return 'Override plan';
|
|
269
|
+
case 'plan-clear': return 'Clear plan';
|
|
270
|
+
case 'health-repair': return 'Repair health issue';
|
|
271
|
+
case 'approval-review': return 'Review approval';
|
|
272
|
+
case 'approval-approve': return 'Approve request';
|
|
273
|
+
case 'approval-deny': return 'Deny request';
|
|
274
|
+
case 'approval-cancel': return 'Cancel approval';
|
|
275
|
+
case 'automation-job-run': return 'Run automation job';
|
|
276
|
+
case 'automation-job-pause': return 'Pause automation job';
|
|
277
|
+
case 'automation-job-resume': return 'Resume automation job';
|
|
278
|
+
case 'automation-run-cancel': return 'Cancel automation run';
|
|
279
|
+
case 'automation-run-retry': return 'Retry automation run';
|
|
280
|
+
case 'schedule-run': return 'Run schedule';
|
|
281
|
+
case 'schedule-edit': return 'Edit schedule';
|
|
282
|
+
case 'routine-receipt': return 'View routine receipt';
|
|
283
|
+
case 'schedule-receipt': return 'View schedule receipt';
|
|
284
|
+
case 'mode-preset': return 'Set mode preset';
|
|
285
|
+
case 'mode-domain': return 'Set mode domain';
|
|
286
|
+
case 'setting-set': return 'Set setting';
|
|
287
|
+
case 'model-pin': return 'Pin model';
|
|
288
|
+
case 'model-unpin': return 'Unpin model';
|
|
289
|
+
case 'workplan-add': return 'Add work item';
|
|
290
|
+
case 'workplan-show': return 'Show work plan';
|
|
291
|
+
case 'workplan-status': return 'Check work plan status';
|
|
292
|
+
case 'workplan-delete': return 'Delete work item';
|
|
293
|
+
case 'workplan-clear-completed': return 'Clear completed items';
|
|
294
|
+
case 'routine-schedule': return 'Schedule routine';
|
|
295
|
+
case 'reminder-schedule': return 'Schedule reminder';
|
|
296
|
+
case 'skill-bundle': return 'Edit skill bundle';
|
|
297
|
+
case 'skill-bundle-search': return 'Search skill bundles';
|
|
298
|
+
case 'skill-bundle-show': return 'Show skill bundle';
|
|
299
|
+
case 'skill-bundle-update': return 'Update skill bundle';
|
|
300
|
+
case 'skill-bundle-enable': return 'Enable skill bundle';
|
|
301
|
+
case 'skill-bundle-disable': return 'Disable skill bundle';
|
|
302
|
+
case 'skill-bundle-review': return 'Review skill bundle';
|
|
303
|
+
case 'skill-bundle-stale': return 'Mark bundle stale';
|
|
304
|
+
case 'skill-bundle-delete': return 'Delete skill bundle';
|
|
305
|
+
case 'learned-behavior': return 'Review learned behavior';
|
|
306
|
+
case 'web-research': return 'Run web research';
|
|
307
|
+
case 'web-fetch': return 'Fetch from web';
|
|
308
|
+
case 'research-run': return 'Run research';
|
|
309
|
+
case 'research-source': return 'Manage research source';
|
|
310
|
+
case 'research-report': return 'Show research report';
|
|
311
|
+
case 'notify-webhook': return 'Add notification webhook';
|
|
312
|
+
case 'notify-webhook-remove': return 'Remove notification webhook';
|
|
313
|
+
case 'notify-webhook-clear': return 'Clear notification webhooks';
|
|
314
|
+
case 'notify-webhook-test': return 'Test notification webhook';
|
|
315
|
+
case 'notify-send': return 'Send notification';
|
|
316
|
+
default: return `Edit ${editorKind}`;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function localOperationLabel(localOperation: string): string {
|
|
321
|
+
switch (localOperation) {
|
|
322
|
+
case 'routine-start': return 'Start routine';
|
|
323
|
+
case 'persona-activate':
|
|
324
|
+
case 'persona-use': return 'Activate persona';
|
|
325
|
+
case 'persona-clear': return 'Deactivate persona';
|
|
326
|
+
case 'persona-edit': return 'Edit persona';
|
|
327
|
+
case 'persona-review': return 'Review persona';
|
|
328
|
+
case 'persona-delete': return 'Delete persona';
|
|
329
|
+
case 'memory-edit': return 'Edit memory';
|
|
330
|
+
case 'memory-review': return 'Review memory';
|
|
331
|
+
case 'memory-stale': return 'Mark memory stale';
|
|
332
|
+
case 'memory-delete': return 'Delete memory';
|
|
333
|
+
case 'note-edit': return 'Edit note';
|
|
334
|
+
case 'note-review': return 'Review note';
|
|
335
|
+
case 'note-stale': return 'Mark note stale';
|
|
336
|
+
case 'note-delete': return 'Delete note';
|
|
337
|
+
case 'note-promote-memory': return 'Promote note to memory';
|
|
338
|
+
case 'note-promote-persona': return 'Promote note to persona';
|
|
339
|
+
case 'note-promote-skill': return 'Promote note to skill';
|
|
340
|
+
case 'note-promote-routine': return 'Promote note to routine';
|
|
341
|
+
case 'note-promote-knowledge-url': return 'Promote note to knowledge';
|
|
342
|
+
case 'skill-edit': return 'Edit skill';
|
|
343
|
+
case 'skill-enable': return 'Enable skill';
|
|
344
|
+
case 'skill-disable': return 'Disable skill';
|
|
345
|
+
case 'skill-review': return 'Review skill';
|
|
346
|
+
case 'skill-delete': return 'Delete skill';
|
|
347
|
+
case 'routine-edit': return 'Edit routine';
|
|
348
|
+
case 'routine-enable': return 'Enable routine';
|
|
349
|
+
case 'routine-disable': return 'Disable routine';
|
|
350
|
+
case 'routine-review': return 'Review routine';
|
|
351
|
+
case 'routine-delete': return 'Delete routine';
|
|
352
|
+
default: return 'Apply local action';
|
|
78
353
|
}
|
|
79
|
-
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function onboardingActionLabel(workspace: AgentWorkspace, action: AgentWorkspaceAction): string {
|
|
357
|
+
if (action.kind === 'settings-import') return 'Import GoodVibes preferences';
|
|
80
358
|
if (action.kind === 'setup-checkpoint') {
|
|
81
|
-
if (action.setupCheckpointOperation === 'show') return '
|
|
82
|
-
if (action.setupCheckpointOperation === 'mark-current') return 'Save
|
|
83
|
-
if (action.setupCheckpointOperation === 'clear') return 'Clear saved
|
|
359
|
+
if (action.setupCheckpointOperation === 'show') return 'Review saved progress';
|
|
360
|
+
if (action.setupCheckpointOperation === 'mark-current') return 'Save progress';
|
|
361
|
+
if (action.setupCheckpointOperation === 'clear') return 'Clear saved progress';
|
|
84
362
|
return 'Review setup progress';
|
|
85
363
|
}
|
|
86
|
-
if (action.kind === 'model-picker') return action.modelPickerFlow === 'model' ? 'Choose
|
|
364
|
+
if (action.kind === 'model-picker') return action.modelPickerFlow === 'model' ? 'Choose model' : 'Choose provider and model';
|
|
87
365
|
if (action.kind === 'settings-modal') return 'Open settings';
|
|
88
|
-
if (action.kind === 'workspace')
|
|
89
|
-
|
|
366
|
+
if (action.kind === 'workspace') {
|
|
367
|
+
if (action.targetCategoryId) {
|
|
368
|
+
const target = workspace.categories.find((c) => c.id === action.targetCategoryId);
|
|
369
|
+
const label = target ? target.label : action.targetCategoryId;
|
|
370
|
+
return `Switch to ${label}`;
|
|
371
|
+
}
|
|
372
|
+
return 'Switch to setup area';
|
|
373
|
+
}
|
|
374
|
+
if (action.kind === 'editor') return action.editorKind ? editorPurposeLabel(action.editorKind) : 'Open form';
|
|
90
375
|
if (action.kind === 'local-selection') return 'Move selection';
|
|
91
|
-
if (action.kind === 'local-operation') return 'Apply
|
|
92
|
-
if (action.kind === 'onboarding-complete') return '
|
|
93
|
-
if (action.
|
|
376
|
+
if (action.kind === 'local-operation') return action.localOperation ? localOperationLabel(action.localOperation) : 'Apply local action';
|
|
377
|
+
if (action.kind === 'onboarding-complete') return 'Finish setup';
|
|
378
|
+
if (action.kind === 'command') {
|
|
379
|
+
const cmd = action.command ?? '';
|
|
380
|
+
return action.commandBehavior === 'inline' ? `Run: ${cmd}` : `Open: ${cmd}`;
|
|
381
|
+
}
|
|
382
|
+
if (action.safety === 'read-only') return 'Review';
|
|
94
383
|
if (action.safety === 'blocked') return 'Unavailable in this setup step';
|
|
95
|
-
return 'Open
|
|
384
|
+
return 'Open';
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function onboardingActionColumns(workspace: AgentWorkspace, action: AgentWorkspaceAction): OnboardingActionColumns {
|
|
388
|
+
if (action.kind === 'setting') {
|
|
389
|
+
return workspace.settingActionDisplay(action) ?? {
|
|
390
|
+
setting: action.label,
|
|
391
|
+
defaultValue: '(unknown)',
|
|
392
|
+
currentValue: '(unknown)',
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
return {
|
|
396
|
+
setting: onboardingActionLabel(workspace, action),
|
|
397
|
+
defaultValue: '',
|
|
398
|
+
currentValue: '',
|
|
399
|
+
};
|
|
96
400
|
}
|
|
97
401
|
|
|
98
402
|
function actionChange(workspace: AgentWorkspace, category: AgentWorkspaceCategory, action: AgentWorkspaceAction): string {
|
|
99
|
-
return isOnboardingCategory(category) ?
|
|
403
|
+
return isOnboardingCategory(category) ? onboardingActionColumns(workspace, action).setting : actionCommand(action);
|
|
100
404
|
}
|
|
101
405
|
|
|
102
406
|
function actionMetaLine(workspace: AgentWorkspace, category: AgentWorkspaceCategory, action: AgentWorkspaceAction): ContextLine {
|
|
103
407
|
const onboarding = isOnboardingCategory(category);
|
|
408
|
+
if (onboarding) {
|
|
409
|
+
return {
|
|
410
|
+
text: `About: ${compactText(action.detail, 100)}`,
|
|
411
|
+
fg: action.safety === 'blocked' ? PALETTE.warn : PALETTE.muted,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
104
414
|
return {
|
|
105
|
-
text:
|
|
106
|
-
fg: action.safety === 'blocked' ? PALETTE.warn :
|
|
415
|
+
text: `Does: ${actionChange(workspace, category, action)}`,
|
|
416
|
+
fg: action.safety === 'blocked' ? PALETTE.warn : action.kind === 'command' ? PALETTE.info : PALETTE.muted,
|
|
107
417
|
};
|
|
108
418
|
}
|
|
109
419
|
|
|
420
|
+
function shouldRenderOnboardingSettingsTable(actions: readonly AgentWorkspaceAction[]): boolean {
|
|
421
|
+
// Exclude the synthetic finish footer row — it is not a setting and must not block table mode.
|
|
422
|
+
const nonFinish = actions.filter((a) => a.kind !== 'onboarding-complete');
|
|
423
|
+
return nonFinish.length > 0 && nonFinish.every((action) => action.kind === 'setting');
|
|
424
|
+
}
|
|
425
|
+
|
|
110
426
|
function editorContextLines(editor: AgentWorkspaceLocalEditor, snapshot: AgentWorkspaceRuntimeSnapshot | null): ContextLine[] {
|
|
111
427
|
const selected = editor.fields[editor.selectedFieldIndex];
|
|
112
428
|
const lines: ContextLine[] = [
|
|
@@ -244,12 +560,25 @@ function buildEditorFieldRows(editor: AgentWorkspaceLocalEditor, index: number,
|
|
|
244
560
|
return rows;
|
|
245
561
|
}
|
|
246
562
|
|
|
563
|
+
function onboardingFinishPrerequisitesMet(workspace: AgentWorkspace): boolean {
|
|
564
|
+
const checklist = workspace.runtimeSnapshot?.setupChecklist ?? [];
|
|
565
|
+
return ONBOARDING_CRITICAL_STEP_IDS.every((id) => checklist.find((item) => item.id === id)?.status === 'ready');
|
|
566
|
+
}
|
|
567
|
+
|
|
247
568
|
function buildActionRows(workspace: AgentWorkspace, width: number, height: number): WorkspaceRow[] {
|
|
248
569
|
if (workspace.localEditor) return buildEditorRows(workspace.localEditor, width, height);
|
|
249
570
|
const category = workspace.selectedActionCategory;
|
|
250
571
|
const onboarding = isOnboardingCategory(category);
|
|
572
|
+
const settingTable = onboarding
|
|
573
|
+
&& !workspace.actionSearchActive
|
|
574
|
+
&& shouldRenderOnboardingSettingsTable(workspace.actions);
|
|
251
575
|
const rows: WorkspaceRow[] = [];
|
|
252
|
-
const
|
|
576
|
+
const valueWidth = settingTable
|
|
577
|
+
? Math.min(22, Math.max(10, Math.floor(width * 0.18)))
|
|
578
|
+
: 0;
|
|
579
|
+
const labelWidth = settingTable
|
|
580
|
+
? Math.max(18, width - (valueWidth * 2) - 6)
|
|
581
|
+
: Math.min(34, Math.max(18, Math.floor(width * 0.38)));
|
|
253
582
|
const commandWidth = Math.max(10, width - labelWidth - 6);
|
|
254
583
|
if (workspace.actionSearchActive) {
|
|
255
584
|
rows.push({
|
|
@@ -259,32 +588,80 @@ function buildActionRows(workspace: AgentWorkspace, width: number, height: numbe
|
|
|
259
588
|
});
|
|
260
589
|
}
|
|
261
590
|
rows.push({
|
|
262
|
-
text:
|
|
591
|
+
text: settingTable
|
|
592
|
+
? ` ${padDisplay(workspace.actionSearchActive ? 'Result' : 'Setting', labelWidth)} ${padDisplay('Default', valueWidth)} ${padDisplay('Current', valueWidth)}`
|
|
593
|
+
: ` ${padDisplay(workspace.actionSearchActive ? 'Result' : onboarding ? 'Option' : 'Action', labelWidth)} ${padDisplay('Does', commandWidth)}`,
|
|
263
594
|
fg: PALETTE.muted,
|
|
264
595
|
bold: true,
|
|
265
596
|
});
|
|
266
597
|
|
|
267
|
-
|
|
598
|
+
// The finish footer row is appended to workspace.actions by the input layer
|
|
599
|
+
// (shouldShowOnboardingFinishFooter). Detect it here by action id for special styling.
|
|
600
|
+
const allActions = workspace.actions;
|
|
601
|
+
const finishActionIndex = allActions.findIndex((a) => a.id === ONBOARDING_COMPLETE_SYNTHETIC_ACTION.id);
|
|
602
|
+
|
|
268
603
|
const visible = Math.max(1, height - (workspace.actionSearchActive ? 3 : 2));
|
|
269
|
-
const window = stableWindow(
|
|
604
|
+
const window = stableWindow(allActions.length, workspace.selectedActionIndex, visible);
|
|
270
605
|
if (window.start > 0) rows.push({ text: `${GLYPHS.navigation.moreAbove} ${window.start} more action(s) above`, kind: 'more', fg: PALETTE.dim, dim: true });
|
|
271
606
|
|
|
272
607
|
for (let index = window.start; index < window.end; index += 1) {
|
|
273
|
-
const action =
|
|
608
|
+
const action = allActions[index]!;
|
|
609
|
+
const isFinishFooterRow = finishActionIndex >= 0 && index === finishActionIndex;
|
|
274
610
|
const selected = index === workspace.selectedActionIndex;
|
|
275
611
|
const searchResult = workspace.actionSearchActive ? workspace.actionSearchResults[index] : null;
|
|
276
612
|
const actionCategory = searchResult?.category ?? category;
|
|
277
613
|
const label = searchResult ? `${searchResult.category.label} / ${action.label}` : action.label;
|
|
278
614
|
const marker = selected ? GLYPHS.navigation.selected : ' ';
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
615
|
+
|
|
616
|
+
if (isFinishFooterRow) {
|
|
617
|
+
// Sticky Finish setup footer row
|
|
618
|
+
const prereqsMet = onboardingFinishPrerequisitesMet(workspace);
|
|
619
|
+
const sep = `${GLYPHS.frame.horizontal.repeat(3)} Finish setup ${GLYPHS.frame.horizontal.repeat(3)}`;
|
|
620
|
+
if (!selected) {
|
|
621
|
+
rows.push({
|
|
622
|
+
text: ` ${sep}`,
|
|
623
|
+
kind: 'item',
|
|
624
|
+
fg: PALETTE.dim,
|
|
625
|
+
dim: true,
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
const finishDetail = prereqsMet
|
|
629
|
+
? 'Finish setup'
|
|
630
|
+
: (() => {
|
|
631
|
+
const checklist = workspace.runtimeSnapshot?.setupChecklist ?? [];
|
|
632
|
+
const unmet = [...ONBOARDING_CRITICAL_STEP_IDS]
|
|
633
|
+
.filter((id) => checklist.find((item) => item.id === id)?.status !== 'ready')
|
|
634
|
+
.map((id) => checklist.find((item) => item.id === id)?.label ?? id)
|
|
635
|
+
.join(', ');
|
|
636
|
+
return `Finish needs: ${unmet}`;
|
|
637
|
+
})();
|
|
638
|
+
const text = settingTable
|
|
639
|
+
? `${marker} ${padDisplay('Finish setup', labelWidth)} ${padDisplay('', valueWidth)} ${padDisplay('', valueWidth)}`
|
|
640
|
+
: `${marker} ${padDisplay('Finish setup', labelWidth)} ${padDisplay(finishDetail, commandWidth)}`;
|
|
641
|
+
rows.push({
|
|
642
|
+
text,
|
|
643
|
+
selected: selected && workspace.focusPane === 'actions',
|
|
644
|
+
fg: prereqsMet ? PALETTE.good : PALETTE.warn,
|
|
645
|
+
bold: selected,
|
|
646
|
+
kind: 'item',
|
|
647
|
+
});
|
|
648
|
+
} else {
|
|
649
|
+
const text = settingTable
|
|
650
|
+
? (() => {
|
|
651
|
+
const columns = onboardingActionColumns(workspace, action);
|
|
652
|
+
return `${marker} ${padDisplay(columns.setting, labelWidth)} ${padDisplay(columns.defaultValue, valueWidth)} ${padDisplay(columns.currentValue, valueWidth)}`;
|
|
653
|
+
})()
|
|
654
|
+
: `${marker} ${padDisplay(label, labelWidth)} ${padDisplay(actionChange(workspace, actionCategory, action), commandWidth)}`;
|
|
655
|
+
rows.push({
|
|
656
|
+
text,
|
|
657
|
+
selected: selected && workspace.focusPane === 'actions',
|
|
658
|
+
fg: action.safety === 'blocked' ? PALETTE.warn : selected ? PALETTE.text : PALETTE.info,
|
|
659
|
+
bold: selected,
|
|
660
|
+
});
|
|
661
|
+
}
|
|
285
662
|
}
|
|
286
663
|
|
|
287
|
-
if (window.end <
|
|
664
|
+
if (window.end < allActions.length) rows.push({ text: `${GLYPHS.navigation.moreBelow} ${allActions.length - window.end} more action(s) below`, kind: 'more', fg: PALETTE.dim, dim: true });
|
|
288
665
|
rows.push({ text: '' });
|
|
289
666
|
rows.push({ text: `Status: ${workspace.status}`, fg: PALETTE.muted });
|
|
290
667
|
if (workspace.lastActionResult) {
|
|
@@ -30,7 +30,7 @@ export async function setupPostureCatalogStatus(context: CommandContext): Promis
|
|
|
30
30
|
autonomyBlockers: plan.filter((item) => item.blocksAutonomy && item.status !== 'ready').length,
|
|
31
31
|
nextSetupHandoffs: nextSetupHandoffSummaries(plan, 5),
|
|
32
32
|
setupWizard,
|
|
33
|
-
setupCloseout: setupWizard.closeout,
|
|
33
|
+
setupCloseout: setupWizard._diagnostic.closeout,
|
|
34
34
|
collectionIssues: snapshot.collectionIssues.length,
|
|
35
35
|
setupMarkerExists: setupCompletionMarkerExists(context),
|
|
36
36
|
setupSmokeEvidence,
|
|
@@ -81,7 +81,7 @@ export async function setupRepairSummary(context: CommandContext, args: AgentHar
|
|
|
81
81
|
status: setupWizard.status,
|
|
82
82
|
currentStepId: setupWizard.currentStepId,
|
|
83
83
|
currentStepLabel: setupWizard.currentStepLabel,
|
|
84
|
-
closeout: setupWizard.closeout,
|
|
84
|
+
closeout: setupWizard._diagnostic.closeout,
|
|
85
85
|
},
|
|
86
86
|
routes: {
|
|
87
87
|
inspectSetup: DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
@@ -149,14 +149,14 @@ export async function setupPostureSummary(context: CommandContext, args: AgentHa
|
|
|
149
149
|
progressLabel: setupWizard.progressLabel,
|
|
150
150
|
currentStepId: setupWizard.currentStepId,
|
|
151
151
|
currentStepLabel: setupWizard.currentStepLabel,
|
|
152
|
-
repeatedBlocker: setupWizard.repeatedBlocker,
|
|
152
|
+
repeatedBlocker: setupWizard._diagnostic.repeatedBlocker,
|
|
153
153
|
},
|
|
154
|
-
setupCloseout: setupWizard.closeout,
|
|
154
|
+
setupCloseout: setupWizard._diagnostic.closeout,
|
|
155
155
|
},
|
|
156
156
|
setupSmokeEvidence,
|
|
157
157
|
setupSmokeHistory,
|
|
158
158
|
setupWizard,
|
|
159
|
-
setupCloseout: setupWizard.closeout,
|
|
159
|
+
setupCloseout: setupWizard._diagnostic.closeout,
|
|
160
160
|
currentRoute: snapshot.providerRouting,
|
|
161
161
|
issues: snapshot.collectionIssues,
|
|
162
162
|
readinessPlan: filteredPlan.map((item) => describePlanItem(item, includeParameters)),
|
|
@@ -175,7 +175,7 @@ export async function setupCheckpointSummary(context: CommandContext): Promise<R
|
|
|
175
175
|
const setupWizard = buildSetupWizard(plan, context);
|
|
176
176
|
return {
|
|
177
177
|
mode: 'setup_checkpoint',
|
|
178
|
-
checkpoint: setupWizard.checkpoint,
|
|
178
|
+
checkpoint: setupWizard._diagnostic.checkpoint,
|
|
179
179
|
currentStep: setupWizard.currentStepId
|
|
180
180
|
? setupWizard.steps.find((step) => step.id === setupWizard.currentStepId) ?? null
|
|
181
181
|
: null,
|
|
@@ -254,7 +254,7 @@ export async function markSetupCheckpoint(context: CommandContext, args: AgentHa
|
|
|
254
254
|
progressLabel: updatedWizard.progressLabel,
|
|
255
255
|
currentStepId: updatedWizard.currentStepId,
|
|
256
256
|
currentStepLabel: updatedWizard.currentStepLabel,
|
|
257
|
-
checkpoint: updatedWizard.checkpoint,
|
|
257
|
+
checkpoint: updatedWizard._diagnostic.checkpoint,
|
|
258
258
|
},
|
|
259
259
|
routes: {
|
|
260
260
|
inspectCheckpoint: DEFAULT_AGENT_SETUP_WIZARD_INSPECT_CHECKPOINT_ROUTE,
|
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.
|
|
9
|
+
let _version = '1.4.1';
|
|
10
10
|
try {
|
|
11
11
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|
|
12
12
|
readonly version?: unknown;
|