@pellux/goodvibes-agent 0.1.116 → 1.0.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 +48 -661
- package/README.md +64 -57
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +199180 -192185
- package/docs/README.md +15 -8
- package/docs/channels-remote-and-api.md +50 -0
- package/docs/connected-host.md +59 -0
- package/docs/getting-started.md +61 -50
- package/docs/knowledge-artifacts-and-multimodal.md +91 -0
- package/docs/project-planning.md +79 -0
- package/docs/providers-and-routing.md +46 -0
- package/docs/release-and-publishing.md +48 -11
- package/docs/tools-and-commands.md +123 -0
- package/docs/voice-and-live-tts.md +51 -0
- package/package.json +3 -6
- package/src/agent/behavior-discovery-summary.ts +1 -3
- package/src/agent/channel-delivery.ts +201 -0
- package/src/agent/media-generation.ts +159 -0
- package/src/agent/memory-prompt.ts +0 -1
- package/src/agent/note-registry.ts +329 -0
- package/src/agent/operator-actions.ts +343 -0
- package/src/agent/persona-discovery.ts +1 -3
- package/src/agent/persona-registry.ts +19 -16
- package/src/agent/record-labels.ts +107 -0
- package/src/agent/reminder-schedule-format.ts +33 -24
- package/src/agent/reminder-schedule.ts +27 -26
- package/src/agent/routine-registry.ts +54 -14
- package/src/agent/routine-schedule-args.ts +2 -1
- package/src/agent/routine-schedule-format.ts +77 -53
- package/src/agent/routine-schedule-promotion.ts +35 -33
- package/src/agent/routine-schedule-receipts.ts +29 -27
- package/src/agent/runtime-profile-starters.ts +5 -5
- package/src/agent/runtime-profile.ts +91 -12
- package/src/agent/skill-registry.ts +210 -32
- package/src/cli/agent-knowledge-args.ts +5 -1
- package/src/cli/agent-knowledge-command.ts +40 -34
- package/src/cli/agent-knowledge-format.ts +80 -67
- package/src/cli/agent-knowledge-methods.ts +1 -1
- package/src/cli/agent-knowledge-runtime.ts +32 -26
- package/src/cli/bundle-command.ts +14 -9
- package/src/cli/config-overrides.ts +37 -36
- package/src/cli/entrypoint.ts +16 -7
- package/src/cli/external-runtime.ts +10 -4
- package/src/cli/help.ts +54 -29
- package/src/cli/local-library-command.ts +203 -83
- package/src/cli/management-commands.ts +105 -68
- package/src/cli/management.ts +55 -74
- package/src/cli/memory-command.ts +66 -32
- package/src/cli/parser.ts +37 -3
- package/src/cli/profiles-command.ts +166 -31
- package/src/cli/provider-auth-routes.ts +2 -1
- package/src/cli/routines-command.ts +176 -40
- package/src/cli/service-posture.ts +16 -16
- package/src/cli/status.ts +56 -135
- package/src/core/conversation-message-snapshot.ts +131 -0
- package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
- package/src/input/agent-workspace-access-command-editors.ts +170 -0
- package/src/input/agent-workspace-activation.ts +35 -8
- package/src/input/agent-workspace-basic-command-editor-submission.ts +351 -94
- package/src/input/agent-workspace-basic-command-editors.ts +502 -9
- package/src/input/agent-workspace-categories.ts +423 -51
- package/src/input/agent-workspace-channel-command-editor-submission.ts +83 -0
- package/src/input/agent-workspace-channel-command-editors.ts +65 -0
- package/src/input/agent-workspace-channels.ts +35 -2
- package/src/input/agent-workspace-command-editor.ts +41 -3
- package/src/input/agent-workspace-config-reader.ts +16 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
- package/src/input/agent-workspace-editors.ts +166 -1
- package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
- package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
- package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
- package/src/input/agent-workspace-learned-behavior.ts +67 -0
- package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
- package/src/input/agent-workspace-library-command-editors.ts +35 -0
- package/src/input/agent-workspace-local-operations.ts +218 -0
- package/src/input/agent-workspace-local-selection.ts +75 -0
- package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
- package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
- package/src/input/agent-workspace-media-command-editors.ts +27 -0
- package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
- package/src/input/agent-workspace-memory-command-editors.ts +180 -0
- package/src/input/agent-workspace-memory-editor.ts +2 -2
- package/src/input/agent-workspace-navigation.ts +81 -0
- package/src/input/agent-workspace-notify-editor-submission.ts +121 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +208 -0
- package/src/input/agent-workspace-operations-command-editors.ts +196 -0
- package/src/input/agent-workspace-panel-route.ts +43 -0
- package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
- package/src/input/agent-workspace-provider-command-editors.ts +93 -0
- package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
- package/src/input/agent-workspace-requirements.ts +11 -0
- package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
- package/src/input/agent-workspace-search.ts +169 -0
- package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
- package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
- package/src/input/agent-workspace-session-command-editors.ts +249 -0
- package/src/input/agent-workspace-setup.ts +37 -16
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
- package/src/input/agent-workspace-snapshot.ts +162 -21
- package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
- package/src/input/agent-workspace-task-command-editors.ts +47 -0
- package/src/input/agent-workspace-token.ts +18 -2
- package/src/input/agent-workspace-types.ts +212 -4
- package/src/input/agent-workspace-voice-media.ts +4 -7
- package/src/input/agent-workspace-web-research-editor.ts +104 -0
- package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
- package/src/input/agent-workspace.ts +178 -240
- package/src/input/command-registry.ts +5 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +126 -37
- package/src/input/commands/agent-skills-runtime.ts +149 -72
- package/src/input/commands/agent-workspace-runtime.ts +23 -6
- package/src/input/commands/brief-runtime.ts +55 -25
- package/src/input/commands/channels-runtime.ts +147 -33
- package/src/input/commands/compat-runtime.ts +32 -0
- package/src/input/commands/delegation-runtime.ts +29 -23
- package/src/input/commands/experience-runtime.ts +6 -4
- package/src/input/commands/guidance-runtime.ts +4 -4
- package/src/input/commands/health-runtime.ts +149 -126
- package/src/input/commands/knowledge.ts +82 -60
- package/src/input/commands/local-provider-runtime.ts +43 -21
- package/src/input/commands/local-runtime.ts +138 -16
- package/src/input/commands/local-setup-review.ts +10 -20
- package/src/input/commands/mcp-runtime.ts +63 -46
- package/src/input/commands/notify-runtime.ts +38 -9
- package/src/input/commands/operator-actions-runtime.ts +138 -0
- package/src/input/commands/operator-runtime.ts +6 -76
- package/src/input/commands/personas-runtime.ts +46 -31
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +35 -98
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/provider-accounts-runtime.ts +60 -39
- package/src/input/commands/qrcode-runtime.ts +50 -9
- package/src/input/commands/recall-bundle.ts +11 -11
- package/src/input/commands/recall-capture.ts +13 -11
- package/src/input/commands/recall-query.ts +29 -21
- package/src/input/commands/recall-review.ts +2 -1
- package/src/input/commands/routines-runtime.ts +99 -45
- package/src/input/commands/runtime-services.ts +1 -14
- package/src/input/commands/schedule-runtime.ts +33 -20
- package/src/input/commands/security-runtime.ts +6 -11
- package/src/input/commands/session-content.ts +80 -78
- package/src/input/commands/session-workflow.ts +134 -104
- package/src/input/commands/session.ts +3 -174
- package/src/input/commands/shell-core.ts +38 -17
- package/src/input/commands/subscription-runtime.ts +54 -185
- package/src/input/commands/support-bundle-runtime.ts +53 -0
- package/src/input/commands/tasks-runtime.ts +21 -21
- package/src/input/commands/work-plan-runtime.ts +33 -8
- package/src/input/commands.ts +6 -2
- package/src/input/feed-context-factory.ts +2 -2
- package/src/input/file-picker.ts +3 -2
- package/src/input/handler-command-route.ts +4 -7
- package/src/input/handler-content-actions.ts +89 -26
- package/src/input/handler-feed-routes.ts +19 -12
- package/src/input/handler-feed.ts +6 -5
- package/src/input/handler-interactions.ts +9 -36
- package/src/input/handler-modal-stack.ts +3 -3
- package/src/input/handler-onboarding.ts +52 -91
- package/src/input/handler-shortcuts.ts +16 -7
- package/src/input/handler.ts +50 -23
- package/src/input/input-history.ts +5 -6
- package/src/input/keybindings.ts +27 -16
- package/src/input/mcp-workspace.ts +90 -26
- package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +62 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +223 -55
- package/src/input/onboarding/onboarding-wizard-steps.ts +59 -35
- package/src/input/onboarding/onboarding-wizard-types.ts +4 -1
- package/src/input/onboarding/onboarding-wizard.ts +87 -2
- package/src/input/profile-picker-modal.ts +31 -12
- package/src/input/session-picker-modal.ts +21 -4
- package/src/input/settings-modal-agent-policy.ts +6 -6
- package/src/input/settings-modal-behavior.ts +0 -3
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal-types.ts +2 -13
- package/src/input/settings-modal.ts +20 -66
- package/src/input/submission-intent.ts +0 -1
- package/src/input/submission-router.ts +3 -3
- package/src/main.ts +18 -10
- package/src/panels/approval-panel.ts +8 -8
- package/src/panels/automation-control-panel.ts +4 -4
- package/src/panels/base-panel.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +3 -12
- package/src/panels/builtin/session.ts +32 -24
- package/src/panels/builtin/shared.ts +7 -7
- package/src/panels/cost-tracker-panel.ts +1 -1
- package/src/panels/docs-panel.ts +5 -3
- package/src/panels/index.ts +0 -1
- package/src/panels/knowledge-panel.ts +6 -5
- package/src/panels/memory-panel.ts +7 -6
- package/src/panels/panel-list-panel.ts +36 -80
- package/src/panels/project-planning-panel.ts +19 -12
- package/src/panels/provider-account-snapshot.ts +51 -25
- package/src/panels/provider-accounts-panel.ts +33 -18
- package/src/panels/provider-health-domains.ts +48 -7
- package/src/panels/provider-health-panel.ts +5 -4
- package/src/panels/qr-panel.ts +44 -20
- package/src/panels/schedule-panel.ts +9 -17
- package/src/panels/security-panel.ts +8 -8
- package/src/panels/session-browser-panel.ts +10 -10
- package/src/panels/subscription-panel.ts +6 -6
- package/src/panels/system-messages-panel.ts +3 -3
- package/src/panels/tasks-panel.ts +21 -14
- package/src/panels/tool-inspector-panel.ts +19 -12
- package/src/panels/work-plan-panel.ts +5 -5
- package/src/planning/project-planning-coordinator.ts +3 -3
- package/src/provider-auth-route-display.ts +9 -0
- package/src/renderer/agent-workspace-style.ts +34 -0
- package/src/renderer/agent-workspace.ts +254 -57
- package/src/renderer/autocomplete-overlay.ts +25 -6
- package/src/renderer/block-actions.ts +1 -3
- package/src/renderer/bookmark-modal.ts +19 -4
- package/src/renderer/buffer.ts +4 -2
- package/src/renderer/context-inspector.ts +50 -13
- package/src/renderer/diff.ts +1 -1
- package/src/renderer/file-picker-overlay.ts +19 -6
- package/src/renderer/help-overlay.ts +112 -34
- package/src/renderer/history-search-overlay.ts +19 -4
- package/src/renderer/live-tail-modal.ts +27 -5
- package/src/renderer/mcp-workspace.ts +176 -43
- package/src/renderer/model-picker-overlay.ts +58 -3
- package/src/renderer/model-workspace.ts +104 -22
- package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
- package/src/renderer/process-modal.ts +27 -6
- package/src/renderer/profile-picker-modal.ts +21 -5
- package/src/renderer/search-overlay.ts +25 -5
- package/src/renderer/selection-modal-overlay.ts +46 -14
- package/src/renderer/session-picker-modal.ts +18 -1
- package/src/renderer/settings-modal-helpers.ts +2 -40
- package/src/renderer/settings-modal.ts +88 -55
- package/src/renderer/system-message.ts +1 -1
- package/src/renderer/tool-call.ts +20 -11
- package/src/runtime/agent-runtime-events.ts +129 -0
- package/src/runtime/bootstrap-command-context.ts +7 -1
- package/src/runtime/bootstrap-command-parts.ts +11 -8
- package/src/runtime/bootstrap-core.ts +23 -65
- package/src/runtime/bootstrap-hook-bridge.ts +7 -18
- package/src/runtime/bootstrap-shell.ts +46 -8
- package/src/runtime/bootstrap.ts +36 -46
- package/src/runtime/connected-host-auth.ts +47 -0
- package/src/runtime/diagnostics/panels/index.ts +2 -2
- package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
- package/src/runtime/diagnostics/panels/policy.ts +7 -7
- package/src/runtime/index.ts +2 -5
- package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
- package/src/runtime/onboarding/apply.ts +288 -74
- package/src/runtime/onboarding/derivation.ts +10 -13
- package/src/runtime/onboarding/snapshot.ts +2 -17
- package/src/runtime/onboarding/types.ts +34 -20
- package/src/runtime/onboarding/verify.ts +105 -4
- package/src/runtime/operator-token-cleanup.ts +3 -3
- package/src/runtime/services.ts +95 -11
- package/src/runtime/store/selectors/index.ts +3 -3
- package/src/runtime/store/state.ts +1 -4
- package/src/runtime/surface-feature-flags.ts +41 -6
- package/src/runtime/ui-read-models.ts +3 -4
- package/src/runtime/ui-services.ts +6 -6
- package/src/shell/blocking-input.ts +2 -1
- package/src/shell/service-settings-sync.ts +7 -7
- package/src/shell/ui-openers.ts +17 -38
- package/src/tools/agent-analysis-registry-policy.ts +0 -1
- package/src/tools/agent-channel-send-tool.ts +133 -0
- package/src/tools/agent-context-policy.ts +1 -1
- package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
- package/src/tools/agent-knowledge-tool.ts +170 -0
- package/src/tools/agent-local-registry-tool.ts +279 -73
- package/src/tools/agent-media-generate-tool.ts +133 -0
- package/src/tools/agent-notify-tool.ts +143 -0
- package/src/tools/agent-operator-action-tool.ts +137 -0
- package/src/tools/agent-operator-briefing-tool.ts +217 -0
- package/src/tools/agent-reminder-schedule-tool.ts +237 -0
- package/src/tools/agent-tool-policy-guard.ts +13 -15
- package/src/tools/agent-work-plan-tool.ts +256 -0
- package/src/version.ts +1 -1
- package/docs/connected-services.md +0 -51
- package/src/cli/package-verification.ts +0 -274
- package/src/input/commands/policy-dispatch.ts +0 -339
- package/src/input/commands/policy.ts +0 -17
- package/src/panels/panel-picker.ts +0 -105
- package/src/panels/policy-panel.ts +0 -308
- package/src/renderer/panel-picker-overlay.ts +0 -202
package/src/main.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Compositor } from './renderer/compositor.ts';
|
|
|
4
4
|
import { type Line } from './types/grid.ts';
|
|
5
5
|
import { UIFactory } from './renderer/ui-factory.ts';
|
|
6
6
|
import { Orchestrator } from './core/orchestrator';
|
|
7
|
+
import { conversationMessagesAsSessionRecords } from './core/conversation-message-snapshot.ts';
|
|
7
8
|
import { InputHandler } from './input/handler.ts';
|
|
8
9
|
import { SelectionManager } from './input/selection.ts';
|
|
9
10
|
import type { ContentPart } from '@pellux/goodvibes-sdk/platform/providers';
|
|
@@ -11,7 +12,6 @@ import { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
|
11
12
|
import { registerAllTools } from '@pellux/goodvibes-sdk/platform/tools';
|
|
12
13
|
import { FileUndoManager } from '@pellux/goodvibes-sdk/platform/state';
|
|
13
14
|
import { PermissionManager } from '@pellux/goodvibes-sdk/platform/permissions';
|
|
14
|
-
import { AcpManager } from '@pellux/goodvibes-sdk/platform/acp';
|
|
15
15
|
import { PermissionPromptUI } from './permissions/prompt.ts';
|
|
16
16
|
import { CommandRegistry } from './input/command-registry.ts';
|
|
17
17
|
import type { CommandContext } from './input/command-registry.ts';
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
persistConversation,
|
|
40
40
|
writeRecoveryFile,
|
|
41
41
|
} from '@/runtime/index.ts';
|
|
42
|
+
import type { SessionSnapshot } from '@/runtime/index.ts';
|
|
42
43
|
import { handleBlockingShellInput, type PendingPermissionState } from './shell/blocking-input.ts';
|
|
43
44
|
import { wireShellUiOpeners } from './shell/ui-openers.ts';
|
|
44
45
|
import { deriveComposerState } from './core/composer-state.ts';
|
|
@@ -114,7 +115,6 @@ async function main() {
|
|
|
114
115
|
sessionLineageTracker: ctx.services.sessionLineageTracker,
|
|
115
116
|
idempotencyStore: ctx.services.idempotencyStore,
|
|
116
117
|
});
|
|
117
|
-
ctx.services.wrfcController.setPlanManager(ctx.services.planManager);
|
|
118
118
|
let activeConversationWidth = stdout.columns || 80;
|
|
119
119
|
conversation.setWidthProvider(() => activeConversationWidth);
|
|
120
120
|
{
|
|
@@ -138,6 +138,16 @@ async function main() {
|
|
|
138
138
|
openPanels: panelManager.getAllOpen().map((panel) => panel.id),
|
|
139
139
|
};
|
|
140
140
|
};
|
|
141
|
+
const buildCurrentSessionSnapshot = (): SessionSnapshot => {
|
|
142
|
+
const messages = conversation.getMessageSnapshot();
|
|
143
|
+
const persisted = buildPersistedSessionContext(messages, conversation.getTitleSource(), buildSessionContinuityHints());
|
|
144
|
+
return {
|
|
145
|
+
messages: conversationMessagesAsSessionRecords(messages),
|
|
146
|
+
timestamp: Date.now(),
|
|
147
|
+
title: conversation.title,
|
|
148
|
+
...persisted,
|
|
149
|
+
};
|
|
150
|
+
};
|
|
141
151
|
|
|
142
152
|
let pendingPermission: PendingPermissionState | null = null;
|
|
143
153
|
approvalBroker.subscribe((approval) => {
|
|
@@ -221,8 +231,8 @@ async function main() {
|
|
|
221
231
|
const exitApp = (): void => {
|
|
222
232
|
stopSpokenOutputForExit?.();
|
|
223
233
|
unsubs.forEach(fn => fn());
|
|
224
|
-
const snapshot =
|
|
225
|
-
ctx.shutdown(
|
|
234
|
+
const snapshot = buildCurrentSessionSnapshot();
|
|
235
|
+
ctx.shutdown(snapshot).catch((err) => {
|
|
226
236
|
logger.debug('ctx.shutdown error during exitApp (non-fatal)', { error: summarizeError(err) });
|
|
227
237
|
});
|
|
228
238
|
if (recoveryInterval !== null) { clearInterval(recoveryInterval); recoveryInterval = null; }
|
|
@@ -668,11 +678,10 @@ async function main() {
|
|
|
668
678
|
unsubs.push(uiServices.events.turns.on('TURN_COMPLETED', () => {
|
|
669
679
|
// Auto-save after every LLM turn so kills don't lose the session
|
|
670
680
|
try {
|
|
671
|
-
const snapshot =
|
|
672
|
-
const persisted = buildPersistedSessionContext(snapshot.messages, conversation.getTitleSource(), buildSessionContinuityHints());
|
|
681
|
+
const snapshot = buildCurrentSessionSnapshot();
|
|
673
682
|
persistConversation(
|
|
674
683
|
runtime.sessionId,
|
|
675
|
-
|
|
684
|
+
snapshot,
|
|
676
685
|
runtime.model,
|
|
677
686
|
runtime.provider,
|
|
678
687
|
conversation.title || '',
|
|
@@ -750,10 +759,9 @@ async function main() {
|
|
|
750
759
|
|
|
751
760
|
// --- Auto-save to recovery file every 60s ---
|
|
752
761
|
recoveryInterval = setInterval(() => {
|
|
753
|
-
const snapshot =
|
|
754
|
-
const persisted = buildPersistedSessionContext(snapshot.messages, conversation.getTitleSource(), buildSessionContinuityHints());
|
|
762
|
+
const snapshot = buildCurrentSessionSnapshot();
|
|
755
763
|
writeRecoveryFile(
|
|
756
|
-
|
|
764
|
+
snapshot,
|
|
757
765
|
runtime.sessionId,
|
|
758
766
|
conversation.title ?? '',
|
|
759
767
|
{ workingDirectory: workingDir, homeDirectory },
|
|
@@ -15,14 +15,14 @@ const C = {
|
|
|
15
15
|
} as const;
|
|
16
16
|
|
|
17
17
|
const APPROVAL_ROWS = [
|
|
18
|
-
['shell', 'why prompted: side effects, destructive ops, secret exposure, escalation', 'review via /
|
|
18
|
+
['shell', 'why prompted: side effects, destructive ops, secret exposure, escalation', 'review via /approval review shell'],
|
|
19
19
|
['file', 'why prompted: config mutation, notebook edits, secret-bearing paths', 'review via /approval review file'],
|
|
20
20
|
['network', 'why prompted: external hosts, fetch scope, egress policy', 'review via /approval review network'],
|
|
21
|
-
['delegate', 'why prompted:
|
|
22
|
-
['mcp', 'why prompted: trust escalation, host scope, path scope, coherence mismatch', 'review via /
|
|
23
|
-
['remote', 'why prompted:
|
|
24
|
-
['hook', 'why prompted: deny/mutate authority, blocking behavior,
|
|
25
|
-
['plugin', 'why prompted: install/update lifecycle, provenance, capability grants', 'review via /
|
|
21
|
+
['delegate', 'why prompted: explicit TUI build handoff, write scope, result ownership', 'review via /approval review delegate'],
|
|
22
|
+
['mcp', 'why prompted: trust escalation, host scope, path scope, coherence mismatch', 'review via /approval review mcp'],
|
|
23
|
+
['remote', 'why prompted: build-host trust, remote write scope, artifact requirements', 'review via /approval review remote'],
|
|
24
|
+
['hook', 'why prompted: deny/mutate authority, blocking behavior, execution provenance', 'review via /approval review hook'],
|
|
25
|
+
['plugin', 'why prompted: install/update lifecycle, provenance, capability grants', 'review via /approval review plugin'],
|
|
26
26
|
] as const;
|
|
27
27
|
|
|
28
28
|
type ApprovalRow = (typeof APPROVAL_ROWS)[number];
|
|
@@ -123,8 +123,8 @@ export class ApprovalPanel extends ScrollableListPanel<ApprovalRow> {
|
|
|
123
123
|
buildPanelLine(width, [[' Approval posture', C.label]]),
|
|
124
124
|
buildKeyValueLine(width, [
|
|
125
125
|
{ label: 'why prompted', value: 'risk summary', valueColor: C.value },
|
|
126
|
-
{ label: 'what-if', value: '/
|
|
127
|
-
{ label: 'operator', value: '/
|
|
126
|
+
{ label: 'what-if', value: '/security review', valueColor: C.info },
|
|
127
|
+
{ label: 'operator', value: '/approval + /security', valueColor: C.good },
|
|
128
128
|
], C),
|
|
129
129
|
buildPanelLine(width, [
|
|
130
130
|
[' \u2713 ', C.good],
|
|
@@ -102,9 +102,9 @@ export class AutomationControlPanel extends ScrollableListPanel<AutomationRun> {
|
|
|
102
102
|
sections: [{
|
|
103
103
|
lines: buildEmptyState(
|
|
104
104
|
width,
|
|
105
|
-
'
|
|
106
|
-
'This
|
|
107
|
-
[{ command: '/schedule list', summary: 'review automation
|
|
105
|
+
' Connected-host automation state is unavailable.',
|
|
106
|
+
'This operator view is read-only. Use /schedule list for compact transcript output; automation stays unchanged.',
|
|
107
|
+
[{ command: '/schedule list', summary: 'review automation without starting hidden work' }],
|
|
108
108
|
C,
|
|
109
109
|
),
|
|
110
110
|
}],
|
|
@@ -182,7 +182,7 @@ export class AutomationControlPanel extends ScrollableListPanel<AutomationRun> {
|
|
|
182
182
|
);
|
|
183
183
|
if (selectedRun.error) {
|
|
184
184
|
footerLines.push(buildPanelLine(width, [
|
|
185
|
-
[' Error
|
|
185
|
+
[' Error ', C.label],
|
|
186
186
|
[truncateDisplay(selectedRun.error, Math.max(0, width - 10)), C.error],
|
|
187
187
|
]));
|
|
188
188
|
}
|
package/src/panels/base-panel.ts
CHANGED
|
@@ -34,7 +34,7 @@ export abstract class BasePanel implements Panel {
|
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Clear a specific timer and remove it from the registry.
|
|
37
|
-
* Safe to call with an
|
|
37
|
+
* Safe to call with an unregistered or already-cleared id.
|
|
38
38
|
*/
|
|
39
39
|
protected clearTimer(id: ReturnType<typeof setTimeout> | ReturnType<typeof setInterval>): void {
|
|
40
40
|
clearInterval(id as ReturnType<typeof setInterval>);
|
|
@@ -80,7 +80,7 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
|
|
|
80
80
|
name: 'Schedule',
|
|
81
81
|
icon: 'Z',
|
|
82
82
|
category: 'agent',
|
|
83
|
-
description: 'Read-only schedule posture from connected GoodVibes
|
|
83
|
+
description: 'Read-only schedule posture from the connected GoodVibes host; Agent-local schedule mutation is blocked',
|
|
84
84
|
factory: () => new SchedulePanel(requireAutomationManager(deps)),
|
|
85
85
|
});
|
|
86
86
|
}
|
|
@@ -7,7 +7,6 @@ import { SecurityPanel } from '../security-panel.ts';
|
|
|
7
7
|
import { TasksPanel } from '../tasks-panel.ts';
|
|
8
8
|
import { ProviderStatsPanel } from '../provider-stats-panel.ts';
|
|
9
9
|
import { ProviderHealthPanel } from '../provider-health-panel.ts';
|
|
10
|
-
import { PolicyPanel } from '../policy-panel.ts';
|
|
11
10
|
import { createProviderAccountSnapshotQuery } from '../provider-account-snapshot.ts';
|
|
12
11
|
import {
|
|
13
12
|
createEnvironmentVariableQuery,
|
|
@@ -45,7 +44,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
45
44
|
name: 'Automation',
|
|
46
45
|
icon: 'M',
|
|
47
46
|
category: 'monitoring',
|
|
48
|
-
description: 'Read-only automation jobs, runs, deliveries, and failure posture from connected GoodVibes
|
|
47
|
+
description: 'Read-only automation jobs, runs, deliveries, and failure posture from the connected GoodVibes host',
|
|
49
48
|
factory: () => new AutomationControlPanel(ui.readModels.automation),
|
|
50
49
|
});
|
|
51
50
|
|
|
@@ -72,7 +71,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
72
71
|
name: 'Security',
|
|
73
72
|
icon: 'U',
|
|
74
73
|
category: 'monitoring',
|
|
75
|
-
description: 'Security review workspace for token
|
|
74
|
+
description: 'Security review workspace for token posture, policy posture, MCP quarantine, and incident pressure',
|
|
76
75
|
factory: () => new SecurityPanel(ui.readModels.security),
|
|
77
76
|
});
|
|
78
77
|
|
|
@@ -81,7 +80,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
81
80
|
name: 'Tasks',
|
|
82
81
|
icon: 'J',
|
|
83
82
|
category: 'monitoring',
|
|
84
|
-
description: 'Queued, running, blocked, failed, and completed task summaries from connected GoodVibes
|
|
83
|
+
description: 'Queued, running, blocked, failed, and completed task summaries from the connected GoodVibes host',
|
|
85
84
|
factory: () => new TasksPanel(ui.readModels.tasks),
|
|
86
85
|
});
|
|
87
86
|
|
|
@@ -119,12 +118,4 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
119
118
|
),
|
|
120
119
|
});
|
|
121
120
|
|
|
122
|
-
manager.registerType({
|
|
123
|
-
id: 'policy',
|
|
124
|
-
name: 'Policy',
|
|
125
|
-
icon: 'U',
|
|
126
|
-
category: 'monitoring',
|
|
127
|
-
description: 'Policy governance: active/candidate bundles, divergence gate, rollout history, and simulation evidence',
|
|
128
|
-
factory: () => new PolicyPanel(deps.policyRuntimeState),
|
|
129
|
-
});
|
|
130
121
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { networkInterfaces } from 'node:os';
|
|
2
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
3
|
import type { PanelManager } from '../panel-manager.ts';
|
|
4
4
|
import { SessionBrowserPanel } from '../session-browser-panel.ts';
|
|
5
5
|
import { QrPanel } from '../qr-panel.ts';
|
|
@@ -9,8 +9,6 @@ import { TokenBudgetPanel } from '../token-budget-panel.ts';
|
|
|
9
9
|
import type { ResolvedBuiltinPanelDeps } from './shared.ts';
|
|
10
10
|
import { requireUiServices } from './shared.ts';
|
|
11
11
|
import {
|
|
12
|
-
getOrCreateCompanionToken,
|
|
13
|
-
regenerateCompanionToken,
|
|
14
12
|
buildCompanionConnectionInfo,
|
|
15
13
|
} from '@pellux/goodvibes-sdk/platform/pairing';
|
|
16
14
|
import { copyToClipboard } from '../../utils/clipboard.ts';
|
|
@@ -42,37 +40,47 @@ function readBootstrapPassword(credentialPath: string): string | undefined {
|
|
|
42
40
|
return undefined;
|
|
43
41
|
}
|
|
44
42
|
|
|
43
|
+
function readOperatorToken(tokenPath: string): string | null {
|
|
44
|
+
if (!existsSync(tokenPath)) return null;
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(readFileSync(tokenPath, 'utf-8')) as unknown;
|
|
47
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return null;
|
|
48
|
+
const token = 'token' in parsed ? parsed.token : undefined;
|
|
49
|
+
return typeof token === 'string' && token.trim().length > 0 ? token : null;
|
|
50
|
+
} catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
|
|
46
56
|
manager.registerType({
|
|
47
57
|
id: 'qr-code',
|
|
48
58
|
name: 'QR Code',
|
|
49
59
|
icon: 'Q',
|
|
50
60
|
category: 'session',
|
|
51
|
-
description: 'QR code for companion app pairing
|
|
61
|
+
description: 'QR code for companion app pairing through the connected GoodVibes host',
|
|
52
62
|
factory: () => {
|
|
53
|
-
if (!deps.
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const daemonUrl = `http://${daemonHost}:${daemonPort}`;
|
|
63
|
+
if (!deps.connectedHostTokenDir) throw new Error('connected host token directory must be provided to the session panel factory via BuiltinPanelDeps');
|
|
64
|
+
const token = readOperatorToken(`${deps.connectedHostTokenDir}/operator-tokens.json`);
|
|
65
|
+
const connectedHostPort = deps.configManager.get('controlPlane.port');
|
|
66
|
+
const connectedHostName = String(process.env['GOODVIBES_AGENT_RUNTIME_HOST'] ?? process.env['GOODVIBES_DAEMON_HOST'] ?? getLocalNetworkIp());
|
|
67
|
+
const connectedHostUrl = `http://${connectedHostName}:${connectedHostPort}`;
|
|
59
68
|
const bootstrapPassword = readBootstrapPassword(deps.localUserAuthManager.getBootstrapCredentialPath());
|
|
60
|
-
const connectionInfo =
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
surface: GOODVIBES_AGENT_PAIRING_SURFACE,
|
|
65
|
-
});
|
|
66
|
-
const regenerate = (): typeof connectionInfo => {
|
|
67
|
-
const newRecord = regenerateCompanionToken({ daemonHomeDir });
|
|
68
|
-
return buildCompanionConnectionInfo({
|
|
69
|
-
daemonUrl,
|
|
70
|
-
token: newRecord.token,
|
|
69
|
+
const connectionInfo = token
|
|
70
|
+
? buildCompanionConnectionInfo({
|
|
71
|
+
daemonUrl: connectedHostUrl,
|
|
72
|
+
token,
|
|
71
73
|
password: bootstrapPassword,
|
|
72
74
|
surface: GOODVIBES_AGENT_PAIRING_SURFACE,
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
})
|
|
76
|
+
: {
|
|
77
|
+
url: connectedHostUrl,
|
|
78
|
+
token: '',
|
|
79
|
+
username: 'admin',
|
|
80
|
+
...(bootstrapPassword !== undefined ? { password: bootstrapPassword } : {}),
|
|
81
|
+
surface: GOODVIBES_AGENT_PAIRING_SURFACE,
|
|
82
|
+
};
|
|
83
|
+
return new QrPanel(connectionInfo, undefined, copyToClipboard);
|
|
76
84
|
},
|
|
77
85
|
});
|
|
78
86
|
|
|
@@ -80,15 +80,15 @@ export interface BuiltinPanelDeps {
|
|
|
80
80
|
tokenAuditor: ApiTokenAuditor;
|
|
81
81
|
/** Shared component-health monitor for rate-limited panels and diagnostics. */
|
|
82
82
|
componentHealthMonitor: ComponentHealthMonitor;
|
|
83
|
-
/**
|
|
83
|
+
/** Inert shell dependency in Agent; build worktree UX belongs to GoodVibes TUI delegation. */
|
|
84
84
|
worktreeRegistry: WorktreeRegistry;
|
|
85
|
-
/**
|
|
85
|
+
/** Isolation session registry used by MCP internals; Agent does not expose local execution-isolation command UX. */
|
|
86
86
|
sandboxSessionRegistry: SandboxSessionRegistry;
|
|
87
87
|
/**
|
|
88
|
-
* Resolved
|
|
89
|
-
* and passed explicitly so panel factories do not discover cwd/home implicitly.
|
|
88
|
+
* Resolved connected-host token directory (e.g. `~/.goodvibes/daemon`) — owned by the
|
|
89
|
+
* composition root and passed explicitly so panel factories do not discover cwd/home implicitly.
|
|
90
90
|
*/
|
|
91
|
-
|
|
91
|
+
connectedHostTokenDir?: string;
|
|
92
92
|
/** Session memory store for context and token budget panels. */
|
|
93
93
|
sessionMemoryStore?: SessionMemoryStore;
|
|
94
94
|
/** Execution plan manager for plan dashboard panels. */
|
|
@@ -103,7 +103,7 @@ export interface BuiltinPanelDeps {
|
|
|
103
103
|
workPlanStore?: import('../../work-plans/work-plan-store.ts').WorkPlanStore;
|
|
104
104
|
/** Shared system-messages panel instance attached from boot so low-priority chatter stays out of conversation. */
|
|
105
105
|
systemMessagesPanel?: import('../system-messages-panel.ts').SystemMessagesPanel;
|
|
106
|
-
/** Explicit UI-facing runtime services for
|
|
106
|
+
/** Explicit UI-facing runtime services for operator panels and modals. */
|
|
107
107
|
uiServices?: UiRuntimeServices;
|
|
108
108
|
/** Shared plugin manager observer for plugin and security panels. */
|
|
109
109
|
pluginManager?: PluginManagerObserver;
|
|
@@ -240,7 +240,7 @@ export function requireAutomationManager(deps: BuiltinPanelDeps): AutomationMana
|
|
|
240
240
|
|
|
241
241
|
export function requireUiServices(deps: BuiltinPanelDeps): UiRuntimeServices {
|
|
242
242
|
if (!deps.uiServices) {
|
|
243
|
-
throw new Error('UI runtime services must be wired at bootstrap for
|
|
243
|
+
throw new Error('UI runtime services must be wired at bootstrap for operator panels.');
|
|
244
244
|
}
|
|
245
245
|
return deps.uiServices;
|
|
246
246
|
}
|
|
@@ -198,7 +198,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
198
198
|
turnEvents.on('TURN_COMPLETED', () => this.onTurnComplete()),
|
|
199
199
|
);
|
|
200
200
|
|
|
201
|
-
// Track
|
|
201
|
+
// Track runtime worker events for cost attribution only.
|
|
202
202
|
this.unsubs.push(
|
|
203
203
|
agentEvents.on('AGENT_SPAWNING', (payload) => {
|
|
204
204
|
this.agents.set(payload.agentId, {
|
package/src/panels/docs-panel.ts
CHANGED
|
@@ -36,15 +36,17 @@ const C = {
|
|
|
36
36
|
// ---------------------------------------------------------------------------
|
|
37
37
|
const SHORTCUTS: Array<{ key: string; desc: string }> = [
|
|
38
38
|
{ key: 'Ctrl+C', desc: 'Cancel generation / exit (double)' },
|
|
39
|
-
{ key: 'Ctrl+P', desc: 'Open
|
|
39
|
+
{ key: 'Ctrl+P', desc: 'Open Agent operator workspace' },
|
|
40
40
|
{ key: 'Ctrl+F', desc: 'Search conversation' },
|
|
41
41
|
{ key: 'Ctrl+K', desc: 'Copy last response to clipboard' },
|
|
42
42
|
{ key: 'Ctrl+L', desc: 'Clear screen' },
|
|
43
43
|
{ key: 'Ctrl+Z', desc: 'Undo input' },
|
|
44
44
|
{ key: 'Alt+Enter', desc: 'Insert newline in prompt' },
|
|
45
45
|
{ key: 'PageUp/Down', desc: 'Scroll conversation' },
|
|
46
|
-
{ key: 'Alt+PgUp/Dn', desc: 'Scroll
|
|
47
|
-
{ key: 'Tab', desc: 'Path completion /
|
|
46
|
+
{ key: 'Alt+PgUp/Dn', desc: 'Scroll active workspace surface' },
|
|
47
|
+
{ key: 'Tab', desc: 'Path completion / workspace focus' },
|
|
48
|
+
{ key: '@path', desc: 'Attach bounded file/folder/URL context in composer' },
|
|
49
|
+
{ key: '!@path', desc: 'Inject raw file contents in composer' },
|
|
48
50
|
{ key: '/', desc: 'Start slash command' },
|
|
49
51
|
{ key: 'Enter', desc: 'Submit prompt' },
|
|
50
52
|
{ key: 'Esc', desc: 'Close overlay / cancel search' },
|
package/src/panels/index.ts
CHANGED
|
@@ -15,7 +15,6 @@ export { ToolInspectorPanel } from './tool-inspector-panel.ts';
|
|
|
15
15
|
export { ContextVisualizerPanel } from './context-visualizer-panel.ts';
|
|
16
16
|
export { registerBuiltinPanels } from './builtin-panels.ts';
|
|
17
17
|
export type { BuiltinPanelDeps } from './builtin-panels.ts';
|
|
18
|
-
export { PolicyPanel } from './policy-panel.ts';
|
|
19
18
|
export { TasksPanel } from './tasks-panel.ts';
|
|
20
19
|
export { SubscriptionPanel } from './subscription-panel.ts';
|
|
21
20
|
export { SecurityPanel } from './security-panel.ts';
|
|
@@ -3,6 +3,7 @@ import { ScrollableListPanel } from './scrollable-list-panel.ts';
|
|
|
3
3
|
import { type ConfirmState, handleConfirmInput, renderConfirmLines } from './confirm-state.ts';
|
|
4
4
|
import type { MemoryClass, MemoryRecord, MemoryRegistry, MemoryReviewState } from '@pellux/goodvibes-sdk/platform/state';
|
|
5
5
|
import type { KnowledgeStatus } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
6
|
+
import { formatAgentRecordReferences } from '../agent/record-labels.ts';
|
|
6
7
|
import {
|
|
7
8
|
buildBodyText,
|
|
8
9
|
buildGuidanceLine,
|
|
@@ -105,7 +106,7 @@ export class KnowledgePanel extends ScrollableListPanel<MemoryRecord> {
|
|
|
105
106
|
{ command: '/knowledge status', summary: 'inspect the isolated Agent Knowledge store' },
|
|
106
107
|
{ command: '/knowledge ingest-url <url> --yes', summary: 'ingest source-backed material into Agent Knowledge only' },
|
|
107
108
|
{ command: '/knowledge queue', summary: 'review Agent Knowledge issues' },
|
|
108
|
-
{ command: '/
|
|
109
|
+
{ command: '/memory add fact <summary>', summary: 'capture a local non-secret memory record when appropriate' },
|
|
109
110
|
];
|
|
110
111
|
}
|
|
111
112
|
|
|
@@ -233,7 +234,7 @@ export class KnowledgePanel extends ScrollableListPanel<MemoryRecord> {
|
|
|
233
234
|
buildPanelLine(width, [
|
|
234
235
|
[' route ', C.label],
|
|
235
236
|
['/api/goodvibes-agent/knowledge/*', C.info],
|
|
236
|
-
[' isolated: no default
|
|
237
|
+
[' isolated: no default knowledge or non-Agent fallback', C.dim],
|
|
237
238
|
]),
|
|
238
239
|
];
|
|
239
240
|
if (this.agentKnowledgeLoading && !this.agentKnowledgeStatus) {
|
|
@@ -283,7 +284,7 @@ export class KnowledgePanel extends ScrollableListPanel<MemoryRecord> {
|
|
|
283
284
|
|
|
284
285
|
if (this.records.length === 0) this.refresh();
|
|
285
286
|
|
|
286
|
-
const intro = 'Isolated Agent Knowledge plus local non-secret memory review. This surface never falls back to default
|
|
287
|
+
const intro = 'Isolated Agent Knowledge plus local non-secret memory review. This surface never falls back to default knowledge or non-Agent knowledge segments.';
|
|
287
288
|
const records = this.registry.search({ limit: 200 });
|
|
288
289
|
const agentKnowledgeHeader = this.buildAgentKnowledgeHeader(width);
|
|
289
290
|
|
|
@@ -335,7 +336,7 @@ export class KnowledgePanel extends ScrollableListPanel<MemoryRecord> {
|
|
|
335
336
|
[' project ', C.label], [String(byScope.get('project') ?? 0), C.value],
|
|
336
337
|
[' team ', C.label], [String(byScope.get('team') ?? 0), C.good],
|
|
337
338
|
]),
|
|
338
|
-
buildGuidanceLine(width, '/
|
|
339
|
+
buildGuidanceLine(width, '/memory review', 'work the stale and contradicted queue from the command workspace', C),
|
|
339
340
|
];
|
|
340
341
|
|
|
341
342
|
const recentSummaryLines: Line[] = [];
|
|
@@ -376,7 +377,7 @@ export class KnowledgePanel extends ScrollableListPanel<MemoryRecord> {
|
|
|
376
377
|
if (selectedRecord.provenance.length) {
|
|
377
378
|
selectedLines.push(...buildBodyText(
|
|
378
379
|
width,
|
|
379
|
-
`
|
|
380
|
+
`Origin: ${formatAgentRecordReferences(selectedRecord.provenance)}`,
|
|
380
381
|
C,
|
|
381
382
|
C.dim,
|
|
382
383
|
));
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { Line } from '../types/grid.ts';
|
|
8
8
|
import type { MemoryRegistry } from '@pellux/goodvibes-sdk/platform/state';
|
|
9
9
|
import type { MemoryRecord, MemoryClass } from '@pellux/goodvibes-sdk/platform/state';
|
|
10
|
+
import { formatAgentRecordReferences } from '../agent/record-labels.ts';
|
|
10
11
|
import { SearchableListPanel } from './scrollable-list-panel.ts';
|
|
11
12
|
import {
|
|
12
13
|
buildBodyText,
|
|
@@ -125,12 +126,12 @@ export class MemoryPanel extends SearchableListPanel<MemoryRecord> {
|
|
|
125
126
|
protected override getEmptyStateMessage() {
|
|
126
127
|
return this.searchQuery
|
|
127
128
|
? ` No records matching "${this.searchQuery}"`
|
|
128
|
-
: ' No memory records. Use /
|
|
129
|
+
: ' No memory records. Use /memory add <class> <summary> to create one.';
|
|
129
130
|
}
|
|
130
131
|
protected override getEmptyStateActions() {
|
|
131
132
|
return [
|
|
132
|
-
{ command: '/
|
|
133
|
-
{ command: '/
|
|
133
|
+
{ command: '/memory add fact <summary>', summary: 'capture a durable fact directly' },
|
|
134
|
+
{ command: '/memory capture incident latest', summary: 'promote the latest incident into memory' },
|
|
134
135
|
];
|
|
135
136
|
}
|
|
136
137
|
|
|
@@ -170,7 +171,7 @@ export class MemoryPanel extends SearchableListPanel<MemoryRecord> {
|
|
|
170
171
|
|
|
171
172
|
render(width: number, height: number): Line[] {
|
|
172
173
|
this.clampSelection();
|
|
173
|
-
const intro = 'Durable project memory across decisions, constraints, incidents, patterns, risks, runbooks, and related
|
|
174
|
+
const intro = 'Durable project memory across decisions, constraints, incidents, patterns, risks, runbooks, and related origin links.';
|
|
174
175
|
|
|
175
176
|
const records = this.getItems();
|
|
176
177
|
const byClass = new Map<MemoryClass, number>();
|
|
@@ -189,7 +190,7 @@ export class MemoryPanel extends SearchableListPanel<MemoryRecord> {
|
|
|
189
190
|
{ label: 'runbooks', value: String(byClass.get('runbook') ?? 0), valueColor: C.runbook },
|
|
190
191
|
], C),
|
|
191
192
|
filterLine,
|
|
192
|
-
buildGuidanceLine(width, '/
|
|
193
|
+
buildGuidanceLine(width, '/memory review', 'review durable memory and queue posture from the command workspace', C),
|
|
193
194
|
];
|
|
194
195
|
|
|
195
196
|
const selected = records[this.selectedIndex];
|
|
@@ -206,7 +207,7 @@ export class MemoryPanel extends SearchableListPanel<MemoryRecord> {
|
|
|
206
207
|
if (selected.provenance.length) {
|
|
207
208
|
selectedLines.push(...buildBodyText(
|
|
208
209
|
width,
|
|
209
|
-
`
|
|
210
|
+
`Origin: ${formatAgentRecordReferences(selected.provenance)}`,
|
|
210
211
|
C,
|
|
211
212
|
C.dim,
|
|
212
213
|
));
|