@pellux/goodvibes-agent 0.1.117 → 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 +13 -4
- package/README.md +35 -14
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +176073 -170980
- package/docs/README.md +11 -5
- package/docs/channels-remote-and-api.md +50 -0
- package/docs/connected-host.md +3 -3
- package/docs/getting-started.md +29 -15
- 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 +44 -9
- package/docs/tools-and-commands.md +123 -0
- package/docs/voice-and-live-tts.md +51 -0
- package/package.json +2 -5
- 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-registry.ts +15 -14
- package/src/agent/record-labels.ts +107 -0
- package/src/agent/reminder-schedule-format.ts +33 -24
- package/src/agent/reminder-schedule.ts +26 -25
- package/src/agent/routine-registry.ts +13 -12
- 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 +34 -32
- package/src/agent/routine-schedule-receipts.ts +28 -26
- package/src/agent/runtime-profile-starters.ts +2 -2
- package/src/agent/runtime-profile.ts +18 -17
- package/src/agent/skill-registry.ts +25 -24
- package/src/cli/agent-knowledge-args.ts +5 -1
- package/src/cli/agent-knowledge-command.ts +39 -33
- 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 +13 -8
- package/src/cli/config-overrides.ts +37 -36
- package/src/cli/external-runtime.ts +10 -4
- package/src/cli/help.ts +29 -11
- package/src/cli/local-library-command.ts +134 -68
- package/src/cli/management-commands.ts +98 -62
- package/src/cli/management.ts +52 -26
- package/src/cli/memory-command.ts +66 -32
- package/src/cli/parser.ts +37 -24
- package/src/cli/profiles-command.ts +52 -35
- package/src/cli/provider-auth-routes.ts +2 -1
- package/src/cli/routines-command.ts +44 -36
- package/src/cli/service-posture.ts +6 -6
- package/src/cli/status.ts +46 -121
- package/src/core/conversation-message-snapshot.ts +131 -0
- package/src/input/agent-workspace-activation.ts +33 -7
- package/src/input/agent-workspace-basic-command-editor-submission.ts +7 -3
- package/src/input/agent-workspace-basic-command-editors.ts +30 -10
- package/src/input/agent-workspace-categories.ts +276 -64
- package/src/input/agent-workspace-channel-command-editor-submission.ts +34 -0
- package/src/input/agent-workspace-channel-command-editors.ts +23 -5
- package/src/input/agent-workspace-channels.ts +35 -2
- package/src/input/agent-workspace-command-editor.ts +18 -2
- package/src/input/agent-workspace-config-reader.ts +16 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +1 -1
- package/src/input/agent-workspace-editors.ts +140 -2
- package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
- package/src/input/agent-workspace-learned-behavior.ts +2 -2
- package/src/input/agent-workspace-library-command-editor-submission.ts +1 -1
- package/src/input/agent-workspace-library-command-editors.ts +2 -2
- 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-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-editors.ts +1 -1
- package/src/input/agent-workspace-memory-editor.ts +2 -2
- package/src/input/agent-workspace-navigation.ts +38 -2
- package/src/input/agent-workspace-notify-editor-submission.ts +16 -2
- package/src/input/agent-workspace-operations-command-editor-submission.ts +63 -1
- package/src/input/agent-workspace-operations-command-editors.ts +80 -3
- package/src/input/agent-workspace-panel-route.ts +43 -0
- package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
- 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-setup.ts +22 -11
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +6 -6
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +10 -10
- package/src/input/agent-workspace-snapshot.ts +112 -13
- package/src/input/agent-workspace-task-command-editors.ts +4 -4
- package/src/input/agent-workspace-token.ts +18 -2
- package/src/input/agent-workspace-types.ts +92 -4
- package/src/input/agent-workspace-voice-media.ts +3 -6
- package/src/input/agent-workspace-web-research-editor.ts +104 -0
- package/src/input/agent-workspace.ts +136 -208
- package/src/input/command-registry.ts +4 -1
- package/src/input/commands/agent-runtime-profile-runtime.ts +45 -41
- package/src/input/commands/agent-skills-runtime.ts +83 -70
- package/src/input/commands/agent-workspace-runtime.ts +23 -7
- package/src/input/commands/brief-runtime.ts +25 -24
- package/src/input/commands/channels-runtime.ts +145 -31
- 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 +140 -115
- package/src/input/commands/knowledge.ts +57 -56
- package/src/input/commands/local-provider-runtime.ts +36 -18
- package/src/input/commands/local-runtime.ts +138 -16
- package/src/input/commands/local-setup-review.ts +7 -7
- package/src/input/commands/mcp-runtime.ts +56 -35
- 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 -17
- package/src/input/commands/personas-runtime.ts +45 -30
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +29 -29
- package/src/input/commands/provider-accounts-runtime.ts +60 -39
- package/src/input/commands/qrcode-runtime.ts +45 -6
- 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 +59 -43
- package/src/input/commands/schedule-runtime.ts +33 -20
- package/src/input/commands/security-runtime.ts +4 -4
- package/src/input/commands/session-content.ts +80 -78
- package/src/input/commands/session-workflow.ts +132 -93
- package/src/input/commands/session.ts +3 -174
- package/src/input/commands/shell-core.ts +32 -17
- package/src/input/commands/subscription-runtime.ts +53 -179
- package/src/input/commands/tasks-runtime.ts +20 -20
- package/src/input/commands/work-plan-runtime.ts +33 -8
- package/src/input/commands.ts +2 -2
- package/src/input/feed-context-factory.ts +2 -1
- 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 -1
- package/src/input/handler-feed-routes.ts +19 -12
- package/src/input/handler-feed.ts +6 -3
- package/src/input/handler-interactions.ts +7 -5
- package/src/input/handler-modal-stack.ts +3 -3
- package/src/input/handler-onboarding.ts +24 -80
- package/src/input/handler-shortcuts.ts +15 -4
- package/src/input/handler.ts +47 -17
- package/src/input/input-history.ts +5 -6
- package/src/input/keybindings.ts +22 -11
- package/src/input/onboarding/onboarding-wizard-apply.ts +13 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +147 -57
- package/src/input/onboarding/onboarding-wizard-steps.ts +46 -29
- package/src/input/onboarding/onboarding-wizard-types.ts +3 -1
- package/src/input/onboarding/onboarding-wizard.ts +68 -0
- package/src/input/profile-picker-modal.ts +31 -12
- package/src/input/session-picker-modal.ts +21 -4
- 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 +6 -52
- package/src/input/submission-intent.ts +0 -1
- package/src/input/submission-router.ts +3 -3
- package/src/main.ts +18 -8
- package/src/panels/approval-panel.ts +8 -8
- package/src/panels/automation-control-panel.ts +2 -2
- package/src/panels/base-panel.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +1 -10
- package/src/panels/builtin/session.ts +9 -9
- package/src/panels/builtin/shared.ts +2 -2
- 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 +18 -11
- 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 +45 -4
- package/src/panels/provider-health-panel.ts +5 -4
- package/src/panels/qr-panel.ts +1 -1
- 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 +3 -3
- package/src/panels/system-messages-panel.ts +1 -1
- package/src/panels/tasks-panel.ts +20 -13
- 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 +1 -1
- package/src/provider-auth-route-display.ts +9 -0
- package/src/renderer/agent-workspace-style.ts +34 -0
- package/src/renderer/agent-workspace.ts +228 -52
- package/src/renderer/autocomplete-overlay.ts +25 -6
- 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 +106 -33
- package/src/renderer/history-search-overlay.ts +19 -4
- package/src/renderer/live-tail-modal.ts +27 -5
- package/src/renderer/mcp-workspace.ts +164 -50
- package/src/renderer/model-picker-overlay.ts +58 -2
- package/src/renderer/model-workspace.ts +104 -20
- package/src/renderer/process-modal.ts +27 -6
- package/src/renderer/profile-picker-modal.ts +20 -4
- 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 +83 -50
- package/src/renderer/tool-call.ts +20 -11
- package/src/runtime/agent-runtime-events.ts +6 -6
- package/src/runtime/bootstrap-command-context.ts +7 -1
- package/src/runtime/bootstrap-command-parts.ts +9 -7
- package/src/runtime/bootstrap-core.ts +19 -1
- package/src/runtime/bootstrap-hook-bridge.ts +7 -18
- package/src/runtime/bootstrap-shell.ts +4 -4
- package/src/runtime/bootstrap.ts +31 -22
- package/src/runtime/connected-host-auth.ts +7 -2
- package/src/runtime/diagnostics/panels/index.ts +2 -2
- package/src/runtime/diagnostics/panels/policy.ts +7 -7
- package/src/runtime/index.ts +2 -1
- package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
- package/src/runtime/onboarding/apply.ts +80 -79
- package/src/runtime/onboarding/derivation.ts +5 -8
- package/src/runtime/onboarding/snapshot.ts +0 -15
- package/src/runtime/onboarding/types.ts +8 -19
- package/src/runtime/onboarding/verify.ts +32 -10
- package/src/runtime/operator-token-cleanup.ts +1 -1
- package/src/runtime/services.ts +91 -22
- 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/ui-openers.ts +3 -13
- 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 +269 -69
- 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 +8 -8
- package/src/tools/agent-work-plan-tool.ts +256 -0
- package/src/version.ts +1 -1
- package/src/input/commands/policy-dispatch.ts +0 -339
- package/src/input/commands/policy.ts +0 -13
- 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
|
@@ -23,8 +23,8 @@ export function routeSubmissionIntent(input: SubmissionRouterInput): SubmissionI
|
|
|
23
23
|
|
|
24
24
|
if (!trimmed) {
|
|
25
25
|
return {
|
|
26
|
-
kind:
|
|
27
|
-
label:
|
|
26
|
+
kind: 'empty',
|
|
27
|
+
label: 'prompt',
|
|
28
28
|
hasAttachments,
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -46,7 +46,7 @@ export function routeSubmissionIntent(input: SubmissionRouterInput): SubmissionI
|
|
|
46
46
|
return { kind: 'delegation', label: 'TUI delegation', commandName, hasAttachments };
|
|
47
47
|
}
|
|
48
48
|
if (PANEL_COMMANDS.has(commandName)) {
|
|
49
|
-
return { kind: '
|
|
49
|
+
return { kind: 'slash-command', label: 'Agent workspace', commandName, hasAttachments };
|
|
50
50
|
}
|
|
51
51
|
if (ORCHESTRATION_COMMANDS.has(commandName)) {
|
|
52
52
|
return { kind: 'orchestration', label: 'orchestration', commandName, hasAttachments };
|
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';
|
|
@@ -38,6 +39,7 @@ import {
|
|
|
38
39
|
persistConversation,
|
|
39
40
|
writeRecoveryFile,
|
|
40
41
|
} from '@/runtime/index.ts';
|
|
42
|
+
import type { SessionSnapshot } from '@/runtime/index.ts';
|
|
41
43
|
import { handleBlockingShellInput, type PendingPermissionState } from './shell/blocking-input.ts';
|
|
42
44
|
import { wireShellUiOpeners } from './shell/ui-openers.ts';
|
|
43
45
|
import { deriveComposerState } from './core/composer-state.ts';
|
|
@@ -136,6 +138,16 @@ async function main() {
|
|
|
136
138
|
openPanels: panelManager.getAllOpen().map((panel) => panel.id),
|
|
137
139
|
};
|
|
138
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
|
+
};
|
|
139
151
|
|
|
140
152
|
let pendingPermission: PendingPermissionState | null = null;
|
|
141
153
|
approvalBroker.subscribe((approval) => {
|
|
@@ -219,8 +231,8 @@ async function main() {
|
|
|
219
231
|
const exitApp = (): void => {
|
|
220
232
|
stopSpokenOutputForExit?.();
|
|
221
233
|
unsubs.forEach(fn => fn());
|
|
222
|
-
const snapshot =
|
|
223
|
-
ctx.shutdown(
|
|
234
|
+
const snapshot = buildCurrentSessionSnapshot();
|
|
235
|
+
ctx.shutdown(snapshot).catch((err) => {
|
|
224
236
|
logger.debug('ctx.shutdown error during exitApp (non-fatal)', { error: summarizeError(err) });
|
|
225
237
|
});
|
|
226
238
|
if (recoveryInterval !== null) { clearInterval(recoveryInterval); recoveryInterval = null; }
|
|
@@ -666,11 +678,10 @@ async function main() {
|
|
|
666
678
|
unsubs.push(uiServices.events.turns.on('TURN_COMPLETED', () => {
|
|
667
679
|
// Auto-save after every LLM turn so kills don't lose the session
|
|
668
680
|
try {
|
|
669
|
-
const snapshot =
|
|
670
|
-
const persisted = buildPersistedSessionContext(snapshot.messages, conversation.getTitleSource(), buildSessionContinuityHints());
|
|
681
|
+
const snapshot = buildCurrentSessionSnapshot();
|
|
671
682
|
persistConversation(
|
|
672
683
|
runtime.sessionId,
|
|
673
|
-
|
|
684
|
+
snapshot,
|
|
674
685
|
runtime.model,
|
|
675
686
|
runtime.provider,
|
|
676
687
|
conversation.title || '',
|
|
@@ -748,10 +759,9 @@ async function main() {
|
|
|
748
759
|
|
|
749
760
|
// --- Auto-save to recovery file every 60s ---
|
|
750
761
|
recoveryInterval = setInterval(() => {
|
|
751
|
-
const snapshot =
|
|
752
|
-
const persisted = buildPersistedSessionContext(snapshot.messages, conversation.getTitleSource(), buildSessionContinuityHints());
|
|
762
|
+
const snapshot = buildCurrentSessionSnapshot();
|
|
753
763
|
writeRecoveryFile(
|
|
754
|
-
|
|
764
|
+
snapshot,
|
|
755
765
|
runtime.sessionId,
|
|
756
766
|
conversation.title ?? '',
|
|
757
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],
|
|
@@ -103,7 +103,7 @@ export class AutomationControlPanel extends ScrollableListPanel<AutomationRun> {
|
|
|
103
103
|
lines: buildEmptyState(
|
|
104
104
|
width,
|
|
105
105
|
' Connected-host automation state is unavailable.',
|
|
106
|
-
'
|
|
106
|
+
'This operator view is read-only. Use /schedule list for compact transcript output; automation stays unchanged.',
|
|
107
107
|
[{ command: '/schedule list', summary: 'review automation without starting hidden work' }],
|
|
108
108
|
C,
|
|
109
109
|
),
|
|
@@ -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 the connected GoodVibes host; local
|
|
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,
|
|
@@ -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
|
|
|
@@ -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
|
}
|
|
@@ -45,7 +45,7 @@ function readOperatorToken(tokenPath: string): string | null {
|
|
|
45
45
|
try {
|
|
46
46
|
const parsed = JSON.parse(readFileSync(tokenPath, 'utf-8')) as unknown;
|
|
47
47
|
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return null;
|
|
48
|
-
const token =
|
|
48
|
+
const token = 'token' in parsed ? parsed.token : undefined;
|
|
49
49
|
return typeof token === 'string' && token.trim().length > 0 ? token : null;
|
|
50
50
|
} catch {
|
|
51
51
|
return null;
|
|
@@ -58,23 +58,23 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
|
|
|
58
58
|
name: 'QR Code',
|
|
59
59
|
icon: 'Q',
|
|
60
60
|
category: 'session',
|
|
61
|
-
description: 'QR code for companion app pairing
|
|
61
|
+
description: 'QR code for companion app pairing through the connected GoodVibes host',
|
|
62
62
|
factory: () => {
|
|
63
|
-
if (!deps.
|
|
64
|
-
const token = readOperatorToken(`${deps.
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const
|
|
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}`;
|
|
68
68
|
const bootstrapPassword = readBootstrapPassword(deps.localUserAuthManager.getBootstrapCredentialPath());
|
|
69
69
|
const connectionInfo = token
|
|
70
70
|
? buildCompanionConnectionInfo({
|
|
71
|
-
daemonUrl,
|
|
71
|
+
daemonUrl: connectedHostUrl,
|
|
72
72
|
token,
|
|
73
73
|
password: bootstrapPassword,
|
|
74
74
|
surface: GOODVIBES_AGENT_PAIRING_SURFACE,
|
|
75
75
|
})
|
|
76
76
|
: {
|
|
77
|
-
url:
|
|
77
|
+
url: connectedHostUrl,
|
|
78
78
|
token: '',
|
|
79
79
|
username: 'admin',
|
|
80
80
|
...(bootstrapPassword !== undefined ? { password: bootstrapPassword } : {}),
|
|
@@ -80,7 +80,7 @@ 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;
|
|
@@ -88,7 +88,7 @@ export interface BuiltinPanelDeps {
|
|
|
88
88
|
* Resolved connected-host token directory (e.g. `~/.goodvibes/daemon`) — owned by the
|
|
89
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. */
|
|
@@ -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
|
));
|