@pellux/goodvibes-agent 1.1.7 → 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 +329 -0
- package/README.md +46 -30
- package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
- package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
- package/dist/package/main.js +138903 -91477
- package/docs/README.md +14 -7
- package/docs/channels-remote-and-api.md +8 -5
- package/docs/connected-host.md +14 -12
- package/docs/getting-started.md +58 -30
- package/docs/knowledge-artifacts-and-multimodal.md +7 -5
- package/docs/project-planning.md +2 -2
- package/docs/providers-and-routing.md +11 -3
- package/docs/tools-and-commands.md +116 -45
- package/docs/voice-and-live-tts.md +3 -1
- package/package.json +3 -2
- package/release/release-notes.md +142 -5
- package/release/release-readiness.json +124 -94
- package/src/agent/assistant-cockpit.ts +247 -0
- package/src/agent/autonomy-schedule-format.ts +96 -0
- package/src/agent/autonomy-schedule.ts +514 -0
- package/src/agent/channel-delivery-receipts.ts +292 -0
- package/src/agent/competitive-feature-inventory.ts +294 -0
- package/src/agent/document-registry-types.ts +106 -0
- package/src/agent/document-registry.ts +734 -0
- package/src/agent/harness-control.ts +2 -2
- package/src/agent/memory-prompt.ts +2 -2
- package/src/agent/operator-actions.ts +50 -6
- package/src/agent/persona-registry.ts +8 -0
- package/src/agent/project-context-files.ts +273 -0
- package/src/agent/prompt-context-receipts.ts +502 -0
- package/src/agent/reminder-schedule-format.ts +16 -2
- package/src/agent/research-run-registry.ts +582 -0
- package/src/agent/research-source-registry.ts +441 -0
- package/src/agent/routine-registry.ts +19 -3
- package/src/agent/routine-schedule-format.ts +27 -2
- package/src/agent/runtime-profile-starters.ts +7 -0
- package/src/agent/runtime-profile.ts +106 -4
- package/src/agent/schedule-edit-format.ts +129 -0
- package/src/agent/schedule-edit.ts +496 -0
- package/src/agent/schedule-next-routes.ts +42 -0
- package/src/agent/setup-wizard-artifact-receipts.ts +366 -0
- package/src/agent/setup-wizard-checkpoint.ts +140 -0
- package/src/agent/setup-wizard.ts +683 -0
- package/src/agent/skill-registry-types.ts +102 -0
- package/src/agent/skill-registry.ts +81 -107
- package/src/agent/vibe-confirmation-routes.ts +62 -0
- package/src/agent/vibe-file.ts +285 -0
- package/src/cli/agent-knowledge-command.ts +45 -2
- package/src/cli/help.ts +3 -0
- package/src/cli/profiles-command.ts +25 -11
- package/src/config/agent-settings-policy.ts +1 -18
- package/src/input/agent-workspace-activation.ts +53 -0
- package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
- package/src/input/agent-workspace-artifact-metadata.ts +17 -0
- package/src/input/agent-workspace-basic-command-editors.ts +5 -1
- package/src/input/agent-workspace-categories.ts +153 -155
- package/src/input/agent-workspace-channel-triage.ts +481 -0
- package/src/input/agent-workspace-channels.ts +263 -0
- package/src/input/agent-workspace-command-editor.ts +152 -0
- package/src/input/agent-workspace-context-snapshot.ts +349 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
- package/src/input/agent-workspace-document-editor.ts +502 -0
- package/src/input/agent-workspace-document-ops-editor.ts +523 -0
- package/src/input/agent-workspace-host-category.ts +1 -1
- package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
- package/src/input/agent-workspace-model-compare-editor.ts +376 -0
- package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
- package/src/input/agent-workspace-model-compare-types.ts +82 -0
- package/src/input/agent-workspace-model-compare-utils.ts +35 -0
- package/src/input/agent-workspace-onboarding-categories.ts +141 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
- package/src/input/agent-workspace-operations-command-editors.ts +22 -0
- package/src/input/agent-workspace-research-report-editor.ts +212 -0
- package/src/input/agent-workspace-research-run-editor.ts +144 -0
- package/src/input/agent-workspace-research-source-editor.ts +167 -0
- package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
- package/src/input/agent-workspace-review-packet-utils.ts +265 -0
- package/src/input/agent-workspace-settings.ts +313 -30
- package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
- package/src/input/agent-workspace-setup-snapshot.ts +217 -0
- package/src/input/agent-workspace-setup.ts +61 -1
- package/src/input/agent-workspace-snapshot.ts +184 -149
- package/src/input/agent-workspace-types.ts +287 -2
- package/src/input/agent-workspace.ts +23 -1
- package/src/input/command-registry.ts +9 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
- package/src/input/commands/channels-runtime.ts +102 -114
- package/src/input/commands/delegation-runtime.ts +87 -24
- package/src/input/commands/knowledge-browser-flags.ts +12 -0
- package/src/input/commands/knowledge.ts +28 -14
- package/src/input/commands/operator-actions-runtime.ts +6 -3
- package/src/input/commands/schedule-runtime.ts +71 -14
- package/src/input/commands/session-content.ts +2 -2
- package/src/input/commands/shell-core.ts +2 -0
- package/src/input/commands/vibe-runtime.ts +140 -0
- package/src/input/commands.ts +2 -0
- package/src/input/connected-host-routes.ts +123 -0
- package/src/input/settings-modal-types.ts +14 -0
- package/src/input/setup-wizard-live-receipts.ts +76 -0
- package/src/main.ts +15 -15
- package/src/panels/qr-panel.ts +2 -2
- package/src/renderer/agent-workspace-context-lines.ts +701 -0
- package/src/renderer/agent-workspace.ts +68 -421
- package/src/renderer/settings-modal-helpers.ts +12 -0
- package/src/renderer/settings-modal.ts +12 -0
- package/src/runtime/bootstrap-command-context.ts +11 -1
- package/src/runtime/bootstrap-command-parts.ts +14 -3
- package/src/runtime/bootstrap-core.ts +39 -1
- package/src/runtime/bootstrap-shell.ts +6 -0
- package/src/runtime/bootstrap.ts +113 -30
- package/src/runtime/connected-host-auth.ts +3 -2
- package/src/runtime/execution-ledger.ts +231 -0
- package/src/runtime/services.ts +88 -10
- package/src/runtime/tool-permission-safety.ts +199 -5
- package/src/shell/session-continuity-hints.ts +39 -0
- package/src/tools/agent-artifacts-tool.ts +606 -0
- package/src/tools/agent-audit-tool.ts +155 -0
- package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
- package/src/tools/agent-autonomy-tool.ts +140 -0
- package/src/tools/agent-channel-send-tool.ts +24 -2
- package/src/tools/agent-channels-tool.ts +140 -0
- package/src/tools/agent-computer-tool.ts +168 -0
- package/src/tools/agent-context-policy.ts +137 -7
- package/src/tools/agent-context-tool.ts +143 -0
- package/src/tools/agent-delegation-tool.ts +128 -0
- package/src/tools/agent-device-tool.ts +240 -0
- package/src/tools/agent-documents-tool.ts +684 -0
- package/src/tools/agent-execution-tool.ts +230 -0
- package/src/tools/agent-harness-agent-orchestration-policy.ts +75 -0
- package/src/tools/agent-harness-agent-orchestration.ts +791 -0
- package/src/tools/agent-harness-autonomy-intake.ts +785 -0
- package/src/tools/agent-harness-autonomy-live-records.ts +742 -0
- package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
- package/src/tools/agent-harness-autonomy-queue.ts +571 -0
- package/src/tools/agent-harness-autonomy-watcher-read-models.ts +509 -0
- package/src/tools/agent-harness-background-processes-types.ts +35 -0
- package/src/tools/agent-harness-background-processes.ts +798 -0
- package/src/tools/agent-harness-browser-cockpit-route.ts +373 -0
- package/src/tools/agent-harness-browser-control.ts +346 -0
- package/src/tools/agent-harness-browser-pwa-read-models.ts +622 -0
- package/src/tools/agent-harness-channel-metadata.ts +168 -10
- package/src/tools/agent-harness-cli-command-policy.ts +110 -0
- package/src/tools/agent-harness-command-catalog.ts +4 -2
- package/src/tools/agent-harness-command-runner.ts +42 -0
- package/src/tools/agent-harness-connected-host-status.ts +7 -4
- package/src/tools/agent-harness-delegation-posture.ts +234 -19
- package/src/tools/agent-harness-device-live-read-models.ts +366 -0
- package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
- package/src/tools/agent-harness-document-ops-types.ts +72 -0
- package/src/tools/agent-harness-document-ops.ts +671 -0
- package/src/tools/agent-harness-execution-history.ts +489 -0
- package/src/tools/agent-harness-execution-posture.ts +385 -0
- package/src/tools/agent-harness-file-recovery.ts +135 -0
- package/src/tools/agent-harness-interactive-runtime-records.ts +421 -0
- package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
- package/src/tools/agent-harness-learning-curator-common.ts +102 -0
- package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
- package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
- package/src/tools/agent-harness-learning-curator-types.ts +151 -0
- package/src/tools/agent-harness-learning-curator.ts +417 -0
- package/src/tools/agent-harness-local-model-benchmarks.ts +269 -0
- package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
- package/src/tools/agent-harness-local-model-endpoints.ts +788 -0
- 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 +223 -2
- package/src/tools/agent-harness-memory-external-providers.ts +796 -0
- package/src/tools/agent-harness-memory-posture.ts +672 -0
- 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-metadata.ts +100 -168
- package/src/tools/agent-harness-mode-catalog.ts +86 -33
- package/src/tools/agent-harness-model-catalog.ts +162 -0
- package/src/tools/agent-harness-model-provider-health.ts +283 -0
- package/src/tools/agent-harness-model-readiness.ts +432 -0
- package/src/tools/agent-harness-model-routing-types.ts +327 -0
- package/src/tools/agent-harness-model-routing-utils.ts +30 -0
- package/src/tools/agent-harness-model-routing.ts +165 -193
- package/src/tools/agent-harness-operator-methods.ts +115 -133
- package/src/tools/agent-harness-pairing-posture.ts +452 -18
- package/src/tools/agent-harness-personal-ops-certification.ts +116 -0
- package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
- package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
- package/src/tools/agent-harness-personal-ops-lanes.ts +270 -0
- 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 +684 -0
- package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
- package/src/tools/agent-harness-personal-ops-types.ts +240 -0
- package/src/tools/agent-harness-personal-ops.ts +613 -0
- package/src/tools/agent-harness-project-context.ts +144 -0
- package/src/tools/agent-harness-prompt-context.ts +589 -0
- package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
- package/src/tools/agent-harness-release-evidence.ts +9 -7
- package/src/tools/agent-harness-release-readiness.ts +9 -7
- package/src/tools/agent-harness-remote-read-models.ts +541 -0
- package/src/tools/agent-harness-research-briefing.ts +446 -0
- package/src/tools/agent-harness-research-live-read-models.ts +500 -0
- package/src/tools/agent-harness-research-queue.ts +250 -0
- package/src/tools/agent-harness-research-runs.ts +307 -0
- package/src/tools/agent-harness-research-workflow.ts +395 -0
- package/src/tools/agent-harness-security-posture.ts +2 -2
- package/src/tools/agent-harness-service-posture.ts +9 -9
- package/src/tools/agent-harness-session-metadata.ts +3 -3
- package/src/tools/agent-harness-setup-connected-host.ts +501 -0
- package/src/tools/agent-harness-setup-describe.ts +557 -0
- package/src/tools/agent-harness-setup-handoffs.ts +502 -0
- package/src/tools/agent-harness-setup-model-helpers.ts +102 -0
- package/src/tools/agent-harness-setup-plan.ts +253 -0
- package/src/tools/agent-harness-setup-posture-types.ts +218 -0
- package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
- package/src/tools/agent-harness-setup-posture.ts +449 -221
- package/src/tools/agent-harness-setup-smoke.ts +533 -0
- package/src/tools/agent-harness-sudo-posture.ts +114 -0
- package/src/tools/agent-harness-tool-schema.ts +142 -7
- package/src/tools/agent-harness-tool-types.ts +83 -0
- package/src/tools/agent-harness-tool-utils.ts +43 -0
- package/src/tools/agent-harness-tool.ts +319 -370
- package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
- package/src/tools/agent-harness-ui-surface-types.ts +46 -0
- package/src/tools/agent-harness-vibe-health.ts +105 -0
- package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
- package/src/tools/agent-harness-workspace-actions.ts +114 -8
- package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
- package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
- package/src/tools/agent-host-tool.ts +159 -0
- package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
- package/src/tools/agent-learning-consolidation-core.ts +327 -0
- package/src/tools/agent-learning-consolidation-tool.ts +758 -0
- package/src/tools/agent-memory-tool.ts +253 -0
- package/src/tools/agent-model-compare-export.ts +315 -0
- package/src/tools/agent-model-compare-handoff.ts +592 -0
- package/src/tools/agent-model-compare-judgment.ts +633 -0
- package/src/tools/agent-model-compare-run.ts +735 -0
- package/src/tools/agent-model-compare-tool.ts +698 -0
- package/src/tools/agent-model-compare-types.ts +191 -0
- package/src/tools/agent-model-compare-utils.ts +93 -0
- package/src/tools/agent-models-tool.ts +208 -0
- package/src/tools/agent-operator-action-tool.ts +1 -1
- package/src/tools/agent-operator-method-tool.ts +643 -0
- package/src/tools/agent-personal-ops-tool.ts +197 -0
- package/src/tools/agent-policy-explanation.ts +415 -0
- package/src/tools/agent-research-report-tool.ts +608 -0
- package/src/tools/agent-research-runner.ts +367 -0
- package/src/tools/agent-research-runs-tool.ts +434 -0
- package/src/tools/agent-research-sources-tool.ts +443 -0
- package/src/tools/agent-research-tool.ts +515 -0
- package/src/tools/agent-review-packet-presets-core.ts +757 -0
- package/src/tools/agent-review-packet-presets-tool.ts +466 -0
- package/src/tools/agent-review-packet-share-tool.ts +305 -0
- package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
- package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
- package/src/tools/agent-route-planner-candidates-work.ts +251 -0
- package/src/tools/agent-route-planner-helpers.ts +667 -0
- package/src/tools/agent-route-planner.ts +185 -0
- package/src/tools/agent-route-tool.ts +105 -0
- package/src/tools/agent-schedule-edit-tool.ts +210 -0
- package/src/tools/agent-schedule-tool.ts +282 -0
- package/src/tools/agent-security-tool.ts +145 -0
- package/src/tools/agent-sessions-tool.ts +122 -0
- package/src/tools/agent-settings-import-tool.ts +104 -0
- package/src/tools/agent-settings-tool.ts +176 -0
- package/src/tools/agent-setup-tool.ts +226 -0
- package/src/tools/agent-support-tool.ts +122 -0
- package/src/tools/agent-terminal-process-tools.ts +167 -0
- package/src/tools/agent-tool-policy-guard-types.ts +77 -0
- package/src/tools/agent-tool-policy-guard.ts +106 -85
- package/src/tools/agent-vibe-tool.ts +297 -0
- package/src/tools/agent-work-plan-tool.ts +265 -6
- package/src/tools/agent-workspace-tool.ts +305 -0
- package/src/tools/artifact-archive.ts +169 -0
- package/src/tools/tool-definition-compaction.ts +36 -0
- package/src/version.ts +1 -1
|
@@ -5,9 +5,8 @@ import type {
|
|
|
5
5
|
AgentWorkspaceLocalEditor,
|
|
6
6
|
AgentWorkspaceRuntimeSnapshot,
|
|
7
7
|
} from '../input/agent-workspace.ts';
|
|
8
|
-
import { formatAgentRecordReviewState } from '../agent/record-labels.ts';
|
|
9
8
|
import type { Line } from '../types/grid.ts';
|
|
10
|
-
import {
|
|
9
|
+
import { wrapText } from '../utils/terminal-width.ts';
|
|
11
10
|
import { GLYPHS } from './ui-primitives.ts';
|
|
12
11
|
import {
|
|
13
12
|
getFullscreenWorkspaceMetrics,
|
|
@@ -17,7 +16,8 @@ import {
|
|
|
17
16
|
WORKSPACE_PALETTE as PALETTE,
|
|
18
17
|
type WorkspaceRow,
|
|
19
18
|
} from './fullscreen-workspace.ts';
|
|
20
|
-
import { actionResultColor,
|
|
19
|
+
import { actionResultColor, type AgentWorkspaceContextLine as ContextLine } from './agent-workspace-style.ts';
|
|
20
|
+
import { compactText, reviewerReadinessContextLines, snapshotLines } from './agent-workspace-context-lines.ts';
|
|
21
21
|
|
|
22
22
|
function buildLeftRows(workspace: AgentWorkspace, height: number): WorkspaceRow[] {
|
|
23
23
|
const rows: WorkspaceRow[] = [];
|
|
@@ -59,6 +59,7 @@ function actionCommand(action: AgentWorkspaceAction): string {
|
|
|
59
59
|
if (action.kind === 'editor') return action.editorKind ? `edit ${action.editorKind}` : 'edit form';
|
|
60
60
|
if (action.kind === 'setting') return action.settingKey ? `setting ${action.settingKey}` : 'setting';
|
|
61
61
|
if (action.kind === 'settings-import') return 'import GoodVibes settings';
|
|
62
|
+
if (action.kind === 'setup-checkpoint') return action.setupCheckpointOperation ? `setup checkpoint ${action.setupCheckpointOperation}` : 'setup checkpoint';
|
|
62
63
|
if (action.kind === 'model-picker') return action.modelPickerFlow === 'model' ? 'model picker' : 'provider/model picker';
|
|
63
64
|
if (action.kind === 'settings-modal') return action.settingsTarget ? `settings ${action.settingsTarget}` : 'settings';
|
|
64
65
|
if (action.kind === 'local-selection') return action.selectionDelta && action.selectionDelta < 0 ? 'select previous' : 'select next';
|
|
@@ -67,428 +68,46 @@ function actionCommand(action: AgentWorkspaceAction): string {
|
|
|
67
68
|
return action.command ?? '(guidance)';
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
function
|
|
71
|
-
return
|
|
72
|
-
ready: snapshot.setupChecklist.filter((item) => item.status === 'ready').length,
|
|
73
|
-
recommended: snapshot.setupChecklist.filter((item) => item.status === 'recommended').length,
|
|
74
|
-
optional: snapshot.setupChecklist.filter((item) => item.status === 'optional').length,
|
|
75
|
-
blocked: snapshot.setupChecklist.filter((item) => item.status === 'blocked').length,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function setupStatusLabel(status: AgentWorkspaceRuntimeSnapshot['setupChecklist'][number]['status']): string {
|
|
80
|
-
return status === 'ready'
|
|
81
|
-
? 'Ready'
|
|
82
|
-
: status === 'recommended'
|
|
83
|
-
? 'Recommended'
|
|
84
|
-
: status === 'blocked'
|
|
85
|
-
? 'Blocked'
|
|
86
|
-
: 'Optional';
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function formatMegabytes(bytes: number): string {
|
|
90
|
-
if (!Number.isFinite(bytes) || bytes <= 0) return '0 MB';
|
|
91
|
-
return `${Math.round(bytes / (1024 * 1024))} MB`;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function compactText(text: string, maxWidth = 104): string {
|
|
95
|
-
const normalized = text.replace(/\s+/g, ' ').trim();
|
|
96
|
-
if (normalized.length === 0) return '';
|
|
97
|
-
const firstSentence = normalized.match(/^.*?[.!?](?:\s|$)/)?.[0]?.trim();
|
|
98
|
-
const source = firstSentence && firstSentence.length <= maxWidth ? firstSentence : normalized;
|
|
99
|
-
return truncateDisplay(source, maxWidth, '...');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function actionMetaLine(action: AgentWorkspaceAction): ContextLine {
|
|
103
|
-
return {
|
|
104
|
-
text: `Does: ${actionCommand(action)}`,
|
|
105
|
-
fg: action.safety === 'blocked' ? PALETTE.warn : action.kind === 'command' ? PALETTE.info : PALETTE.muted,
|
|
106
|
-
};
|
|
71
|
+
function isOnboardingCategory(category: AgentWorkspaceCategory): boolean {
|
|
72
|
+
return category.group === 'ONBOARDING';
|
|
107
73
|
}
|
|
108
74
|
|
|
109
|
-
function
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
...snapshot.setupChecklist.filter((item) => item.status === 'recommended'),
|
|
113
|
-
...snapshot.setupChecklist.filter((item) => item.status === 'optional'),
|
|
114
|
-
].slice(0, limit);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function conciseSetupLine(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine {
|
|
118
|
-
const counts = setupCounts(snapshot);
|
|
119
|
-
return {
|
|
120
|
-
text: `Setup: ${counts.ready}/${snapshot.setupChecklist.length} ready; ${counts.recommended} recommended; ${counts.blocked} blocked.`,
|
|
121
|
-
fg: counts.blocked > 0 ? PALETTE.warn : PALETTE.info,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function setupOverviewLines(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine[] {
|
|
126
|
-
const counts = setupCounts(snapshot);
|
|
127
|
-
const nextItems = setupAttentionItems(snapshot, 3);
|
|
128
|
-
const lines: ContextLine[] = [
|
|
129
|
-
{ text: 'Onboarding', fg: PALETTE.title, bold: true },
|
|
130
|
-
{ text: `${counts.ready}/${snapshot.setupChecklist.length} ready; ${counts.recommended} recommended; ${counts.optional} optional; ${counts.blocked} blocked.`, fg: counts.blocked > 0 ? PALETTE.warn : PALETTE.info },
|
|
131
|
-
{ text: `Chat: ${snapshot.provider} / ${snapshot.modelDisplayName}.`, fg: PALETTE.info },
|
|
132
|
-
{ text: `Local: ${snapshot.localPersonaCount} personas, ${snapshot.localSkillCount} skills, ${snapshot.localRoutineCount} routines, ${snapshot.localMemoryCount} memories.`, fg: PALETTE.info },
|
|
133
|
-
];
|
|
134
|
-
if (nextItems.length > 0) {
|
|
135
|
-
const item = nextItems[0]!;
|
|
136
|
-
lines.push({
|
|
137
|
-
text: `Next: ${item.label} (${setupStatusLabel(item.status).toLowerCase()})`,
|
|
138
|
-
fg: setupStatusColor(item.status),
|
|
139
|
-
bold: item.status === 'blocked',
|
|
140
|
-
});
|
|
75
|
+
function onboardingActionChange(workspace: AgentWorkspace, action: AgentWorkspaceAction): string {
|
|
76
|
+
if (action.kind === 'setting') {
|
|
77
|
+
return workspace.settingActionPreview(action) ?? 'Update setting';
|
|
141
78
|
}
|
|
142
|
-
return
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return [
|
|
149
|
-
{ text: 'Next Actions', fg: PALETTE.title, bold: true },
|
|
150
|
-
{ text: 'Core setup is ready. Continue normal assistant work, review Knowledge sources, or tune local skills/routines as needed.', fg: PALETTE.good },
|
|
151
|
-
];
|
|
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';
|
|
152
85
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
function companionAccessLine(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine {
|
|
165
|
-
const access = snapshot.companionAccess;
|
|
166
|
-
const tokenState = access.tokenReadable
|
|
167
|
-
? `ready sha256:${access.tokenFingerprint ?? 'unknown'}`
|
|
168
|
-
: access.tokenPresent
|
|
169
|
-
? 'present but unreadable'
|
|
170
|
-
: 'missing';
|
|
171
|
-
const error = access.tokenError ? `; token read error ${access.tokenError}` : '';
|
|
172
|
-
return {
|
|
173
|
-
text: `Companion: ${access.surface}; token ${tokenState}; QR ${access.qrCommand}${error}.`,
|
|
174
|
-
fg: access.pairingReady ? PALETTE.good : PALETTE.warn,
|
|
175
|
-
};
|
|
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';
|
|
176
96
|
}
|
|
177
97
|
|
|
178
|
-
function
|
|
179
|
-
|
|
180
|
-
items: readonly AgentWorkspaceRuntimeSnapshot['localPersonas'][number][],
|
|
181
|
-
emptyText: string,
|
|
182
|
-
selectedId: string | null,
|
|
183
|
-
): ContextLine[] {
|
|
184
|
-
const lines: ContextLine[] = [];
|
|
185
|
-
if (items.length === 0) {
|
|
186
|
-
lines.push({ text: `${title}: 0. ${emptyText}`, fg: PALETTE.warn });
|
|
187
|
-
return lines;
|
|
188
|
-
}
|
|
189
|
-
const selected = items.find((item) => item.id === selectedId) ?? items[0]!;
|
|
190
|
-
const status = [
|
|
191
|
-
selected.active ? 'active' : '',
|
|
192
|
-
selected.enabled === true ? 'enabled' : selected.enabled === false ? 'disabled' : '',
|
|
193
|
-
selected.scope && selected.cls ? `${selected.scope}/${selected.cls}` : '',
|
|
194
|
-
selected.confidence !== undefined ? `${selected.confidence}%` : '',
|
|
195
|
-
selected.requirementCount !== undefined && selected.requirementCount > 0
|
|
196
|
-
? (selected.missingRequirementCount && selected.missingRequirementCount > 0 ? `needs ${selected.missingRequirementCount}/${selected.requirementCount}` : `ready ${selected.requirementCount}/${selected.requirementCount}`)
|
|
197
|
-
: '',
|
|
198
|
-
formatAgentRecordReviewState(selected.reviewState),
|
|
199
|
-
selected.startCount !== undefined ? `starts ${selected.startCount}` : '',
|
|
200
|
-
].filter(Boolean).join(', ');
|
|
201
|
-
lines.push({
|
|
202
|
-
text: `${title}: ${items.length}; selected ${selected.name}${status ? ` (${status})` : ''}.`,
|
|
203
|
-
fg: selected.reviewState === 'stale' ? PALETTE.warn : PALETTE.info,
|
|
204
|
-
bold: selected.active === true,
|
|
205
|
-
});
|
|
206
|
-
if (selected.missingRequirements && selected.missingRequirements.length > 0) {
|
|
207
|
-
lines.push({ text: `Missing setup: ${selected.missingRequirements.join(', ')}`, fg: PALETTE.warn });
|
|
208
|
-
}
|
|
209
|
-
return lines;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
type LocalRoutineItem = AgentWorkspaceRuntimeSnapshot['localRoutines'][number];
|
|
213
|
-
|
|
214
|
-
function readyRoutineItems(snapshot: AgentWorkspaceRuntimeSnapshot): readonly LocalRoutineItem[] {
|
|
215
|
-
return snapshot.localRoutines.filter((routine) =>
|
|
216
|
-
routine.enabled === true
|
|
217
|
-
&& routine.reviewState === 'reviewed'
|
|
218
|
-
&& (routine.missingRequirementCount ?? 0) === 0
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function routinesNeedingSetup(snapshot: AgentWorkspaceRuntimeSnapshot): readonly LocalRoutineItem[] {
|
|
223
|
-
return snapshot.localRoutines.filter((routine) => (routine.missingRequirementCount ?? 0) > 0);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function routinesNeedingReview(snapshot: AgentWorkspaceRuntimeSnapshot): readonly LocalRoutineItem[] {
|
|
227
|
-
return snapshot.localRoutines.filter((routine) => routine.reviewState !== 'reviewed');
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function routineNextActionLine(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine {
|
|
231
|
-
const discovered = snapshot.discoveredBehavior.routines.count;
|
|
232
|
-
const ready = readyRoutineItems(snapshot);
|
|
233
|
-
const needsSetup = routinesNeedingSetup(snapshot);
|
|
234
|
-
const needsReview = routinesNeedingReview(snapshot);
|
|
235
|
-
|
|
236
|
-
if (snapshot.localRoutineCount === 0 && discovered > 0) {
|
|
237
|
-
return { text: 'Next routine action: Discover routine files, preview one, then import it from this workspace.', fg: PALETTE.warn, bold: true };
|
|
238
|
-
}
|
|
239
|
-
if (snapshot.localRoutineCount === 0) {
|
|
240
|
-
return { text: 'Next routine action: Create routine for a repeatable main-conversation workflow.', fg: PALETTE.warn, bold: true };
|
|
241
|
-
}
|
|
242
|
-
if (needsSetup.length > 0) {
|
|
243
|
-
return { text: `Next routine action: Needs setup for ${needsSetup[0]?.id ?? 'a routine'} before it can be trusted for schedule promotion.`, fg: PALETTE.warn, bold: true };
|
|
244
|
-
}
|
|
245
|
-
if (needsReview.length > 0) {
|
|
246
|
-
return { text: `Next routine action: Review selected or inspect ${needsReview[0]?.id ?? 'a routine'} before schedule promotion.`, fg: PALETTE.warn, bold: true };
|
|
247
|
-
}
|
|
248
|
-
if (ready.length > 0 && snapshot.routineScheduleReceiptCount === 0) {
|
|
249
|
-
return { text: `Next routine action: Promote ${ready[0]?.id ?? 'a reviewed routine'} to a connected schedule when you have a real cadence.`, fg: PALETTE.good, bold: true };
|
|
250
|
-
}
|
|
251
|
-
return { text: 'Next routine action: Start selected in the main conversation, inspect receipts, or reconcile connected schedules.', fg: PALETTE.info, bold: true };
|
|
98
|
+
function actionChange(workspace: AgentWorkspace, category: AgentWorkspaceCategory, action: AgentWorkspaceAction): string {
|
|
99
|
+
return isOnboardingCategory(category) ? onboardingActionChange(workspace, action) : actionCommand(action);
|
|
252
100
|
}
|
|
253
101
|
|
|
254
|
-
function
|
|
255
|
-
const
|
|
256
|
-
if (!latest) {
|
|
257
|
-
return {
|
|
258
|
-
text: `Promotion receipts: ${snapshot.routineScheduleReceiptCount}; none created yet.`,
|
|
259
|
-
fg: PALETTE.muted,
|
|
260
|
-
};
|
|
261
|
-
}
|
|
102
|
+
function actionMetaLine(workspace: AgentWorkspace, category: AgentWorkspaceCategory, action: AgentWorkspaceAction): ContextLine {
|
|
103
|
+
const onboarding = isOnboardingCategory(category);
|
|
262
104
|
return {
|
|
263
|
-
text:
|
|
264
|
-
fg:
|
|
105
|
+
text: `${onboarding ? 'Change' : 'Does'}: ${actionChange(workspace, category, action)}`,
|
|
106
|
+
fg: action.safety === 'blocked' ? PALETTE.warn : !onboarding && action.kind === 'command' ? PALETTE.info : PALETTE.muted,
|
|
265
107
|
};
|
|
266
108
|
}
|
|
267
109
|
|
|
268
|
-
function
|
|
269
|
-
const ready = readyRoutineItems(snapshot);
|
|
270
|
-
const needsSetup = routinesNeedingSetup(snapshot);
|
|
271
|
-
const needsReview = routinesNeedingReview(snapshot);
|
|
272
|
-
if (snapshot.routineScheduleReceiptCount > 0) {
|
|
273
|
-
return { text: 'Next automation action: Reconcile schedules to compare local receipts with the connected host.', fg: PALETTE.info, bold: true };
|
|
274
|
-
}
|
|
275
|
-
if (ready.length > 0) {
|
|
276
|
-
return { text: `Next automation action: Promote ${ready[0]?.id ?? 'a reviewed routine'} or create a one-off reminder.`, fg: PALETTE.good, bold: true };
|
|
277
|
-
}
|
|
278
|
-
if (needsSetup.length > 0) {
|
|
279
|
-
return { text: `Next automation action: Resolve routine setup gaps in ${needsSetup[0]?.id ?? 'Routines'} before promotion, or create a reminder.`, fg: PALETTE.warn, bold: true };
|
|
280
|
-
}
|
|
281
|
-
if (needsReview.length > 0) {
|
|
282
|
-
return { text: `Next automation action: Review ${needsReview[0]?.id ?? 'a routine'} in Routines before schedule promotion, or create a reminder.`, fg: PALETTE.warn, bold: true };
|
|
283
|
-
}
|
|
284
|
-
return { text: 'Next automation action: Create a reminder, or create/import a routine before recurring workflow promotion.', fg: PALETTE.warn, bold: true };
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCategory, snapshot: AgentWorkspaceRuntimeSnapshot | null): ContextLine[] {
|
|
288
|
-
if (!snapshot) return [{ text: 'Runtime context is not loaded yet.', fg: PALETTE.warn }];
|
|
289
|
-
const base: ContextLine[] = [];
|
|
290
|
-
if (category.id === 'home') {
|
|
291
|
-
base.push(
|
|
292
|
-
{ text: `Chat route: ${snapshot.provider} / ${snapshot.modelDisplayName}`, fg: PALETTE.info },
|
|
293
|
-
{ text: `Session: ${snapshot.sessionId}`, fg: PALETTE.muted },
|
|
294
|
-
{ text: `Policy: ${snapshot.executionPolicy}; delegated review ${snapshot.delegatedReviewPolicy}`, fg: PALETTE.good },
|
|
295
|
-
conciseSetupLine(snapshot),
|
|
296
|
-
...homeNextActionLines(snapshot),
|
|
297
|
-
);
|
|
298
|
-
} else if (category.id === 'setup') {
|
|
299
|
-
base.push(
|
|
300
|
-
...setupOverviewLines(snapshot),
|
|
301
|
-
);
|
|
302
|
-
} else if (category.id === 'account-model') {
|
|
303
|
-
base.push(
|
|
304
|
-
{ text: `Chat route: ${snapshot.provider} / ${snapshot.modelDisplayName}`, fg: PALETTE.info },
|
|
305
|
-
{ text: `Subscriptions: ${snapshot.activeSubscriptionCount} active; ${snapshot.pendingSubscriptionCount} pending; ${snapshot.availableSubscriptionProviderCount} available.`, fg: snapshot.activeSubscriptionCount > 0 ? PALETTE.good : snapshot.pendingSubscriptionCount > 0 ? PALETTE.warn : PALETTE.muted },
|
|
306
|
-
{ text: `Embedding: ${snapshot.embeddingProvider}; reasoning ${snapshot.reasoningEffort}.`, fg: PALETTE.info },
|
|
307
|
-
{ text: `Helper: ${snapshot.helperEnabled ? 'enabled' : 'disabled'}; Tool LLM: ${snapshot.toolLlmEnabled ? 'enabled' : 'disabled'}.`, fg: snapshot.helperEnabled || snapshot.toolLlmEnabled ? PALETTE.good : PALETTE.muted },
|
|
308
|
-
{ text: `Cache: ${snapshot.cacheEnabled ? snapshot.cacheStableTtl : 'off'}; monitor ${snapshot.cacheMonitorHitRate ? snapshot.cacheHitRateWarningThreshold : 'off'}; failure hints ${snapshot.providerFailureHints ? 'on' : 'off'}.`, fg: snapshot.cacheEnabled ? PALETTE.info : PALETTE.muted },
|
|
309
|
-
);
|
|
310
|
-
} else if (category.id === 'assistant-behavior') {
|
|
311
|
-
base.push(
|
|
312
|
-
{ text: `Interaction: ${snapshot.hitlMode}; guidance ${snapshot.guidanceMode}; history ${snapshot.saveHistory ? 'saved' : 'off'}.`, fg: PALETTE.info },
|
|
313
|
-
{ text: `Context: compact at ${snapshot.autoCompactThreshold}; stale warnings ${snapshot.staleContextWarnings ? 'on' : 'off'}.`, fg: PALETTE.info },
|
|
314
|
-
{ text: `Reasoning display: thinking ${snapshot.showThinking ? 'on' : 'off'}; summaries ${snapshot.showReasoningSummary ? 'on' : 'off'}.`, fg: PALETTE.muted },
|
|
315
|
-
);
|
|
316
|
-
} else if (category.id === 'tools-permissions') {
|
|
317
|
-
base.push(
|
|
318
|
-
{ text: `Permission mode: ${snapshot.permissionMode}.`, fg: snapshot.permissionMode === 'allow-all' ? PALETTE.warn : PALETTE.info },
|
|
319
|
-
{ text: `Auto-approve ${snapshot.autoApprove ? 'on' : 'off'}; tool auto-heal ${snapshot.toolAutoHeal ? 'on' : 'off'}; token budget ${snapshot.toolsDefaultTokenBudget}.`, fg: snapshot.autoApprove ? PALETTE.warn : PALETTE.info },
|
|
320
|
-
{ text: `Artifact limit ${formatMegabytes(snapshot.artifactMaxBytes)}; raw prompt telemetry ${snapshot.rawPromptTelemetry ? 'on' : 'off'}.`, fg: snapshot.rawPromptTelemetry ? PALETTE.warn : PALETTE.muted },
|
|
321
|
-
{ text: `MCP servers: ${snapshot.mcpConnectedServerCount}/${snapshot.mcpServerCount} connected; quarantined ${snapshot.mcpQuarantinedServerCount}.`, fg: snapshot.mcpQuarantinedServerCount > 0 ? PALETTE.warn : PALETTE.info },
|
|
322
|
-
{ text: 'MCP and secret setup use forms; selecting a row does not run arbitrary tools.', fg: PALETTE.good },
|
|
323
|
-
);
|
|
324
|
-
} else if (category.id === 'onboarding-display') {
|
|
325
|
-
base.push(
|
|
326
|
-
{ text: `Theme: ${snapshot.theme}; streaming ${snapshot.stream ? 'on' : 'off'}; line numbers ${snapshot.lineNumbers}.`, fg: PALETTE.info },
|
|
327
|
-
{ text: `Messages: operational ${snapshot.operationalMessages}; system ${snapshot.systemMessages}.`, fg: PALETTE.info },
|
|
328
|
-
{ text: `Release channel: ${snapshot.releaseChannel}.`, fg: PALETTE.muted },
|
|
329
|
-
);
|
|
330
|
-
} else if (category.id === 'onboarding-channels') {
|
|
331
|
-
const enabledCount = snapshot.channels.filter((channel) => channel.enabled).length;
|
|
332
|
-
const readyCount = snapshot.channels.filter((channel) => channel.ready).length;
|
|
333
|
-
const needsConfig = snapshot.channels.filter((channel) => channel.setupState === 'needs-config');
|
|
334
|
-
const needsTarget = snapshot.channels.filter((channel) => channel.setupState === 'needs-target');
|
|
335
|
-
base.push(
|
|
336
|
-
{ text: `Channels: ${readyCount}/${snapshot.channels.length} ready; ${enabledCount} enabled.`, fg: enabledCount > 0 ? PALETTE.info : PALETTE.muted },
|
|
337
|
-
{ text: `Needs config: ${needsConfig.length}; needs target: ${needsTarget.length}.`, fg: needsConfig.length > 0 || needsTarget.length > 0 ? PALETTE.warn : PALETTE.good },
|
|
338
|
-
{ text: 'Enable only the channels you want; hidden channel fields appear after the channel is enabled.', fg: PALETTE.good },
|
|
339
|
-
);
|
|
340
|
-
} else if (category.id === 'onboarding-voice-media') {
|
|
341
|
-
const readiness = snapshot.voiceMediaReadiness;
|
|
342
|
-
base.push(
|
|
343
|
-
{ text: `Voice: ${snapshot.voiceSurfaceEnabled ? 'enabled' : 'disabled'}; TTS ${snapshot.ttsProvider}; voice ${snapshot.ttsVoice}.`, fg: snapshot.voiceSurfaceEnabled ? PALETTE.good : PALETTE.info },
|
|
344
|
-
{ text: `Media readiness: ${readiness.readyMediaProviderCount}/${snapshot.mediaProviderCount}; generation providers ${snapshot.mediaGenerationProviderCount}.`, fg: readiness.readyMediaProviderCount > 0 ? PALETTE.good : PALETTE.muted },
|
|
345
|
-
{ text: `Telephony channel: ${snapshot.channels.find((channel) => channel.id === 'telephony')?.setupState ?? 'disabled'}.`, fg: PALETTE.info },
|
|
346
|
-
);
|
|
347
|
-
} else if (category.id === 'onboarding-context') {
|
|
348
|
-
base.push(
|
|
349
|
-
{ text: `Local context: ${snapshot.localMemoryCount} memories, ${snapshot.localNoteCount} notes, ${snapshot.localPersonaCount} personas.`, fg: PALETTE.info },
|
|
350
|
-
{ text: `Skills: ${snapshot.enabledSkillCount}/${snapshot.localSkillCount} enabled; routines ${snapshot.enabledRoutineCount}/${snapshot.localRoutineCount} enabled.`, fg: PALETTE.info },
|
|
351
|
-
{ text: `Discovered files: personas ${snapshot.discoveredBehavior.personas.count}, skills ${snapshot.discoveredBehavior.skills.count}, routines ${snapshot.discoveredBehavior.routines.count}.`, fg: PALETTE.muted },
|
|
352
|
-
);
|
|
353
|
-
} else if (category.id === 'onboarding-automation') {
|
|
354
|
-
base.push(
|
|
355
|
-
{ text: `Automation: ${snapshot.automationEnabled ? 'enabled' : 'disabled'}; max ${snapshot.automationMaxConcurrentRuns} concurrent; history ${snapshot.automationRunHistoryLimit}.`, fg: snapshot.automationEnabled ? PALETTE.good : PALETTE.muted },
|
|
356
|
-
{ text: `Timeout ${snapshot.automationDefaultTimeoutMs} ms; catch-up ${snapshot.automationCatchUpWindowMinutes} min; cooldown ${snapshot.automationFailureCooldownMs} ms.`, fg: PALETTE.info },
|
|
357
|
-
{ text: `Delete one-shot jobs after success: ${snapshot.automationDeleteAfterRun ? 'yes' : 'no'}.`, fg: snapshot.automationDeleteAfterRun ? PALETTE.info : PALETTE.muted },
|
|
358
|
-
);
|
|
359
|
-
} else if (category.id === 'artifacts') {
|
|
360
|
-
const mediaReady = snapshot.voiceMediaReadiness.readyMediaProviderCount;
|
|
361
|
-
base.push(
|
|
362
|
-
{ text: `Chat: ${snapshot.provider} / ${snapshot.modelDisplayName}; Knowledge: ${snapshot.knowledgeRoute}`, fg: PALETTE.info },
|
|
363
|
-
{ text: `Media: ${mediaReady}/${snapshot.mediaProviderCount} ready; generation ${snapshot.mediaGenerationProviderCount}.`, fg: mediaReady > 0 ? PALETTE.good : PALETTE.warn },
|
|
364
|
-
{ text: 'Files: attach, export, inspect, ingest reviewed sources, or generate media.', fg: PALETTE.good },
|
|
365
|
-
{ text: 'Knowledge ingest and media generation require explicit actions.', fg: PALETTE.warn },
|
|
366
|
-
);
|
|
367
|
-
} else if (category.id === 'channels') {
|
|
368
|
-
const enabledCount = snapshot.channels.filter((channel) => channel.enabled).length;
|
|
369
|
-
const readyCount = snapshot.channels.filter((channel) => channel.ready).length;
|
|
370
|
-
const configuredDefaults = snapshot.channels.filter((channel) => channel.defaultTarget === 'configured').length;
|
|
371
|
-
const needsTarget = snapshot.channels.filter((channel) => channel.setupState === 'needs-target');
|
|
372
|
-
const needsConfig = snapshot.channels.filter((channel) => channel.setupState === 'needs-config');
|
|
373
|
-
const nextAttentionChannel = needsConfig[0] ?? needsTarget[0] ?? snapshot.channels.find((channel) => !channel.enabled);
|
|
374
|
-
base.push(
|
|
375
|
-
{ text: `API: ${snapshot.runtimeBaseUrl}`, fg: PALETTE.info },
|
|
376
|
-
companionAccessLine(snapshot),
|
|
377
|
-
{ text: `Channels: ${readyCount}/${snapshot.channels.length} ready; ${enabledCount} enabled; ${configuredDefaults} target(s).`, fg: PALETTE.info },
|
|
378
|
-
{ text: `Next: ${nextAttentionChannel ? `${nextAttentionChannel.label} - ${compactText(nextAttentionChannel.nextStep)}` : 'All enabled channels ready.'}`, fg: nextAttentionChannel ? PALETTE.warn : PALETTE.good },
|
|
379
|
-
{ text: 'Secrets hidden; sends require explicit action.', fg: PALETTE.warn },
|
|
380
|
-
);
|
|
381
|
-
} else if (category.id === 'knowledge') {
|
|
382
|
-
base.push(
|
|
383
|
-
{ text: `Route: ${snapshot.knowledgeRoute}; isolation ${snapshot.knowledgeIsolation}.`, fg: PALETTE.info },
|
|
384
|
-
{ text: 'Ask/search, ingest, review, reindex, and reports stay Agent-owned.', fg: PALETTE.good },
|
|
385
|
-
{ text: 'Ingest requires explicit confirmation.', fg: PALETTE.warn },
|
|
386
|
-
);
|
|
387
|
-
} else if (category.id === 'research') {
|
|
388
|
-
base.push(
|
|
389
|
-
{ text: `Chat: ${snapshot.provider} / ${snapshot.modelDisplayName}; Knowledge: ${snapshot.knowledgeRoute}`, fg: PALETTE.info },
|
|
390
|
-
{ text: `Browser: ${snapshot.voiceMediaReadiness.browserToolState}; public URL ${snapshot.browserToolPublicBaseUrl}.`, fg: snapshot.browserToolExposureEnabled ? PALETTE.warn : PALETTE.muted },
|
|
391
|
-
{ text: 'Research is read-only. Knowledge ingest is a separate confirmed action.', fg: PALETTE.good },
|
|
392
|
-
{ text: compactText(snapshot.voiceMediaReadiness.browserToolNextStep), fg: PALETTE.muted },
|
|
393
|
-
);
|
|
394
|
-
} else if (category.id === 'tools') {
|
|
395
|
-
base.push(
|
|
396
|
-
{ 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 },
|
|
397
|
-
{ text: 'Add/update/reload and trust changes require confirmation.', fg: PALETTE.good },
|
|
398
|
-
{ text: 'Start: /mcp review, /mcp tools, /mcp config, Add MCP server.', fg: PALETTE.muted },
|
|
399
|
-
);
|
|
400
|
-
} else if (category.id === 'voice-media') {
|
|
401
|
-
const readiness = snapshot.voiceMediaReadiness;
|
|
402
|
-
base.push(
|
|
403
|
-
{ text: `Voice: ${readiness.readyVoiceProviderCount}/${snapshot.voiceProviderCount} ready; TTS ${snapshot.ttsProvider}; voice ${snapshot.ttsVoice}.`, fg: readiness.readyVoiceProviderCount > 0 ? PALETTE.good : PALETTE.warn },
|
|
404
|
-
{ text: `Media: ${readiness.readyMediaProviderCount}/${snapshot.mediaProviderCount} ready; generation ${snapshot.mediaGenerationProviderCount}.`, fg: readiness.readyMediaProviderCount > 0 ? PALETTE.good : PALETTE.warn },
|
|
405
|
-
{ text: `Browser: ${readiness.browserToolState}; public URL ${snapshot.browserToolPublicBaseUrl}.`, fg: snapshot.browserToolExposureEnabled ? PALETTE.warn : PALETTE.muted },
|
|
406
|
-
{ text: readiness.nextSteps[0] ? `Next: ${compactText(readiness.nextSteps[0])}` : 'Next: voice/media setup is ready.', fg: readiness.nextSteps.length > 0 ? PALETTE.info : PALETTE.good },
|
|
407
|
-
{ text: 'Secrets hidden; voice, browser, and media side effects require explicit action.', fg: PALETTE.warn },
|
|
408
|
-
);
|
|
409
|
-
} else if (category.id === 'profiles') {
|
|
410
|
-
const defaultProfile = snapshot.selectedRuntimeProfile
|
|
411
|
-
? `${snapshot.selectedRuntimeProfile}${snapshot.selectedRuntimeProfileExists ? '' : ' (missing)'}`
|
|
412
|
-
: '(base Agent home)';
|
|
413
|
-
base.push(
|
|
414
|
-
{ text: `Profiles: active ${snapshot.activeRuntimeProfile}; default ${defaultProfile}.`, fg: snapshot.selectedRuntimeProfileExists || !snapshot.selectedRuntimeProfile ? PALETTE.info : PALETTE.warn },
|
|
415
|
-
{ text: `Local profiles: ${snapshot.runtimeProfileCount}; starters ${snapshot.runtimeStarterTemplateCount}; custom ${snapshot.localStarterTemplateCount}.`, fg: PALETTE.info },
|
|
416
|
-
{ text: `Starter ids: ${truncateDisplay(snapshot.runtimeStarterTemplates.map((template) => template.id).join(', ') || 'none', 96, '...')}`, fg: PALETTE.muted },
|
|
417
|
-
{ text: 'Profiles isolate local Agent config, sessions, memory, personas, skills, routines, setup, and bundles.', fg: PALETTE.good },
|
|
418
|
-
);
|
|
419
|
-
} else if (category.id === 'memory') {
|
|
420
|
-
base.push(
|
|
421
|
-
{ text: `Memory: ${snapshot.localMemoryCount}; prompt ${snapshot.localMemoryPromptActiveCount}; queue ${snapshot.localMemoryReviewQueueCount}; session ${snapshot.sessionMemoryCount}.`, fg: PALETTE.info },
|
|
422
|
-
{ text: `Notes: ${snapshot.localNoteCount}; skills ${snapshot.localSkillCount}/${snapshot.enabledSkillCount}; routines ${snapshot.localRoutineCount}/${snapshot.enabledRoutineCount}; personas ${snapshot.localPersonaCount}.`, fg: PALETTE.info },
|
|
423
|
-
{ text: `Active persona: ${snapshot.activePersonaName}.`, fg: PALETTE.info },
|
|
424
|
-
...compactLocalLibraryLines('Agent Memory', snapshot.localMemories, 'Create one with Create memory.', workspace.selectedLocalLibraryItem('memory')?.id ?? null),
|
|
425
|
-
{ text: 'Secrets are rejected or redacted; use secret references.', fg: PALETTE.warn },
|
|
426
|
-
);
|
|
427
|
-
} else if (category.id === 'notes') {
|
|
428
|
-
base.push(
|
|
429
|
-
{ text: `Scratchpad notes: ${snapshot.localNoteCount}; review queue: ${snapshot.localNoteReviewQueueCount}`, fg: PALETTE.info },
|
|
430
|
-
...compactLocalLibraryLines('Scratchpad Notes', snapshot.localNotes, 'Create one with Create note.', workspace.selectedLocalLibraryItem('note')?.id ?? null),
|
|
431
|
-
{ text: 'Notes stay local unless promoted by explicit action.', fg: PALETTE.warn },
|
|
432
|
-
);
|
|
433
|
-
} else if (category.id === 'personas') {
|
|
434
|
-
base.push(
|
|
435
|
-
{ text: `Personas: ${snapshot.localPersonaCount}; active: ${snapshot.activePersonaName}`, fg: PALETTE.info },
|
|
436
|
-
...compactLocalLibraryLines('Persona Library', snapshot.localPersonas, 'Create one with Create persona.', workspace.selectedLocalLibraryItem('persona')?.id ?? null),
|
|
437
|
-
{ text: 'Personas shape the serial main-conversation assistant.', fg: PALETTE.good },
|
|
438
|
-
);
|
|
439
|
-
} else if (category.id === 'skills') {
|
|
440
|
-
base.push(
|
|
441
|
-
{ text: `Skills: ${snapshot.localSkillCount}; enabled: ${snapshot.enabledSkillCount}; bundles: ${snapshot.localSkillBundleCount}; enabled bundles: ${snapshot.enabledSkillBundleCount}; active skills: ${snapshot.activeSkillCount}`, fg: PALETTE.info },
|
|
442
|
-
...compactLocalLibraryLines('Skill Library', snapshot.localSkills, 'Create one with Create skill.', workspace.selectedLocalLibraryItem('skill')?.id ?? null),
|
|
443
|
-
...compactLocalLibraryLines('Skill Bundles', snapshot.localSkillBundles, 'Create one after adding skills.', null),
|
|
444
|
-
{ text: 'Enabled skills/bundles become operating guidance; secrets are rejected.', fg: PALETTE.warn },
|
|
445
|
-
);
|
|
446
|
-
} else if (category.id === 'routines') {
|
|
447
|
-
const ready = readyRoutineItems(snapshot);
|
|
448
|
-
const needsSetup = routinesNeedingSetup(snapshot);
|
|
449
|
-
const needsReview = routinesNeedingReview(snapshot);
|
|
450
|
-
base.push(
|
|
451
|
-
{ text: `Routines: ${snapshot.localRoutineCount}; enabled: ${snapshot.enabledRoutineCount}`, fg: PALETTE.info },
|
|
452
|
-
{ 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 },
|
|
453
|
-
routineNextActionLine(snapshot),
|
|
454
|
-
compactRoutineReceiptLine(snapshot),
|
|
455
|
-
...compactLocalLibraryLines('Routine Library', snapshot.localRoutines, 'Create one with Create routine.', workspace.selectedLocalLibraryItem('routine')?.id ?? null),
|
|
456
|
-
{ text: 'Scheduling requires a confirmed action.', fg: PALETTE.warn },
|
|
457
|
-
);
|
|
458
|
-
} else if (category.id === 'work') {
|
|
459
|
-
base.push(
|
|
460
|
-
{ text: 'Work plans and approvals are read or explicitly confirmed.', fg: PALETTE.info },
|
|
461
|
-
{ text: 'Selection alone does not approve, deny, cancel, or mutate requests.', fg: PALETTE.good },
|
|
462
|
-
{ text: 'Approval actions require id plus typed confirmation.', fg: PALETTE.warn },
|
|
463
|
-
);
|
|
464
|
-
} else if (category.id === 'automation') {
|
|
465
|
-
const ready = readyRoutineItems(snapshot);
|
|
466
|
-
base.push(
|
|
467
|
-
{ text: `Automation: ${ready.length} schedule-ready routine(s); receipts ${snapshot.routineScheduleReceiptCount}.`, fg: ready.length > 0 ? PALETTE.good : PALETTE.warn },
|
|
468
|
-
automationNextActionLine(snapshot),
|
|
469
|
-
compactRoutineReceiptLine(snapshot),
|
|
470
|
-
{ text: 'Reminders and routine promotion require confirmation.', fg: PALETTE.warn },
|
|
471
|
-
);
|
|
472
|
-
} else if (category.id === 'delegate') {
|
|
473
|
-
base.push(
|
|
474
|
-
{ text: 'Build/fix/review work is handed to GoodVibes TUI.', fg: PALETTE.info },
|
|
475
|
-
{ text: `Delegated review policy: ${snapshot.delegatedReviewPolicy}`, fg: PALETTE.warn },
|
|
476
|
-
{ text: 'No coding-role Agent jobs are created here.', fg: PALETTE.good },
|
|
477
|
-
);
|
|
478
|
-
} else if (category.id === 'finish') {
|
|
479
|
-
base.push(
|
|
480
|
-
{ text: 'Apply & close marks onboarding finished for this user.', fg: PALETTE.good },
|
|
481
|
-
{ text: 'Future normal launches start in the main conversation.', fg: PALETTE.info },
|
|
482
|
-
{ text: 'Use /agent, /setup, or /onboarding to reopen this workspace later.', fg: PALETTE.muted },
|
|
483
|
-
);
|
|
484
|
-
}
|
|
485
|
-
if (snapshot.warnings.length > 0) {
|
|
486
|
-
base.push({ text: `Warnings: ${snapshot.warnings.map((warning) => compactText(warning, 60)).join('; ')}`, fg: PALETTE.warn });
|
|
487
|
-
}
|
|
488
|
-
return base;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
function editorContextLines(editor: AgentWorkspaceLocalEditor): ContextLine[] {
|
|
110
|
+
function editorContextLines(editor: AgentWorkspaceLocalEditor, snapshot: AgentWorkspaceRuntimeSnapshot | null): ContextLine[] {
|
|
492
111
|
const selected = editor.fields[editor.selectedFieldIndex];
|
|
493
112
|
const lines: ContextLine[] = [
|
|
494
113
|
{ text: editor.title, fg: PALETTE.title, bold: true },
|
|
@@ -501,6 +120,30 @@ function editorContextLines(editor: AgentWorkspaceLocalEditor): ContextLine[] {
|
|
|
501
120
|
{ text: compactText(selected.hint), fg: PALETTE.muted },
|
|
502
121
|
);
|
|
503
122
|
}
|
|
123
|
+
lines.push(...reviewerReadinessContextLines(editor, snapshot));
|
|
124
|
+
if (editor.kind === 'model-compare-handoff-diff') {
|
|
125
|
+
const left = editor.fields.find((field) => field.id === 'leftArtifactId')?.value.trim();
|
|
126
|
+
const right = editor.fields.find((field) => field.id === 'rightArtifactId')?.value.trim();
|
|
127
|
+
lines.push(
|
|
128
|
+
{ text: 'Split view: compare left and right reviewer handoff artifacts without changing model routing.', fg: PALETTE.good },
|
|
129
|
+
{ text: 'Section jumps: all, metadata, policy, related, comparison.', fg: PALETTE.info },
|
|
130
|
+
left && right
|
|
131
|
+
? { text: `Current diff: ${left} -> ${right}.`, fg: PALETTE.good }
|
|
132
|
+
: { text: 'No complete handoff pair selected; submitting lists recent saved handoffs.', fg: PALETTE.info },
|
|
133
|
+
);
|
|
134
|
+
if (snapshot?.recentReviewerHandoffArtifacts.length) {
|
|
135
|
+
const choices = snapshot.recentReviewerHandoffArtifacts
|
|
136
|
+
.slice(0, 4)
|
|
137
|
+
.map((artifact) => `${artifact.id} (${artifact.sourceKind}; related ${artifact.relatedArtifactCount})`)
|
|
138
|
+
.join(', ');
|
|
139
|
+
lines.push({ text: `Recent choices: ${choices}.`, fg: PALETTE.muted });
|
|
140
|
+
}
|
|
141
|
+
} else if (editor.kind === 'document-reviewer-readiness') {
|
|
142
|
+
lines.push(
|
|
143
|
+
{ text: 'Preflight checks: comments, suggestions, source artifacts, comparison reveal, route decisions, handoff evidence.', fg: PALETTE.info },
|
|
144
|
+
{ text: 'Use before export, handoff archive, or applying a comparison winner.', fg: PALETTE.good },
|
|
145
|
+
);
|
|
146
|
+
}
|
|
504
147
|
return lines;
|
|
505
148
|
}
|
|
506
149
|
|
|
@@ -518,25 +161,26 @@ function buildContextRows(workspace: AgentWorkspace, category: AgentWorkspaceCat
|
|
|
518
161
|
},
|
|
519
162
|
{ text: 'Enter opens; Esc clears.', fg: PALETTE.muted },
|
|
520
163
|
] satisfies ContextLine[] : []),
|
|
521
|
-
...(workspace.localEditor ? editorContextLines(workspace.localEditor) : []),
|
|
164
|
+
...(workspace.localEditor ? editorContextLines(workspace.localEditor, workspace.runtimeSnapshot) : []),
|
|
522
165
|
];
|
|
523
166
|
|
|
524
167
|
const selectedActionLines: ContextLine[] = action
|
|
525
168
|
? [
|
|
526
169
|
{ text: `Selected: ${action.label}`, fg: PALETTE.title, bold: true },
|
|
527
|
-
actionMetaLine(action),
|
|
170
|
+
actionMetaLine(workspace, category, action),
|
|
528
171
|
]
|
|
529
172
|
: [];
|
|
530
173
|
const snapshotContextLines = snapshotLines(workspace, category, workspace.runtimeSnapshot);
|
|
531
174
|
lines.push(...selectedActionLines, ...snapshotContextLines);
|
|
532
175
|
|
|
176
|
+
const onboarding = isOnboardingCategory(category);
|
|
533
177
|
if (workspace.lastActionResult) {
|
|
534
178
|
lines.push(
|
|
535
|
-
{ text: 'Action Result', fg: PALETTE.title, bold: true },
|
|
179
|
+
{ text: onboarding ? 'Result' : 'Action Result', fg: PALETTE.title, bold: true },
|
|
536
180
|
{ text: workspace.lastActionResult.title, fg: actionResultColor(workspace.lastActionResult), bold: true },
|
|
537
181
|
{ text: compactText(workspace.lastActionResult.detail), fg: PALETTE.text },
|
|
538
182
|
);
|
|
539
|
-
if (workspace.lastActionResult.command) {
|
|
183
|
+
if (!onboarding && workspace.lastActionResult.command) {
|
|
540
184
|
lines.push({ text: `Command: ${workspace.lastActionResult.command}`, fg: PALETTE.muted });
|
|
541
185
|
}
|
|
542
186
|
}
|
|
@@ -602,6 +246,8 @@ function buildEditorFieldRows(editor: AgentWorkspaceLocalEditor, index: number,
|
|
|
602
246
|
|
|
603
247
|
function buildActionRows(workspace: AgentWorkspace, width: number, height: number): WorkspaceRow[] {
|
|
604
248
|
if (workspace.localEditor) return buildEditorRows(workspace.localEditor, width, height);
|
|
249
|
+
const category = workspace.selectedActionCategory;
|
|
250
|
+
const onboarding = isOnboardingCategory(category);
|
|
605
251
|
const rows: WorkspaceRow[] = [];
|
|
606
252
|
const labelWidth = Math.min(34, Math.max(18, Math.floor(width * 0.38)));
|
|
607
253
|
const commandWidth = Math.max(10, width - labelWidth - 6);
|
|
@@ -613,7 +259,7 @@ function buildActionRows(workspace: AgentWorkspace, width: number, height: numbe
|
|
|
613
259
|
});
|
|
614
260
|
}
|
|
615
261
|
rows.push({
|
|
616
|
-
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)}`,
|
|
617
263
|
fg: PALETTE.muted,
|
|
618
264
|
bold: true,
|
|
619
265
|
});
|
|
@@ -627,10 +273,11 @@ function buildActionRows(workspace: AgentWorkspace, width: number, height: numbe
|
|
|
627
273
|
const action = actions[index]!;
|
|
628
274
|
const selected = index === workspace.selectedActionIndex;
|
|
629
275
|
const searchResult = workspace.actionSearchActive ? workspace.actionSearchResults[index] : null;
|
|
276
|
+
const actionCategory = searchResult?.category ?? category;
|
|
630
277
|
const label = searchResult ? `${searchResult.category.label} / ${action.label}` : action.label;
|
|
631
278
|
const marker = selected ? GLYPHS.navigation.selected : ' ';
|
|
632
279
|
rows.push({
|
|
633
|
-
text: `${marker} ${padDisplay(label, labelWidth)} ${padDisplay(
|
|
280
|
+
text: `${marker} ${padDisplay(label, labelWidth)} ${padDisplay(actionChange(workspace, actionCategory, action), commandWidth)}`,
|
|
634
281
|
selected: selected && workspace.focusPane === 'actions',
|
|
635
282
|
fg: action.safety === 'blocked' ? PALETTE.warn : selected ? PALETTE.text : PALETTE.info,
|
|
636
283
|
bold: selected,
|
|
@@ -642,11 +289,11 @@ function buildActionRows(workspace: AgentWorkspace, width: number, height: numbe
|
|
|
642
289
|
rows.push({ text: `Status: ${workspace.status}`, fg: PALETTE.muted });
|
|
643
290
|
if (workspace.lastActionResult) {
|
|
644
291
|
rows.push({ text: '' });
|
|
645
|
-
rows.push({ text:
|
|
292
|
+
rows.push({ text: `${onboarding ? 'Result' : 'Action Result'}: ${workspace.lastActionResult.title}`, fg: actionResultColor(workspace.lastActionResult), bold: true });
|
|
646
293
|
for (const line of wrapText(workspace.lastActionResult.detail, Math.max(1, width - 2))) {
|
|
647
294
|
rows.push({ text: ` ${line}`, fg: PALETTE.text });
|
|
648
295
|
}
|
|
649
|
-
if (workspace.lastActionResult.command) {
|
|
296
|
+
if (!onboarding && workspace.lastActionResult.command) {
|
|
650
297
|
rows.push({ text: ` Command: ${workspace.lastActionResult.command}`, fg: PALETTE.muted });
|
|
651
298
|
}
|
|
652
299
|
}
|
|
@@ -85,6 +85,18 @@ export const CATEGORY_LABELS: Record<(typeof SETTINGS_CATEGORIES)[number], strin
|
|
|
85
85
|
helper: 'Helper',
|
|
86
86
|
tts: 'TTS',
|
|
87
87
|
automation: 'Automation',
|
|
88
|
+
service: 'Service',
|
|
89
|
+
controlPlane: 'Control Plane',
|
|
90
|
+
httpListener: 'HTTP Listener',
|
|
91
|
+
web: 'Web',
|
|
92
|
+
watchers: 'Watchers',
|
|
93
|
+
network: 'Network',
|
|
94
|
+
orchestration: 'Orchestration',
|
|
95
|
+
runtime: 'Runtime',
|
|
96
|
+
sandbox: 'Sandbox',
|
|
97
|
+
batch: 'Batch',
|
|
98
|
+
cloudflare: 'Cloudflare',
|
|
99
|
+
wrfc: 'WRFC',
|
|
88
100
|
telemetry: 'Telemetry',
|
|
89
101
|
cache: 'Cache',
|
|
90
102
|
mcp: 'MCP',
|
|
@@ -34,6 +34,18 @@ const CATEGORY_INFO: Record<SettingsCategory, string> = {
|
|
|
34
34
|
helper: 'Helper model defaults used by helper subsystems when they do not use the main chat route.',
|
|
35
35
|
tts: 'Text-to-speech provider, voice, and optional spoken-turn LLM overrides.',
|
|
36
36
|
automation: 'Scheduled and automated run settings, concurrency, timeout, catch-up, cooldown, and retention behavior.',
|
|
37
|
+
service: 'GoodVibes daemon service posture and restart/autostart preferences.',
|
|
38
|
+
controlPlane: 'Control-plane endpoint, stream, remote access, and TLS settings used by daemon-backed operator routes.',
|
|
39
|
+
httpListener: 'HTTP listener binding, trust proxy, and TLS settings for inbound companion/channel routes.',
|
|
40
|
+
web: 'Web companion surface settings including host, port, public URL, and static asset path.',
|
|
41
|
+
watchers: 'Polling watcher and heartbeat behavior for runtime recovery and periodic checks.',
|
|
42
|
+
network: 'Outbound TLS and remote fetch network policy.',
|
|
43
|
+
orchestration: 'Visible agent orchestration limits such as recursion and active-agent caps.',
|
|
44
|
+
runtime: 'Runtime service limits and event bus settings.',
|
|
45
|
+
sandbox: 'Isolation settings for REPL, MCP, and VM-backed sessions.',
|
|
46
|
+
batch: 'Batch queue backend, limits, and provider batching behavior.',
|
|
47
|
+
cloudflare: 'Cloudflare worker, tunnel, queue, storage, and token-reference settings.',
|
|
48
|
+
wrfc: 'WRFC review/fix chain scoring, fix attempts, and commit preferences.',
|
|
37
49
|
telemetry: 'Telemetry payload policy.',
|
|
38
50
|
cache: 'Provider and model cache behavior, TTL, and hit-rate monitoring.',
|
|
39
51
|
mcp: 'MCP server trust and scope review. Trust changes can expose local files, tools, databases, browsers, or remote automation depending on the server.',
|