@pellux/goodvibes-agent 1.2.0 → 1.3.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 +159 -0
- package/dist/package/main.js +19016 -12684
- package/docs/README.md +3 -3
- package/docs/connected-host.md +2 -2
- package/docs/getting-started.md +11 -9
- package/docs/tools-and-commands.md +12 -10
- package/docs/voice-and-live-tts.md +2 -2
- package/package.json +1 -1
- package/release/release-notes.md +17 -5
- package/release/release-readiness.json +36 -36
- package/src/agent/competitive-feature-inventory.ts +42 -44
- package/src/agent/setup-wizard-artifact-receipts.ts +366 -0
- package/src/agent/setup-wizard.ts +245 -9
- package/src/input/agent-workspace-categories.ts +2 -2
- package/src/input/agent-workspace-onboarding-categories.ts +4 -4
- package/src/input/agent-workspace-settings.ts +52 -1
- package/src/input/agent-workspace-setup-snapshot.ts +20 -1
- package/src/input/agent-workspace-setup.ts +32 -5
- package/src/input/agent-workspace-snapshot.ts +23 -3
- package/src/input/agent-workspace.ts +5 -1
- package/src/input/setup-wizard-live-receipts.ts +76 -0
- package/src/renderer/agent-workspace-context-lines.ts +21 -6
- package/src/renderer/agent-workspace.ts +46 -10
- package/src/runtime/tool-permission-safety.ts +1 -1
- package/src/tools/agent-harness-agent-orchestration-policy.ts +75 -0
- package/src/tools/agent-harness-agent-orchestration.ts +216 -128
- package/src/tools/agent-harness-autonomy-live-records.ts +154 -0
- package/src/tools/agent-harness-autonomy-queue-types.ts +1 -1
- package/src/tools/agent-harness-autonomy-queue.ts +19 -8
- package/src/tools/agent-harness-autonomy-watcher-read-models.ts +509 -0
- package/src/tools/agent-harness-background-processes.ts +8 -4
- package/src/tools/agent-harness-browser-cockpit-route.ts +188 -34
- package/src/tools/agent-harness-browser-control.ts +12 -4
- package/src/tools/agent-harness-browser-pwa-read-models.ts +622 -0
- package/src/tools/agent-harness-device-live-read-models.ts +366 -0
- package/src/tools/agent-harness-execution-posture.ts +3 -0
- package/src/tools/agent-harness-interactive-runtime-records.ts +421 -0
- package/src/tools/agent-harness-local-model-benchmarks.ts +71 -1
- package/src/tools/agent-harness-local-model-endpoints.ts +469 -354
- package/src/tools/agent-harness-local-model-smoke.ts +277 -0
- package/src/tools/agent-harness-local-model-url.ts +78 -0
- package/src/tools/agent-harness-media-posture.ts +27 -12
- package/src/tools/agent-harness-memory-external-providers.ts +796 -0
- package/src/tools/agent-harness-memory-posture.ts +253 -137
- package/src/tools/agent-harness-memory-provider-certification.ts +219 -0
- package/src/tools/agent-harness-memory-refinement.ts +340 -0
- package/src/tools/agent-harness-mode-catalog.ts +4 -2
- package/src/tools/agent-harness-model-provider-health.ts +139 -42
- package/src/tools/agent-harness-model-readiness.ts +31 -5
- package/src/tools/agent-harness-model-routing-types.ts +61 -0
- package/src/tools/agent-harness-model-routing.ts +31 -6
- package/src/tools/agent-harness-pairing-posture.ts +30 -9
- package/src/tools/agent-harness-personal-ops-certification.ts +116 -0
- package/src/tools/agent-harness-personal-ops-lanes.ts +81 -15
- package/src/tools/agent-harness-personal-ops-operations.ts +225 -0
- package/src/tools/agent-harness-personal-ops-provider-records.ts +358 -0
- package/src/tools/agent-harness-personal-ops-provider-task-records.ts +321 -0
- package/src/tools/agent-harness-personal-ops-records.ts +176 -224
- package/src/tools/agent-harness-personal-ops-types.ts +19 -1
- package/src/tools/agent-harness-personal-ops.ts +18 -11
- package/src/tools/agent-harness-remote-read-models.ts +541 -0
- package/src/tools/agent-harness-research-briefing.ts +26 -7
- package/src/tools/agent-harness-research-live-read-models.ts +500 -0
- package/src/tools/agent-harness-research-runs.ts +15 -3
- package/src/tools/agent-harness-research-workflow.ts +92 -19
- package/src/tools/agent-harness-setup-model-helpers.ts +1 -0
- package/src/tools/agent-harness-setup-smoke.ts +26 -1
- package/src/tools/agent-harness-tool-schema.ts +23 -1
- package/src/tools/agent-harness-tool-types.ts +5 -0
- package/src/tools/agent-harness-tool.ts +9 -1
- package/src/tools/agent-harness-workspace-actions.ts +1 -1
- package/src/tools/agent-memory-tool.ts +40 -1
- package/src/tools/agent-model-compare-run.ts +13 -0
- package/src/tools/agent-research-runner.ts +367 -0
- package/src/tools/agent-research-tool.ts +7 -179
- package/src/tools/agent-route-planner-candidates-surfaces.ts +1 -1
- package/src/version.ts +1 -1
|
@@ -24,6 +24,8 @@ import type { PromptContextReceipt } from '../agent/prompt-context-receipts.ts';
|
|
|
24
24
|
import { discoverProjectContextFiles } from '../agent/project-context-files.ts';
|
|
25
25
|
import { getAgentRuntimeProfilesRoot, listAgentRuntimeProfiles, listAgentRuntimeProfileTemplates, readAgentRuntimeProfileSelection } from '../agent/runtime-profile.ts';
|
|
26
26
|
import { RoutineScheduleReceiptStore } from '../agent/routine-schedule-receipts.ts';
|
|
27
|
+
import { buildSetupWizardDurableReceipts } from '../agent/setup-wizard-artifact-receipts.ts';
|
|
28
|
+
import { mergeSetupWizardDurableReceipts, setupWizardLiveDurableReceipts } from './setup-wizard-live-receipts.ts';
|
|
27
29
|
import { readSetupWizardCheckpoint } from '../agent/setup-wizard-checkpoint.ts';
|
|
28
30
|
import { discoverVibeFiles } from '../agent/vibe-file.ts';
|
|
29
31
|
import {
|
|
@@ -35,6 +37,7 @@ import {
|
|
|
35
37
|
buildAgentSetupWizard,
|
|
36
38
|
emptyAgentSetupSmokeHistory,
|
|
37
39
|
emptyAgentSetupWizardCheckpoint,
|
|
40
|
+
setupStepHasSatisfyingReceipt,
|
|
38
41
|
type AgentSetupWizard,
|
|
39
42
|
type AgentSetupWizardBlockedCheckFrequency,
|
|
40
43
|
type AgentSetupWizardCheckpoint,
|
|
@@ -266,6 +269,11 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
266
269
|
return { available: false, items: [] };
|
|
267
270
|
}
|
|
268
271
|
})();
|
|
272
|
+
const setupSmokeHistory = buildSetupSmokeHistory(artifactListSnapshot.items, artifactListSnapshot.available);
|
|
273
|
+
const durableSetupReceipts = mergeSetupWizardDurableReceipts(
|
|
274
|
+
buildSetupWizardDurableReceipts(artifactListSnapshot.items),
|
|
275
|
+
setupWizardLiveDurableReceipts(context),
|
|
276
|
+
);
|
|
269
277
|
const recentReviewerHandoffs = (() => {
|
|
270
278
|
try {
|
|
271
279
|
const handoffs = artifactListSnapshot.items
|
|
@@ -452,6 +460,12 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
452
460
|
voiceProviders: voiceProviderDescriptors,
|
|
453
461
|
mediaProviders: mediaProviderDescriptors,
|
|
454
462
|
});
|
|
463
|
+
const browserPwaEnabled = readConfigBoolean(context, 'web.enabled', false);
|
|
464
|
+
const browserPwaPublicBaseUrl = readConfigString(context, 'web.publicBaseUrl', '(not configured)');
|
|
465
|
+
const connectedHostAuthReceiptReady = setupStepHasSatisfyingReceipt(durableSetupReceipts, 'connected-host-auth');
|
|
466
|
+
const installSmokeReceiptReady = setupSmokeHistory.latestResult === 'ready-for-user-run'
|
|
467
|
+
|| setupStepHasSatisfyingReceipt(durableSetupReceipts, 'install-smoke');
|
|
468
|
+
const browserPwaReceiptReady = setupStepHasSatisfyingReceipt(durableSetupReceipts, 'browser-pwa');
|
|
455
469
|
const setupChecklist = buildAgentWorkspaceSetupChecklist({
|
|
456
470
|
provider,
|
|
457
471
|
model,
|
|
@@ -460,6 +474,7 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
460
474
|
connectedHostTokenReadable: companionAccess.tokenReadable,
|
|
461
475
|
connectedHostTokenPath: companionAccess.tokenPath,
|
|
462
476
|
connectedHostTokenError: companionAccess.tokenError,
|
|
477
|
+
connectedHostAuthReceiptReady,
|
|
463
478
|
activeSubscriptionCount: subscriptionSnapshot.active,
|
|
464
479
|
pendingSubscriptionCount: subscriptionSnapshot.pending,
|
|
465
480
|
availableSubscriptionProviderCount: subscriptionSnapshot.available,
|
|
@@ -483,14 +498,19 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
483
498
|
readyChannelCount: channels.filter((channel) => channel.ready).length,
|
|
484
499
|
voiceProviderCount: voiceProviders.length,
|
|
485
500
|
mediaProviderCount: mediaProviders.length,
|
|
501
|
+
installSmokeReceiptReady,
|
|
502
|
+
browserPwaEnabled,
|
|
503
|
+
browserPwaPublicBaseUrl,
|
|
504
|
+
browserPwaFirstRunReceiptStatus: browserPwaReceiptReady ? 'published' : 'not-published',
|
|
486
505
|
runtimeProfileCount: runtimeProfiles.length,
|
|
487
506
|
runtimeStarterTemplateCount: runtimeStarterTemplates.length,
|
|
488
507
|
});
|
|
489
508
|
const setupWizard = buildWorkspaceSetupWizard(
|
|
490
509
|
setupChecklist,
|
|
491
|
-
|
|
510
|
+
setupSmokeHistory,
|
|
492
511
|
buildSetupWizardCheckpoint(context),
|
|
493
512
|
setupCompletionMarkerExists(context),
|
|
513
|
+
durableSetupReceipts,
|
|
494
514
|
);
|
|
495
515
|
const researchBrowserRunnerContract = buildResearchBrowserRunnerContract(context);
|
|
496
516
|
const researchVisualReportContract = buildResearchVisualReportContract(researchSourceSnapshot);
|
|
@@ -619,8 +639,8 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
619
639
|
mcpConnectedServerCount: mcpSnapshot.connectedCount,
|
|
620
640
|
mcpQuarantinedServerCount: mcpSnapshot.quarantinedCount,
|
|
621
641
|
mcpAllowAllServerCount: mcpSnapshot.allowAllCount,
|
|
622
|
-
browserToolExposureEnabled:
|
|
623
|
-
browserToolPublicBaseUrl:
|
|
642
|
+
browserToolExposureEnabled: browserPwaEnabled,
|
|
643
|
+
browserToolPublicBaseUrl: browserPwaPublicBaseUrl,
|
|
624
644
|
activeRuntimeProfile: inferActiveRuntimeProfile(context.workspace?.shellPaths?.homeDirectory ?? ''),
|
|
625
645
|
selectedRuntimeProfile: selectedRuntimeProfile?.id ?? null,
|
|
626
646
|
selectedRuntimeProfileExists: selectedRuntimeProfile?.exists ?? false,
|
|
@@ -19,7 +19,7 @@ import { deleteAgentWorkspaceMemoryEditor, submitAgentWorkspaceMemoryEditor } fr
|
|
|
19
19
|
import { jumpAgentWorkspaceSelection, moveAgentWorkspaceSelection, selectAgentWorkspaceCategory } from './agent-workspace-navigation.ts';
|
|
20
20
|
import { appendAgentWorkspaceActionSearchText, backspaceAgentWorkspaceActionSearch, beginAgentWorkspaceActionSearch, clearAgentWorkspaceActionSearch, commitAgentWorkspaceActionSearchSelection, searchAgentWorkspaceActions } from './agent-workspace-search.ts';
|
|
21
21
|
import { applyAgentWorkspaceSetupCheckpointAction } from './agent-workspace-setup-checkpoint-action.ts';
|
|
22
|
-
import { agentWorkspaceSettingSchema, applyAgentWorkspaceSettingValue, buildAgentWorkspaceSettingActionEffect, importAgentWorkspaceTuiSettings, isAgentWorkspaceActionVisible } from './agent-workspace-settings.ts';
|
|
22
|
+
import { agentWorkspaceSettingSchema, applyAgentWorkspaceSettingValue, buildAgentWorkspaceSettingActionEffect, buildAgentWorkspaceSettingActionPreview, importAgentWorkspaceTuiSettings, isAgentWorkspaceActionVisible } from './agent-workspace-settings.ts';
|
|
23
23
|
import { buildAgentWorkspaceRuntimeSnapshot } from './agent-workspace-snapshot.ts';
|
|
24
24
|
import { submitAgentWorkspaceSubscriptionLoginFinishEditor, submitAgentWorkspaceSubscriptionLoginStartEditor, submitAgentWorkspaceSubscriptionLogoutEditor } from './agent-workspace-subscription-editor.ts';
|
|
25
25
|
import type { AgentWorkspaceAction, AgentWorkspaceActionResult, AgentWorkspaceActionSearchResult, AgentWorkspaceCategory, AgentWorkspaceCommandDispatcher, AgentWorkspaceEditorField, AgentWorkspaceFocusPane, AgentWorkspaceLocalEditor, AgentWorkspaceLocalEditorKind, AgentWorkspaceLocalLibraryItem, AgentWorkspaceLocalOperation, AgentWorkspacePromptDispatcher, AgentWorkspaceRuntimeSnapshot } from './agent-workspace-types.ts';
|
|
@@ -142,6 +142,10 @@ export class AgentWorkspace {
|
|
|
142
142
|
return selectedAgentWorkspaceLocalLibraryItem(this.runtimeSnapshot, this.selectedLibraryItemIndexes, kind);
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
settingActionPreview(action: AgentWorkspaceAction): string | null {
|
|
146
|
+
return buildAgentWorkspaceSettingActionPreview(this.context, action);
|
|
147
|
+
}
|
|
148
|
+
|
|
145
149
|
focusCategories(): void {
|
|
146
150
|
this.focusPane = 'categories';
|
|
147
151
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { CommandContext } from './command-registry.ts';
|
|
2
|
+
import { buildSetupWizardDurableReceiptsFromReadModel, mergeSetupWizardDurableReceipts } from '../agent/setup-wizard-artifact-receipts.ts';
|
|
3
|
+
import type { AgentSetupWizardDurableReceipt } from '../agent/setup-wizard.ts';
|
|
4
|
+
|
|
5
|
+
interface SetupReceiptReadModelSource {
|
|
6
|
+
readonly path: string;
|
|
7
|
+
readonly source: unknown;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function readRecord(value: unknown): Record<string, unknown> {
|
|
11
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function setupReceiptReadModelSources(context: CommandContext): readonly SetupReceiptReadModelSource[] {
|
|
15
|
+
const contextRecord = context as unknown as Record<string, unknown>;
|
|
16
|
+
const platform = readRecord(contextRecord.platform);
|
|
17
|
+
const clients = readRecord(contextRecord.clients);
|
|
18
|
+
const readModels = readRecord(platform.readModels);
|
|
19
|
+
const setup = readRecord(readModels.setup);
|
|
20
|
+
const setupWizard = readRecord(readModels.setupWizard);
|
|
21
|
+
const firstRun = readRecord(readModels.firstRun);
|
|
22
|
+
const browserPwa = readRecord(readModels.browserPwa);
|
|
23
|
+
const operator = readRecord(clients.operator);
|
|
24
|
+
return [
|
|
25
|
+
{ path: 'context.platform.readModels.setup.receipts', source: setup.receipts },
|
|
26
|
+
{ path: 'context.platform.readModels.setup.setupReceipts', source: setup.setupReceipts },
|
|
27
|
+
{ path: 'context.platform.readModels.setup.receiptEvents', source: setup.receiptEvents },
|
|
28
|
+
{ path: 'context.platform.readModels.setup.eventStream', source: setup.eventStream },
|
|
29
|
+
{ path: 'context.platform.readModels.setup', source: readModels.setup },
|
|
30
|
+
{ path: 'context.platform.readModels.setupWizard.receipts', source: setupWizard.receipts },
|
|
31
|
+
{ path: 'context.platform.readModels.setupWizard.durableReceipts', source: setupWizard.durableReceipts },
|
|
32
|
+
{ path: 'context.platform.readModels.setupWizard.receiptEvents', source: setupWizard.receiptEvents },
|
|
33
|
+
{ path: 'context.platform.readModels.setupWizard.eventStream', source: setupWizard.eventStream },
|
|
34
|
+
{ path: 'context.platform.readModels.setupReceipts', source: readModels.setupReceipts },
|
|
35
|
+
{ path: 'context.platform.readModels.setupReceiptEvents', source: readModels.setupReceiptEvents },
|
|
36
|
+
{ path: 'context.platform.readModels.setupReceiptEventStream', source: readModels.setupReceiptEventStream },
|
|
37
|
+
{ path: 'context.platform.readModels.durableSetupReceipts', source: readModels.durableSetupReceipts },
|
|
38
|
+
{ path: 'context.platform.readModels.firstRun.receipts', source: firstRun.receipts },
|
|
39
|
+
{ path: 'context.platform.readModels.browserPwa.firstRunReceipts', source: browserPwa.firstRunReceipts },
|
|
40
|
+
{ path: 'context.platform.setupReceipts', source: platform.setupReceipts },
|
|
41
|
+
{ path: 'context.platform.setupReceiptEvents', source: platform.setupReceiptEvents },
|
|
42
|
+
{ path: 'context.clients.operator.setupReceipts', source: operator.setupReceipts },
|
|
43
|
+
{ path: 'context.clients.operator.setupReceiptEvents', source: operator.setupReceiptEvents },
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readSnapshot(source: unknown): unknown {
|
|
48
|
+
if (typeof source === 'function') {
|
|
49
|
+
const result = (source as () => unknown)();
|
|
50
|
+
return result instanceof Promise ? undefined : result;
|
|
51
|
+
}
|
|
52
|
+
const record = readRecord(source);
|
|
53
|
+
for (const methodName of ['getSnapshot', 'snapshot', 'list', 'listReceipts', 'listEvents', 'listReceiptEvents', 'readEvents']) {
|
|
54
|
+
const method = record[methodName];
|
|
55
|
+
if (typeof method === 'function') {
|
|
56
|
+
const result = (method as () => unknown)();
|
|
57
|
+
return result instanceof Promise ? undefined : result;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return source;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function setupWizardLiveDurableReceipts(context: CommandContext): readonly AgentSetupWizardDurableReceipt[] {
|
|
64
|
+
const receipts: AgentSetupWizardDurableReceipt[][] = [];
|
|
65
|
+
for (const entry of setupReceiptReadModelSources(context)) {
|
|
66
|
+
if (entry.source === undefined || entry.source === null) continue;
|
|
67
|
+
try {
|
|
68
|
+
receipts.push([...buildSetupWizardDurableReceiptsFromReadModel(readSnapshot(entry.source), entry.path)]);
|
|
69
|
+
} catch {
|
|
70
|
+
// Broken host read models should not hide local setup posture.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return mergeSetupWizardDurableReceipts(...receipts);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { mergeSetupWizardDurableReceipts };
|
|
@@ -83,6 +83,21 @@ function setupOverviewLines(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLin
|
|
|
83
83
|
fg: wizard.smokeHistory.latestResult === 'blocked' ? PALETTE.warn : PALETTE.info,
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
+
if (wizard.stepHistory.length > 0) {
|
|
87
|
+
const latest = wizard.stepHistory[0]!;
|
|
88
|
+
lines.push({
|
|
89
|
+
text: `Step history: ${wizard.stepHistory.length} recorded; latest ${latest.stepLabel} ${latest.kind} at ${latest.recordedAt}.`,
|
|
90
|
+
fg: PALETTE.good,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (wizard.receiptGaps.length > 0) {
|
|
94
|
+
const labels = wizard.receiptGaps.slice(0, 3).map((gap) => gap.stepLabel).join(', ');
|
|
95
|
+
const suffix = wizard.receiptGaps.length > 3 ? `, +${wizard.receiptGaps.length - 3} more` : '';
|
|
96
|
+
lines.push({
|
|
97
|
+
text: `Receipt gaps: ${labels}${suffix} still need durable setup receipt ids.`,
|
|
98
|
+
fg: PALETTE.warn,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
86
101
|
return lines;
|
|
87
102
|
}
|
|
88
103
|
|
|
@@ -257,13 +272,13 @@ function promptReceiptTimelineLines(snapshot: AgentWorkspaceRuntimeSnapshot): Co
|
|
|
257
272
|
fg: promptReceiptOutcomeColor(latest.outcomeStatus),
|
|
258
273
|
bold: latest.outcomeStatus === 'error' || latest.outcomeStatus === 'cancelled',
|
|
259
274
|
});
|
|
260
|
-
lines.push({ text: `
|
|
275
|
+
lines.push({ text: `Latest prompt receipt: ${latest.receiptId}; inspect it from Prompt context.`, fg: PALETTE.good });
|
|
261
276
|
if (timeline.errorCount > 0) {
|
|
262
|
-
lines.push({ text:
|
|
277
|
+
lines.push({ text: 'Prompt receipt filter: show errors.', fg: PALETTE.warn });
|
|
263
278
|
} else if (timeline.cancelledCount > 0) {
|
|
264
|
-
lines.push({ text:
|
|
279
|
+
lines.push({ text: 'Prompt receipt filter: show cancelled turns.', fg: PALETTE.warn });
|
|
265
280
|
} else if (timeline.pendingCount > 0) {
|
|
266
|
-
lines.push({ text:
|
|
281
|
+
lines.push({ text: 'Prompt receipt filter: show pending turns.', fg: PALETTE.info });
|
|
267
282
|
}
|
|
268
283
|
for (const receipt of timeline.items.slice(0, 3)) {
|
|
269
284
|
lines.push({
|
|
@@ -274,7 +289,7 @@ function promptReceiptTimelineLines(snapshot: AgentWorkspaceRuntimeSnapshot): Co
|
|
|
274
289
|
if (latest.detail) {
|
|
275
290
|
lines.push({ text: `Latest outcome detail: ${compactText(latest.detail, 104)}`, fg: PALETTE.warn });
|
|
276
291
|
}
|
|
277
|
-
lines.push({ text:
|
|
292
|
+
lines.push({ text: 'Prompt context controls stay read-only from this setup page.', fg: PALETTE.good });
|
|
278
293
|
return lines;
|
|
279
294
|
}
|
|
280
295
|
|
|
@@ -478,7 +493,7 @@ export function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspac
|
|
|
478
493
|
{ text: `VIBE.md: ${vibe.applied} applied; ${vibe.blocked} blocked; ${vibe.truncated} truncated.`, fg: vibe.blocked > 0 ? PALETTE.warn : vibe.applied > 0 ? PALETTE.good : PALETTE.muted },
|
|
479
494
|
{ text: `Project context: ${projectContext.loaded} loaded; ${projectContext.blocked} blocked; ${projectContext.truncated} truncated.`, fg: projectContext.blocked > 0 ? PALETTE.warn : projectContext.loaded > 0 ? PALETTE.good : PALETTE.muted },
|
|
480
495
|
...promptReceiptTimelineLines(snapshot),
|
|
481
|
-
{ text: 'Context
|
|
496
|
+
{ text: 'Context controls: prompt receipts, project files, one-file inspection, and VIBE.md review.', fg: PALETTE.good },
|
|
482
497
|
);
|
|
483
498
|
} else if (category.id === 'onboarding-automation') {
|
|
484
499
|
base.push(
|
|
@@ -68,10 +68,42 @@ function actionCommand(action: AgentWorkspaceAction): string {
|
|
|
68
68
|
return action.command ?? '(guidance)';
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
function
|
|
71
|
+
function isOnboardingCategory(category: AgentWorkspaceCategory): boolean {
|
|
72
|
+
return category.group === 'ONBOARDING';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function onboardingActionChange(workspace: AgentWorkspace, action: AgentWorkspaceAction): string {
|
|
76
|
+
if (action.kind === 'setting') {
|
|
77
|
+
return workspace.settingActionPreview(action) ?? 'Update setting';
|
|
78
|
+
}
|
|
79
|
+
if (action.kind === 'settings-import') return 'Import compatible GoodVibes preferences';
|
|
80
|
+
if (action.kind === 'setup-checkpoint') {
|
|
81
|
+
if (action.setupCheckpointOperation === 'show') return 'Show saved setup progress';
|
|
82
|
+
if (action.setupCheckpointOperation === 'mark-current') return 'Save current setup progress';
|
|
83
|
+
if (action.setupCheckpointOperation === 'clear') return 'Clear saved setup progress';
|
|
84
|
+
return 'Review setup progress';
|
|
85
|
+
}
|
|
86
|
+
if (action.kind === 'model-picker') return action.modelPickerFlow === 'model' ? 'Choose a model' : 'Choose provider and model';
|
|
87
|
+
if (action.kind === 'settings-modal') return 'Open settings';
|
|
88
|
+
if (action.kind === 'workspace') return 'Open setup area';
|
|
89
|
+
if (action.kind === 'editor') return 'Open guided form';
|
|
90
|
+
if (action.kind === 'local-selection') return 'Move selection';
|
|
91
|
+
if (action.kind === 'local-operation') return 'Apply selected library action';
|
|
92
|
+
if (action.kind === 'onboarding-complete') return 'Save setup completion';
|
|
93
|
+
if (action.safety === 'read-only') return 'Review readiness';
|
|
94
|
+
if (action.safety === 'blocked') return 'Unavailable in this setup step';
|
|
95
|
+
return 'Open option';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function actionChange(workspace: AgentWorkspace, category: AgentWorkspaceCategory, action: AgentWorkspaceAction): string {
|
|
99
|
+
return isOnboardingCategory(category) ? onboardingActionChange(workspace, action) : actionCommand(action);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function actionMetaLine(workspace: AgentWorkspace, category: AgentWorkspaceCategory, action: AgentWorkspaceAction): ContextLine {
|
|
103
|
+
const onboarding = isOnboardingCategory(category);
|
|
72
104
|
return {
|
|
73
|
-
text:
|
|
74
|
-
fg: action.safety === 'blocked' ? PALETTE.warn : action.kind === 'command' ? PALETTE.info : PALETTE.muted,
|
|
105
|
+
text: `${onboarding ? 'Change' : 'Does'}: ${actionChange(workspace, category, action)}`,
|
|
106
|
+
fg: action.safety === 'blocked' ? PALETTE.warn : !onboarding && action.kind === 'command' ? PALETTE.info : PALETTE.muted,
|
|
75
107
|
};
|
|
76
108
|
}
|
|
77
109
|
|
|
@@ -135,19 +167,20 @@ function buildContextRows(workspace: AgentWorkspace, category: AgentWorkspaceCat
|
|
|
135
167
|
const selectedActionLines: ContextLine[] = action
|
|
136
168
|
? [
|
|
137
169
|
{ text: `Selected: ${action.label}`, fg: PALETTE.title, bold: true },
|
|
138
|
-
actionMetaLine(action),
|
|
170
|
+
actionMetaLine(workspace, category, action),
|
|
139
171
|
]
|
|
140
172
|
: [];
|
|
141
173
|
const snapshotContextLines = snapshotLines(workspace, category, workspace.runtimeSnapshot);
|
|
142
174
|
lines.push(...selectedActionLines, ...snapshotContextLines);
|
|
143
175
|
|
|
176
|
+
const onboarding = isOnboardingCategory(category);
|
|
144
177
|
if (workspace.lastActionResult) {
|
|
145
178
|
lines.push(
|
|
146
|
-
{ text: 'Action Result', fg: PALETTE.title, bold: true },
|
|
179
|
+
{ text: onboarding ? 'Result' : 'Action Result', fg: PALETTE.title, bold: true },
|
|
147
180
|
{ text: workspace.lastActionResult.title, fg: actionResultColor(workspace.lastActionResult), bold: true },
|
|
148
181
|
{ text: compactText(workspace.lastActionResult.detail), fg: PALETTE.text },
|
|
149
182
|
);
|
|
150
|
-
if (workspace.lastActionResult.command) {
|
|
183
|
+
if (!onboarding && workspace.lastActionResult.command) {
|
|
151
184
|
lines.push({ text: `Command: ${workspace.lastActionResult.command}`, fg: PALETTE.muted });
|
|
152
185
|
}
|
|
153
186
|
}
|
|
@@ -213,6 +246,8 @@ function buildEditorFieldRows(editor: AgentWorkspaceLocalEditor, index: number,
|
|
|
213
246
|
|
|
214
247
|
function buildActionRows(workspace: AgentWorkspace, width: number, height: number): WorkspaceRow[] {
|
|
215
248
|
if (workspace.localEditor) return buildEditorRows(workspace.localEditor, width, height);
|
|
249
|
+
const category = workspace.selectedActionCategory;
|
|
250
|
+
const onboarding = isOnboardingCategory(category);
|
|
216
251
|
const rows: WorkspaceRow[] = [];
|
|
217
252
|
const labelWidth = Math.min(34, Math.max(18, Math.floor(width * 0.38)));
|
|
218
253
|
const commandWidth = Math.max(10, width - labelWidth - 6);
|
|
@@ -224,7 +259,7 @@ function buildActionRows(workspace: AgentWorkspace, width: number, height: numbe
|
|
|
224
259
|
});
|
|
225
260
|
}
|
|
226
261
|
rows.push({
|
|
227
|
-
text: ` ${padDisplay(workspace.actionSearchActive ? 'Result' : 'Action', labelWidth)} ${padDisplay('Does', commandWidth)}`,
|
|
262
|
+
text: ` ${padDisplay(workspace.actionSearchActive ? 'Result' : onboarding ? 'Option' : 'Action', labelWidth)} ${padDisplay(onboarding ? 'Change' : 'Does', commandWidth)}`,
|
|
228
263
|
fg: PALETTE.muted,
|
|
229
264
|
bold: true,
|
|
230
265
|
});
|
|
@@ -238,10 +273,11 @@ function buildActionRows(workspace: AgentWorkspace, width: number, height: numbe
|
|
|
238
273
|
const action = actions[index]!;
|
|
239
274
|
const selected = index === workspace.selectedActionIndex;
|
|
240
275
|
const searchResult = workspace.actionSearchActive ? workspace.actionSearchResults[index] : null;
|
|
276
|
+
const actionCategory = searchResult?.category ?? category;
|
|
241
277
|
const label = searchResult ? `${searchResult.category.label} / ${action.label}` : action.label;
|
|
242
278
|
const marker = selected ? GLYPHS.navigation.selected : ' ';
|
|
243
279
|
rows.push({
|
|
244
|
-
text: `${marker} ${padDisplay(label, labelWidth)} ${padDisplay(
|
|
280
|
+
text: `${marker} ${padDisplay(label, labelWidth)} ${padDisplay(actionChange(workspace, actionCategory, action), commandWidth)}`,
|
|
245
281
|
selected: selected && workspace.focusPane === 'actions',
|
|
246
282
|
fg: action.safety === 'blocked' ? PALETTE.warn : selected ? PALETTE.text : PALETTE.info,
|
|
247
283
|
bold: selected,
|
|
@@ -253,11 +289,11 @@ function buildActionRows(workspace: AgentWorkspace, width: number, height: numbe
|
|
|
253
289
|
rows.push({ text: `Status: ${workspace.status}`, fg: PALETTE.muted });
|
|
254
290
|
if (workspace.lastActionResult) {
|
|
255
291
|
rows.push({ text: '' });
|
|
256
|
-
rows.push({ text:
|
|
292
|
+
rows.push({ text: `${onboarding ? 'Result' : 'Action Result'}: ${workspace.lastActionResult.title}`, fg: actionResultColor(workspace.lastActionResult), bold: true });
|
|
257
293
|
for (const line of wrapText(workspace.lastActionResult.detail, Math.max(1, width - 2))) {
|
|
258
294
|
rows.push({ text: ` ${line}`, fg: PALETTE.text });
|
|
259
295
|
}
|
|
260
|
-
if (workspace.lastActionResult.command) {
|
|
296
|
+
if (!onboarding && workspace.lastActionResult.command) {
|
|
261
297
|
rows.push({ text: ` Command: ${workspace.lastActionResult.command}`, fg: PALETTE.muted });
|
|
262
298
|
}
|
|
263
299
|
}
|
|
@@ -67,7 +67,7 @@ const READ_ONLY_VIBE_ACTIONS = new Set(['', 'status', 'summary', 'list', 'show',
|
|
|
67
67
|
const READ_ONLY_PERSONAL_OPS_ACTIONS = new Set(['', 'briefing', 'brief', 'daily', 'daily_brief', 'morning', 'status', 'summary', 'overview', 'map', 'list', 'queue', 'queues', 'review_queue', 'review_queues', 'personal_queue', 'ops_queue', 'intake', 'request', 'route', 'plan', 'triage', 'draft', 'lane', 'inspect', 'show']);
|
|
68
68
|
const READ_ONLY_RESEARCH_ACTIONS = new Set(['', 'briefing', 'brief', 'status', 'dashboard', 'cockpit', 'next', 'plan', 'workflow', 'research', 'runner', 'browser', 'browser_runner', 'browser_backed', 'deep_research', 'runs', 'list_runs', 'run_list', 'run', 'show_run', 'inspect_run', 'sources', 'queue', 'source_queue', 'source', 'show_source', 'inspect_source', 'bundle', 'bundle_sources', 'source_bundle', 'search', 'public_search', 'collect', 'collect_sources', 'source_candidates', 'reports', 'list_reports', 'report_list', 'visual_reports', 'report_artifact', 'show_report', 'inspect_report', 'show_visual_report', 'visual_report_artifact']);
|
|
69
69
|
const READ_ONLY_CHANNELS_ACTIONS = new Set(['', 'status', 'summary', 'list', 'readiness', 'channels', 'channel', 'show', 'inspect', 'setup', 'guide', 'setup_guide', 'channel_setup_guide', 'triage', 'inbox', 'blockers', 'retries', 'channel_triage', 'deliveries', 'delivery', 'receipts', 'history', 'channel_deliveries']);
|
|
70
|
-
const READ_ONLY_MEMORY_ACTIONS = new Set(['', 'status', 'summary', 'posture', 'memory_posture', 'recall', 'providers', 'provider', 'memory_provider', 'embedding', 'external', 'external_provider', 'curator', 'learning', 'learning_curator', 'queue', 'review_queue', 'plan', 'candidate', 'learning_candidate', 'card', 'inspect_candidate', 'list', 'records', 'memories', 'search', 'find', 'lookup', 'get', 'show', 'inspect', 'read']);
|
|
70
|
+
const READ_ONLY_MEMORY_ACTIONS = new Set(['', 'status', 'summary', 'posture', 'memory_posture', 'recall', 'providers', 'provider', 'memory_provider', 'embedding', 'external', 'external_provider', 'refinement', 'refinement_tasks', 'semantic_refinement', 'self_improvement', 'semantic_self_improvement', 'learning_loop', 'curator', 'learning', 'learning_curator', 'queue', 'review_queue', 'plan', 'candidate', 'learning_candidate', 'card', 'inspect_candidate', 'list', 'records', 'memories', 'search', 'find', 'lookup', 'get', 'show', 'inspect', 'read']);
|
|
71
71
|
const READ_ONLY_COMPUTER_ACTIONS = new Set(['', 'status', 'summary', 'overview', 'computer', 'computer_use', 'plan', 'route', 'control_plan', 'browser_plan', 'desktop_plan', 'control', 'browser_control', 'desktop', 'desktop_control', 'screenshot', 'screen', 'screen_recording', 'observe', 'browser', 'pwa', 'cockpit', 'browser_cockpit', 'web', 'setup', 'configure', 'browser_desktop_control', 'mcp', 'tools', 'servers', 'mcp_servers']);
|
|
72
72
|
const READ_ONLY_DEVICE_ACTIONS = new Set(['', 'status', 'map', 'capabilities', 'device', 'devices', 'mobile', 'phone', 'pairing', 'capability', 'route', 'pairing_route', 'show', 'inspect', 'browser', 'pwa', 'cockpit', 'browser_cockpit', 'web', 'control', 'browser_control', 'desktop', 'desktop_control', 'computer_use', 'voice', 'media', 'voice_media', 'workflows', 'provider', 'media_provider', 'voice_provider']);
|
|
73
73
|
const READ_ONLY_MODELS_ACTIONS = new Set(['', 'status', 'routing', 'routes', 'models', 'model', 'readiness', 'route_readiness', 'route', 'model_route', 'inspect', 'show', 'candidate', 'endpoint', 'local', 'cookbook', 'local_cookbook', 'recipes', 'recipe', 'ollama', 'llama_cpp', 'llamacpp', 'vllm', 'local_servers', 'providers', 'provider_accounts', 'accounts', 'subscriptions', 'auth', 'logins', 'provider', 'provider_account', 'account', 'subscription', 'auth_status']);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export const AGENT_TOOL_MODES = [
|
|
2
|
+
'spawn',
|
|
3
|
+
'batch-spawn',
|
|
4
|
+
'list',
|
|
5
|
+
'templates',
|
|
6
|
+
'status',
|
|
7
|
+
'get',
|
|
8
|
+
'budget',
|
|
9
|
+
'plan',
|
|
10
|
+
'wait',
|
|
11
|
+
'message',
|
|
12
|
+
'cancel',
|
|
13
|
+
'wrfc-chains',
|
|
14
|
+
'wrfc-history',
|
|
15
|
+
'cohort-status',
|
|
16
|
+
'cohort-report',
|
|
17
|
+
] as const;
|
|
18
|
+
|
|
19
|
+
export const AGENT_TEMPLATES = ['orchestrator', 'engineer', 'reviewer', 'tester', 'researcher', 'integrator', 'general'] as const;
|
|
20
|
+
|
|
21
|
+
export function agentOrchestrationDecisionCards(agentToolAvailable: boolean): readonly Record<string, unknown>[] {
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
id: 'serial-by-default',
|
|
25
|
+
label: 'Stay serial by default',
|
|
26
|
+
status: 'ready',
|
|
27
|
+
chooseWhen: ['Ordinary chat, planning, research, setup, local context, and short current-workspace tool work.'],
|
|
28
|
+
route: 'main conversation',
|
|
29
|
+
reason: 'Lowest-friction route for the user when parallelism does not improve outcome.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'visible-single-agent',
|
|
33
|
+
label: 'Spawn one visible agent',
|
|
34
|
+
status: agentToolAvailable ? 'ready' : 'unavailable',
|
|
35
|
+
chooseWhen: ['A bounded autonomous task can run independently with visible status and cancellation.'],
|
|
36
|
+
requiredFields: ['task', 'successCriteria or requiredEvidence when outcome quality matters'],
|
|
37
|
+
modelRoute: 'agent { mode: "spawn" }',
|
|
38
|
+
inspectRoute: 'agent_harness mode:"agent_orchestration"',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 'visible-batch-spawn',
|
|
42
|
+
label: 'Batch-spawn independent agents',
|
|
43
|
+
status: agentToolAvailable ? 'ready' : 'unavailable',
|
|
44
|
+
chooseWhen: ['Tasks are genuinely independent and parallel work materially improves time-to-result.'],
|
|
45
|
+
doNotUseWhen: ['Review/test/verification role fanout for one deliverable; that collapses to one owner chain.'],
|
|
46
|
+
requiredFields: ['tasks[]', 'authoritativeTask for the original user ask when applicable'],
|
|
47
|
+
modelRoute: 'agent { mode: "batch-spawn" }',
|
|
48
|
+
inspectRoute: 'agent_harness mode:"agent_orchestration"',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'managed-multi-runner-plan',
|
|
52
|
+
label: 'Use a managed multi-runner plan',
|
|
53
|
+
status: agentToolAvailable ? 'ready' : 'unavailable',
|
|
54
|
+
chooseWhen: ['A large task already has approval for parallel work and needs milestones, evidence, and cancellation routes.'],
|
|
55
|
+
requiredFields: ['original user ask', 'lane reason', 'success criteria', 'per-runner evidence', 'cancel/recovery route'],
|
|
56
|
+
modelRoute: 'agent_work_plan action:"dispatch_agents" ids:["..."] confirm:true explicitUserRequest:"..."',
|
|
57
|
+
inspectRoute: 'agent_harness mode:"agent_orchestration"',
|
|
58
|
+
policy: 'Read-only plan surface first; approved work-plan dispatch, spawn, message, wait, cancel, or remote mutation stays on confirmed first-class routes.',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: 'inspect-or-control-visible-agent',
|
|
62
|
+
label: 'Inspect or control a visible agent',
|
|
63
|
+
status: agentToolAvailable ? 'ready' : 'unavailable',
|
|
64
|
+
chooseWhen: ['The user asks for progress, budget, plan, message, wait, cancel, WRFC chain, or cohort status.'],
|
|
65
|
+
modelRoutes: ['agent { mode: "list" }', 'agent { mode: "get" }', 'agent { mode: "message" }', 'agent { mode: "wait" }', 'agent { mode: "cancel" }'],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: 'hidden-fanout-blocked',
|
|
69
|
+
label: 'Block hidden fanout',
|
|
70
|
+
status: 'blocked',
|
|
71
|
+
chooseWhen: ['A request implies invisible background agents, unmanaged parallel coding workers, or orphaned jobs.'],
|
|
72
|
+
saferRoutes: ['visible work plan', 'research run', 'confirmed schedule', 'agent { mode: "spawn" }', 'delegation action:"status"'],
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
}
|