@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
|
@@ -26,12 +26,21 @@ import {
|
|
|
26
26
|
} from '@/runtime/index.ts';
|
|
27
27
|
import { loadBootstrapSystemPrompt, syncConfiguredServices } from '@/runtime/index.ts';
|
|
28
28
|
import { registerBootstrapHookBridge } from '@/runtime/index.ts';
|
|
29
|
-
import { registerBootstrapRuntimeEvents } from '@/runtime/index.ts';
|
|
30
29
|
import { createRuntimeServices, type RuntimeServices } from './services.ts';
|
|
31
30
|
import { createUiRuntimeServices, type UiRuntimeServices } from './ui-services.ts';
|
|
32
31
|
import { installAgentToolPolicyGuard } from '../tools/agent-tool-policy-guard.ts';
|
|
32
|
+
import { registerAgentChannelSendTool } from '../tools/agent-channel-send-tool.ts';
|
|
33
|
+
import { registerAgentKnowledgeIngestTool } from '../tools/agent-knowledge-ingest-tool.ts';
|
|
34
|
+
import { registerAgentKnowledgeTool } from '../tools/agent-knowledge-tool.ts';
|
|
33
35
|
import { registerAgentLocalRegistryTool } from '../tools/agent-local-registry-tool.ts';
|
|
36
|
+
import { registerAgentMediaGenerateTool } from '../tools/agent-media-generate-tool.ts';
|
|
37
|
+
import { registerAgentNotifyTool } from '../tools/agent-notify-tool.ts';
|
|
38
|
+
import { registerAgentOperatorActionTool } from '../tools/agent-operator-action-tool.ts';
|
|
39
|
+
import { registerAgentOperatorBriefingTool } from '../tools/agent-operator-briefing-tool.ts';
|
|
40
|
+
import { registerAgentReminderScheduleTool } from '../tools/agent-reminder-schedule-tool.ts';
|
|
41
|
+
import { registerAgentWorkPlanTool } from '../tools/agent-work-plan-tool.ts';
|
|
34
42
|
import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
|
|
43
|
+
import { registerAgentRuntimeEvents } from './agent-runtime-events.ts';
|
|
35
44
|
|
|
36
45
|
export interface BootstrapCoreState {
|
|
37
46
|
readonly userSessionId: string;
|
|
@@ -139,7 +148,7 @@ export async function initializeBootstrapCore(
|
|
|
139
148
|
metadata: {
|
|
140
149
|
product: 'goodvibes-agent',
|
|
141
150
|
surfaceRoot: GOODVIBES_AGENT_SURFACE_ROOT,
|
|
142
|
-
clientKindNote: 'SDK
|
|
151
|
+
clientKindNote: 'SDK compatibility client kind; GoodVibes Agent remains an interactive operator TUI.',
|
|
143
152
|
},
|
|
144
153
|
}, 'bootstrap.control-plane');
|
|
145
154
|
|
|
@@ -211,7 +220,6 @@ export async function initializeBootstrapCore(
|
|
|
211
220
|
agentManager: services.agentManager,
|
|
212
221
|
agentMessageBus: services.agentMessageBus,
|
|
213
222
|
archetypeLoader: services.archetypeLoader,
|
|
214
|
-
wrfcController: services.wrfcController,
|
|
215
223
|
webSearchService: services.webSearchService,
|
|
216
224
|
channelRegistry: services.channelPlugins,
|
|
217
225
|
remoteRunnerRegistry: services.remoteRunnerRegistry,
|
|
@@ -228,7 +236,16 @@ export async function initializeBootstrapCore(
|
|
|
228
236
|
overflowHandler: services.overflowHandler,
|
|
229
237
|
changeTracker: services.sessionChangeTracker,
|
|
230
238
|
});
|
|
239
|
+
registerAgentKnowledgeIngestTool(toolRegistry, services.shellPaths, configManager);
|
|
240
|
+
registerAgentChannelSendTool(toolRegistry, services.channelDeliveryRouter);
|
|
241
|
+
registerAgentKnowledgeTool(toolRegistry, services.shellPaths, configManager);
|
|
231
242
|
registerAgentLocalRegistryTool(toolRegistry, services.shellPaths, services.memoryRegistry);
|
|
243
|
+
registerAgentMediaGenerateTool(toolRegistry, services.mediaProviders, services.artifactStore);
|
|
244
|
+
registerAgentNotifyTool(toolRegistry, configManager, services.webhookNotifier);
|
|
245
|
+
registerAgentOperatorActionTool(toolRegistry, services.shellPaths, configManager);
|
|
246
|
+
registerAgentOperatorBriefingTool(toolRegistry, services.shellPaths, configManager);
|
|
247
|
+
registerAgentReminderScheduleTool(toolRegistry, services.shellPaths, configManager);
|
|
248
|
+
registerAgentWorkPlanTool(toolRegistry, services.workPlanStore);
|
|
232
249
|
installAgentToolPolicyGuard(toolRegistry, {
|
|
233
250
|
getLastUserMessage: () => conversation.getLastUserMessage(),
|
|
234
251
|
});
|
|
@@ -314,7 +331,7 @@ export async function initializeBootstrapCore(
|
|
|
314
331
|
const runtimeSessionIdRef = { value: userSessionId };
|
|
315
332
|
const systemMessageRouterRef: { value: SystemMessageRouter | null } = { value: null };
|
|
316
333
|
const conversationFollowUpRef: { value: ((item: ConversationFollowUpItem) => void) | null } = { value: null };
|
|
317
|
-
const { unsubs: runtimeUnsubs, agentStatusIntervalRef } =
|
|
334
|
+
const { unsubs: runtimeUnsubs, agentStatusIntervalRef } = registerAgentRuntimeEvents({
|
|
318
335
|
runtimeBus,
|
|
319
336
|
domainDispatch,
|
|
320
337
|
getSystemMessageRouter: () => systemMessageRouterRef.value,
|
|
@@ -322,69 +339,10 @@ export async function initializeBootstrapCore(
|
|
|
322
339
|
requestRender,
|
|
323
340
|
configManager,
|
|
324
341
|
agentManager: services.agentManager,
|
|
325
|
-
wrfcController: services.wrfcController,
|
|
326
342
|
});
|
|
327
343
|
|
|
328
|
-
//
|
|
329
|
-
//
|
|
330
|
-
// core WORKFLOW_REVIEW_COMPLETED / WORKFLOW_CHAIN_CREATED messages.
|
|
331
|
-
// The SDK does not surface constraint-specific system messages; the TUI layer
|
|
332
|
-
// adds them here so operators can observe constraint enumeration and violations
|
|
333
|
-
// in the SystemMessagesPanel and main conversation.
|
|
334
|
-
runtimeUnsubs.push(
|
|
335
|
-
runtimeBus.on<Extract<import('@/runtime/index.ts').WorkflowEvent, { type: 'WORKFLOW_CONSTRAINTS_ENUMERATED' }>>(
|
|
336
|
-
'WORKFLOW_CONSTRAINTS_ENUMERATED',
|
|
337
|
-
({ payload }) => {
|
|
338
|
-
const router = systemMessageRouterRef.value;
|
|
339
|
-
if (!router) return;
|
|
340
|
-
const count = payload.constraints.length;
|
|
341
|
-
if (count > 0) {
|
|
342
|
-
router.wrfc(
|
|
343
|
-
`[WRFC] Engineer enumerated ${count} constraint${count !== 1 ? 's' : ''} for chain ${payload.chainId.slice(0, 12)}`,
|
|
344
|
-
'low',
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
requestRender();
|
|
348
|
-
},
|
|
349
|
-
),
|
|
350
|
-
);
|
|
351
|
-
runtimeUnsubs.push(
|
|
352
|
-
runtimeBus.on<Extract<import('@/runtime/index.ts').WorkflowEvent, { type: 'WORKFLOW_FIX_ATTEMPTED' }>>(
|
|
353
|
-
'WORKFLOW_FIX_ATTEMPTED',
|
|
354
|
-
({ payload }) => {
|
|
355
|
-
const router = systemMessageRouterRef.value;
|
|
356
|
-
if (!router) return;
|
|
357
|
-
const targetIds = payload.targetConstraintIds;
|
|
358
|
-
if (targetIds && targetIds.length > 0) {
|
|
359
|
-
router.wrfc(
|
|
360
|
-
`[WRFC] Fix #${payload.attempt} targeting ${targetIds.length} constraint${targetIds.length !== 1 ? 's' : ''} on chain ${payload.chainId.slice(0, 12)}`,
|
|
361
|
-
'low',
|
|
362
|
-
);
|
|
363
|
-
requestRender();
|
|
364
|
-
}
|
|
365
|
-
},
|
|
366
|
-
),
|
|
367
|
-
);
|
|
368
|
-
runtimeUnsubs.push(
|
|
369
|
-
runtimeBus.on<Extract<import('@/runtime/index.ts').WorkflowEvent, { type: 'WORKFLOW_REVIEW_COMPLETED' }>>(
|
|
370
|
-
'WORKFLOW_REVIEW_COMPLETED',
|
|
371
|
-
({ payload }) => {
|
|
372
|
-
const router = systemMessageRouterRef.value;
|
|
373
|
-
if (!router) return;
|
|
374
|
-
const unsatisfied = payload.unsatisfiedConstraintIds;
|
|
375
|
-
if (!payload.passed && unsatisfied && unsatisfied.length > 0) {
|
|
376
|
-
router.wrfc(
|
|
377
|
-
`[WRFC] ✗ Chain ${payload.chainId.slice(0, 12)}: ${unsatisfied.length} constraint violation${unsatisfied.length !== 1 ? 's' : ''} forced failure`,
|
|
378
|
-
'high',
|
|
379
|
-
);
|
|
380
|
-
requestRender();
|
|
381
|
-
}
|
|
382
|
-
},
|
|
383
|
-
),
|
|
384
|
-
);
|
|
385
|
-
|
|
386
|
-
// Subscribe to companion main-chat messages received from the daemon's HTTP layer.
|
|
387
|
-
// The daemon emits COMPANION_MESSAGE_RECEIVED on the runtime bus when a companion
|
|
344
|
+
// Subscribe to companion main-chat messages received from the connected host's HTTP layer.
|
|
345
|
+
// The connected host emits COMPANION_MESSAGE_RECEIVED on the runtime bus when a companion
|
|
388
346
|
// POST /api/sessions/:id/messages with kind='message' arrives.
|
|
389
347
|
//
|
|
390
348
|
// bootstrap.ts patches orchestratorHandleUserInputRef.value after the Orchestrator
|
|
@@ -10,9 +10,9 @@ import type { ConfigManager } from '@pellux/goodvibes-sdk/platform/config';
|
|
|
10
10
|
import { formatReturnContextForDisplay, getReturnContextMode, maybeAssistReturnContextSummary } from '@/runtime/index.ts';
|
|
11
11
|
import type { SharedSessionBroker } from '@pellux/goodvibes-sdk/platform/control-plane';
|
|
12
12
|
import type { SessionManager } from '@pellux/goodvibes-sdk/platform/sessions';
|
|
13
|
-
import type { PanelManager } from '../panels/panel-manager.ts';
|
|
14
13
|
import type { ProviderRegistry } from '@pellux/goodvibes-sdk/platform/providers';
|
|
15
14
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
15
|
+
import { readConversationMessageSnapshots } from '../core/conversation-message-snapshot.ts';
|
|
16
16
|
|
|
17
17
|
export interface ResumeSessionOptions {
|
|
18
18
|
readonly runtimeBus: RuntimeEventBus;
|
|
@@ -24,7 +24,6 @@ export interface ResumeSessionOptions {
|
|
|
24
24
|
readonly writeLastSessionPointer: (sessionId: string) => void;
|
|
25
25
|
readonly hookDispatcher: HookDispatcher;
|
|
26
26
|
readonly sessionManager: SessionManager;
|
|
27
|
-
readonly panelManager: PanelManager;
|
|
28
27
|
readonly configManager: Pick<ConfigManager, 'get' | 'getCategory'>;
|
|
29
28
|
readonly providerRegistry: Pick<ProviderRegistry, 'get' | 'getCurrentModel' | 'getForModel' | 'require'>;
|
|
30
29
|
}
|
|
@@ -42,7 +41,7 @@ export function createResumeSessionHandler(options: ResumeSessionOptions): (sess
|
|
|
42
41
|
turnCount: messages.length,
|
|
43
42
|
});
|
|
44
43
|
options.conversation.fromJSON({
|
|
45
|
-
messages: messages
|
|
44
|
+
messages: readConversationMessageSnapshots(messages),
|
|
46
45
|
title: meta.title,
|
|
47
46
|
titleSource: meta.titleSource,
|
|
48
47
|
});
|
|
@@ -53,28 +52,18 @@ export function createResumeSessionHandler(options: ResumeSessionOptions): (sess
|
|
|
53
52
|
options.writeLastSessionPointer(sessionId);
|
|
54
53
|
void options.sharedSessionBroker.reopenSession(sessionId).catch((err) => { logger.debug('session broker reopen session failed', { err }); });
|
|
55
54
|
options.conversation.log(`Resumed session: ${sessionId}`, { fg: '135' });
|
|
56
|
-
const
|
|
57
|
-
if (meta.returnContext?.openPanels?.length) {
|
|
58
|
-
for (const panelId of meta.returnContext.openPanels.slice(0, 4)) {
|
|
59
|
-
try {
|
|
60
|
-
options.panelManager.open(panelId);
|
|
61
|
-
reopenedPanels.push(panelId);
|
|
62
|
-
} catch {
|
|
63
|
-
// Ignore unavailable panels during restore.
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (reopenedPanels.length > 0) options.panelManager.show();
|
|
67
|
-
}
|
|
55
|
+
const ignoredPanels = meta.returnContext?.openPanels?.slice(0, 4) ?? [];
|
|
68
56
|
const returnContextMode = getReturnContextMode(options.configManager);
|
|
69
57
|
if (returnContextMode !== 'off' && meta.returnContext) {
|
|
70
58
|
for (const line of formatReturnContextForDisplay(meta.returnContext)) {
|
|
59
|
+
if (line.startsWith('Open panels:')) continue;
|
|
71
60
|
options.conversation.log(`Resume: ${line}`, { fg: '244' });
|
|
72
61
|
}
|
|
73
|
-
if (
|
|
74
|
-
options.conversation.log(`Resume:
|
|
62
|
+
if (ignoredPanels.length > 0) {
|
|
63
|
+
options.conversation.log(`Resume: Saved panel state ignored: ${ignoredPanels.join(', ')}. Open the Agent workspace for current operator controls.`, { fg: '244' });
|
|
75
64
|
}
|
|
76
65
|
if ((meta.returnContext.remoteRunners?.length ?? 0) > 0) {
|
|
77
|
-
options.conversation.log('Resume: Remote
|
|
66
|
+
options.conversation.log('Resume: Remote build-host recovery belongs outside Agent; delegate explicit build/fix/review recovery from Agent.', { fg: '244' });
|
|
78
67
|
}
|
|
79
68
|
if (returnContextMode === 'assisted') {
|
|
80
69
|
const helperModel = new HelperModel({
|
|
@@ -62,6 +62,43 @@ export interface BootstrapShellOptions {
|
|
|
62
62
|
readonly completeModelSelectionSideEffect?: () => void;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
type PlanningAnswerSubmit = (answer: string) => void;
|
|
66
|
+
|
|
67
|
+
export interface PlanningAnswerSubmitBridgeOptions {
|
|
68
|
+
readonly getSubmitInput: () => PlanningAnswerSubmit | undefined;
|
|
69
|
+
readonly addSystemMessage: (message: string) => void;
|
|
70
|
+
readonly requestRender: () => void;
|
|
71
|
+
readonly defer?: (callback: () => void) => void;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function submitPlanningAnswerWithShellFallback(
|
|
75
|
+
answer: string,
|
|
76
|
+
options: PlanningAnswerSubmitBridgeOptions,
|
|
77
|
+
): void {
|
|
78
|
+
const submit = options.getSubmitInput();
|
|
79
|
+
if (submit) {
|
|
80
|
+
submit(answer);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const defer = options.defer ?? ((callback) => {
|
|
85
|
+
setTimeout(callback, 0);
|
|
86
|
+
});
|
|
87
|
+
defer(() => {
|
|
88
|
+
const deferredSubmit = options.getSubmitInput();
|
|
89
|
+
if (deferredSubmit) {
|
|
90
|
+
deferredSubmit(answer);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
options.addSystemMessage([
|
|
95
|
+
'[Planning] Could not submit the selected answer because the prompt bridge is not ready.',
|
|
96
|
+
`Paste this answer into the prompt to continue planning: ${answer}`,
|
|
97
|
+
].join('\n'));
|
|
98
|
+
options.requestRender();
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
65
102
|
export function createBootstrapShell(options: BootstrapShellOptions): BootstrapShellState {
|
|
66
103
|
const {
|
|
67
104
|
configManager,
|
|
@@ -96,7 +133,6 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
|
|
|
96
133
|
writeLastSessionPointer,
|
|
97
134
|
hookDispatcher: services.hookDispatcher,
|
|
98
135
|
sessionManager: services.sessionManager,
|
|
99
|
-
panelManager: services.panelManager,
|
|
100
136
|
configManager,
|
|
101
137
|
providerRegistry: services.providerRegistry,
|
|
102
138
|
});
|
|
@@ -113,10 +149,11 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
|
|
|
113
149
|
resumeSession,
|
|
114
150
|
requestRender,
|
|
115
151
|
submitPlanningAnswer: (answer) => {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
152
|
+
submitPlanningAnswerWithShellFallback(answer, {
|
|
153
|
+
getSubmitInput: () => commandContextRef?.submitInput,
|
|
154
|
+
addSystemMessage: (message) => conversation.addSystemMessage(message),
|
|
155
|
+
requestRender,
|
|
156
|
+
});
|
|
120
157
|
},
|
|
121
158
|
dismissPlanning: () => {
|
|
122
159
|
services.panelManager.close('project-planning');
|
|
@@ -142,7 +179,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
|
|
|
142
179
|
hookActivityTracker: services.hookActivityTracker,
|
|
143
180
|
hookWorkbench: services.hookWorkbench,
|
|
144
181
|
mcpRegistry: services.mcpRegistry,
|
|
145
|
-
|
|
182
|
+
connectedHostTokenDir: join(services.homeDirectory, '.goodvibes', 'daemon'),
|
|
146
183
|
});
|
|
147
184
|
services.panelManager.prewarmRegistered();
|
|
148
185
|
|
|
@@ -160,9 +197,8 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
|
|
|
160
197
|
|
|
161
198
|
const commandRegistry = new CommandRegistry();
|
|
162
199
|
registerBuiltinCommands(commandRegistry);
|
|
163
|
-
type RuntimeFoundationInput = Parameters<typeof createRuntimeFoundationClients>[0];
|
|
164
200
|
const foundationClients = createRuntimeFoundationClients({
|
|
165
|
-
runtimeServices: services
|
|
201
|
+
runtimeServices: services,
|
|
166
202
|
tasksReadModel: uiServices.readModels.tasks,
|
|
167
203
|
taskManager,
|
|
168
204
|
opsControlPlane,
|
|
@@ -198,6 +234,8 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
|
|
|
198
234
|
voiceProviderRegistry: services.voiceProviders,
|
|
199
235
|
voiceService: services.voiceService,
|
|
200
236
|
mediaProviderRegistry: services.mediaProviders,
|
|
237
|
+
artifactStore: services.artifactStore,
|
|
238
|
+
channelDeliveryRouter: services.channelDeliveryRouter,
|
|
201
239
|
forensicsRegistry,
|
|
202
240
|
policyRuntimeState,
|
|
203
241
|
readModels: uiServices.readModels,
|
package/src/runtime/bootstrap.ts
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
* - lifecycle.ts: save/shutdown helpers
|
|
11
11
|
*/
|
|
12
12
|
import { Orchestrator, type OrchestratorUserInputOptions } from '../core/orchestrator.ts';
|
|
13
|
-
import { AcpManager } from '@pellux/goodvibes-sdk/platform/acp';
|
|
14
13
|
import { getTierPromptSupplement, getTierForContextWindow } from '@pellux/goodvibes-sdk/platform/providers';
|
|
15
14
|
import { logger } from '@pellux/goodvibes-sdk/platform/utils';
|
|
16
15
|
import type { PermissionRequestHandler } from '@pellux/goodvibes-sdk/platform/permissions';
|
|
@@ -23,7 +22,6 @@ import type { RuntimeContext, BootstrapOptions } from './context.ts';
|
|
|
23
22
|
import { shutdownRuntime, fireSessionStart, saveSession } from '@/runtime/index.ts';
|
|
24
23
|
import { createTaskManager } from '@/runtime/index.ts';
|
|
25
24
|
import { OpsControlPlane } from '@/runtime/index.ts';
|
|
26
|
-
import { AcpTaskAdapter } from '@/runtime/index.ts';
|
|
27
25
|
import type { SystemMessageRouter } from '../core/system-message-router.ts';
|
|
28
26
|
import { emitSessionReady, emitSessionStarted } from '@/runtime/index.ts';
|
|
29
27
|
import {
|
|
@@ -47,14 +45,23 @@ import { buildReviewedMemoryPrompt } from '../agent/memory-prompt.ts';
|
|
|
47
45
|
|
|
48
46
|
const GOODVIBES_AGENT_OPERATOR_POLICY = [
|
|
49
47
|
'## GoodVibes Agent Operator Policy',
|
|
50
|
-
'- Default to serial, proactive assistant work in the main conversation. Answer, inspect, summarize, remember useful non-secret facts, configure local
|
|
51
|
-
'- GoodVibes Agent connects to GoodVibes
|
|
52
|
-
'- Use the `
|
|
53
|
-
'-
|
|
54
|
-
'-
|
|
55
|
-
'-
|
|
56
|
-
'-
|
|
57
|
-
'-
|
|
48
|
+
'- Default to serial, proactive assistant work in the main conversation. Answer, inspect, summarize, remember useful non-secret facts, configure Agent-local state, use read-only connected-host/operator routes, and take safe non-destructive actions without creating separate Agent jobs or GoodVibes TUI delegations.',
|
|
49
|
+
'- GoodVibes Agent connects to a GoodVibes host owned outside this package. Do not start, stop, restart, install, expose, or mutate connected-host network/listener posture from Agent.',
|
|
50
|
+
'- Use the `agent_operator_briefing` tool for read-only main-conversation summaries of connected work plan, approvals, automation, schedules, and scheduler capacity. This tool must not call mutation routes, connected-host lifecycle routes, default knowledge, non-Agent knowledge spaces, separate Agent job creation, or GoodVibes TUI delegation.',
|
|
51
|
+
'- When the user explicitly asks Agent to approve, deny, or cancel a specific approval, run/pause/resume a specific automation job, cancel/retry a specific automation run, or run a specific schedule, use the `agent_operator_action` tool with confirm:true and the original user request. It can call only its allowlisted public operator routes and must not create, edit, delete, or discover automation definitions.',
|
|
52
|
+
'- Use the `agent_work_plan` tool to keep the visible Agent-local work plan current while working in the main conversation. Create, inspect, and update local work items proactively when useful. Removing items or clearing completed items requires an explicit user request and confirm:true.',
|
|
53
|
+
'- Use the `agent_knowledge` tool for Agent Knowledge status, ask, and search from the main conversation. It must use only /api/goodvibes-agent/knowledge/* and must fail closed instead of falling back to default knowledge or non-Agent knowledge spaces.',
|
|
54
|
+
'- When the user explicitly asks Agent to add, import, remember, or ingest a URL, URL-list file, local file, bookmarks file, browser history, or connector input into Agent Knowledge, use the `agent_knowledge_ingest` tool with confirm:true and the original user request. It must write only to /api/goodvibes-agent/knowledge/* ingest routes and never to default knowledge or non-Agent knowledge spaces.',
|
|
55
|
+
'- Use the `agent_local_registry` tool when a scratchpad note, durable memory, reusable persona, skill, skill bundle, or routine would improve later work. Keep those records Agent-local, non-secret, source/provenance tagged, and reviewable. Notes are for temporary/source-triage context; promote them explicitly into memory, skills, personas, routines, or Agent Knowledge only when that is the correct durable home. Review memory with a confidence score when it should shape later turns. Starting a routine means applying its steps in this same serial conversation, not creating a background job.',
|
|
56
|
+
'- When the user explicitly asks Agent to generate an image, video, or other media artifact, use the `agent_media_generate` tool with confirm:true and the original user request. Generated media is stored as artifacts; do not print base64, call default knowledge, use non-Agent knowledge spaces, send channels, create separate Agent jobs, or request GoodVibes TUI delegation for media generation.',
|
|
57
|
+
'- When the user explicitly asks Agent to send an alert, message, or notification to configured notification targets, use the `agent_notify` tool with confirm:true and the original user request. Do not infer external notifications from vague suggestions, and never create channel routes or account authorizations from the main conversation.',
|
|
58
|
+
'- When the user explicitly asks Agent to send one message to a specific configured channel, route, webhook, or link target, use the `agent_channel_send` tool with confirm:true and the original user request. It can deliver one message through configured delivery strategies, but must not create routes, authorize accounts, manage connected-host hosting, use default knowledge, use non-Agent knowledge spaces, create separate Agent jobs, or request GoodVibes TUI delegation.',
|
|
59
|
+
'- When the user explicitly asks for a reminder or asks Agent to schedule a reminder, use the `agent_reminder_schedule` tool with confirm:true and the original user request. That creates one connected schedules.create reminder on the external GoodVibes host. Do not infer reminders from vague suggestions or routine startup, and never create local scheduler jobs.',
|
|
60
|
+
'- GoodVibes TUI delegation is never the default Agent reasoning path. Do not delegate planning, research, operations, knowledge, memory, configuration, approvals, automation observability, or ordinary assistant work.',
|
|
61
|
+
'- GoodVibes Agent is not the coding TUI. Do not use the `agent` tool to create coding-role Agent jobs or batch job roots from Agent.',
|
|
62
|
+
'- When the user explicitly asks to build, implement, fix, patch, or review code, preserve the full original user ask and delegate one build request to GoodVibes TUI through the public shared-session/build-delegation contract. Include clear executionIntent and request delegated review only for explicit build/fix/review work or when the user explicitly asks for delegated Agent review.',
|
|
63
|
+
'- Do not narrow explicit build/fix/review requests into design-only, read-only, or no-write work unless the user explicitly requested that limitation. TUI owns file edits, git/worktree work, execution isolation UX, and delegated review coordination.',
|
|
64
|
+
'- If a stable public delegation route is unavailable, say that the task needs GoodVibes TUI delegation and report the missing route instead of pretending to implement it locally or creating sibling Agent jobs.',
|
|
58
65
|
].join('\n');
|
|
59
66
|
|
|
60
67
|
function joinPromptParts(...parts: Array<string | null | undefined>): string {
|
|
@@ -128,9 +135,9 @@ export type BootstrapContext = RuntimeContext & {
|
|
|
128
135
|
* 1. Config, caches, keybindings
|
|
129
136
|
* 2. Runtime event bus, conversation, compositor, selection
|
|
130
137
|
* 3. Tool registry + agent wiring
|
|
131
|
-
* 4. Runtime bus subscriptions (
|
|
138
|
+
* 4. Runtime bus subscriptions (delegation, subagent, hook bridge)
|
|
132
139
|
* 5. Providers, webhooks, PermissionManager, HookDispatcher
|
|
133
|
-
* 6. Orchestrator
|
|
140
|
+
* 6. Orchestrator and Agent-local task read models
|
|
134
141
|
* 7. MCP auto-connect + workspace/panel manager
|
|
135
142
|
* 8. Command registry + plugin init + CommandContext
|
|
136
143
|
* 9. Input handler wiring
|
|
@@ -183,7 +190,7 @@ export async function bootstrapRuntime(
|
|
|
183
190
|
pluginManager,
|
|
184
191
|
} = services;
|
|
185
192
|
|
|
186
|
-
// ── Phase 6: Orchestrator
|
|
193
|
+
// ── Phase 6: Orchestrator and Agent-local task read models ───────────────
|
|
187
194
|
|
|
188
195
|
// Mutable function refs so main.ts can patch these after constructing the scroll/viewport state.
|
|
189
196
|
// The orchestrator closes over these refs, so patching them in main.ts takes immediate effect.
|
|
@@ -243,17 +250,6 @@ export async function bootstrapRuntime(
|
|
|
243
250
|
});
|
|
244
251
|
conversation.setSessionLineageTracker(services.sessionLineageTracker);
|
|
245
252
|
|
|
246
|
-
const acpManager = new AcpManager({
|
|
247
|
-
requestPermission: (request) => permissionPromptRef.requestPermission(request),
|
|
248
|
-
runtimeBus,
|
|
249
|
-
hookDispatcher: services.hookDispatcher,
|
|
250
|
-
});
|
|
251
|
-
const acpTaskAdapter = new AcpTaskAdapter(store);
|
|
252
|
-
const ACP_TASK_SYNC_INTERVAL_MS = 1_000;
|
|
253
|
-
const acpTaskSyncInterval = setInterval(() => {
|
|
254
|
-
acpTaskAdapter.sync(acpManager);
|
|
255
|
-
}, ACP_TASK_SYNC_INTERVAL_MS);
|
|
256
|
-
bootstrapUnsubs.push(() => clearInterval(acpTaskSyncInterval));
|
|
257
253
|
const opsTaskManager = createTaskManager(store, runtimeBus, userSessionId);
|
|
258
254
|
const opsControlPlane = services.featureFlags.isEnabled('operator-control-plane')
|
|
259
255
|
? new OpsControlPlane(opsTaskManager, runtimeBus, store, userSessionId)
|
|
@@ -308,7 +304,7 @@ export async function bootstrapRuntime(
|
|
|
308
304
|
},
|
|
309
305
|
};
|
|
310
306
|
|
|
311
|
-
// ── Phase 7:
|
|
307
|
+
// ── Phase 7: Connected-host posture + deferred startup ────────────────
|
|
312
308
|
|
|
313
309
|
const deferredStartup = createDeferredStartupCoordinator();
|
|
314
310
|
|
|
@@ -323,7 +319,7 @@ export async function bootstrapRuntime(
|
|
|
323
319
|
return `http://${urlHost}:${port}`;
|
|
324
320
|
};
|
|
325
321
|
|
|
326
|
-
const
|
|
322
|
+
const createAgentDependencyStatus = (
|
|
327
323
|
service: 'daemon' | 'httpListener',
|
|
328
324
|
): HostServiceStatus => {
|
|
329
325
|
const host = String(configManager.get(service === 'daemon' ? 'controlPlane.host' : 'httpListener.host') ?? '127.0.0.1');
|
|
@@ -334,7 +330,7 @@ export async function bootstrapRuntime(
|
|
|
334
330
|
port,
|
|
335
331
|
baseUrl: formatHostServiceBaseUrl(host, port),
|
|
336
332
|
reason: service === 'daemon'
|
|
337
|
-
? 'GoodVibes Agent connects to GoodVibes
|
|
333
|
+
? 'GoodVibes Agent connects to a GoodVibes host owned outside this product and does not start or restart it.'
|
|
338
334
|
: 'GoodVibes Agent does not own listener lifecycle.',
|
|
339
335
|
};
|
|
340
336
|
};
|
|
@@ -343,15 +339,15 @@ export async function bootstrapRuntime(
|
|
|
343
339
|
|
|
344
340
|
const hostServiceIsBlocked = (status: HostServiceStatus): boolean => status.mode === 'blocked';
|
|
345
341
|
|
|
346
|
-
const
|
|
342
|
+
const inspectAgentDependencies = () => {
|
|
347
343
|
const daemonStatus = externalServices.daemonStatus;
|
|
348
344
|
const httpListenerStatus = externalServices.httpListenerStatus;
|
|
349
345
|
return {
|
|
350
|
-
|
|
351
|
-
|
|
346
|
+
connectedHostRunning: hostServiceIsActive(daemonStatus),
|
|
347
|
+
connectedHostPortInUse: hostServiceIsBlocked(daemonStatus),
|
|
352
348
|
httpListenerRunning: hostServiceIsActive(httpListenerStatus),
|
|
353
349
|
httpListenerPortInUse: hostServiceIsBlocked(httpListenerStatus),
|
|
354
|
-
daemonStatus,
|
|
350
|
+
connectedHostStatus: daemonStatus,
|
|
355
351
|
httpListenerStatus,
|
|
356
352
|
};
|
|
357
353
|
};
|
|
@@ -359,8 +355,8 @@ export async function bootstrapRuntime(
|
|
|
359
355
|
let externalServices: ExternalServicesHandle = {
|
|
360
356
|
daemonServer: null,
|
|
361
357
|
httpListener: null,
|
|
362
|
-
daemonStatus:
|
|
363
|
-
httpListenerStatus:
|
|
358
|
+
daemonStatus: createAgentDependencyStatus('daemon'),
|
|
359
|
+
httpListenerStatus: createAgentDependencyStatus('httpListener'),
|
|
364
360
|
listRecentControlPlaneEvents: () => [],
|
|
365
361
|
async stop(): Promise<void> {},
|
|
366
362
|
};
|
|
@@ -368,16 +364,16 @@ export async function bootstrapRuntime(
|
|
|
368
364
|
externalServices: NonNullable<typeof uiServices.platform.externalServices>;
|
|
369
365
|
};
|
|
370
366
|
platformExternalServices.externalServices = {
|
|
371
|
-
inspect:
|
|
367
|
+
inspect: inspectAgentDependencies,
|
|
372
368
|
restart: async () => {
|
|
373
369
|
externalServices = {
|
|
374
370
|
...externalServices,
|
|
375
|
-
daemonStatus:
|
|
376
|
-
httpListenerStatus:
|
|
371
|
+
daemonStatus: createAgentDependencyStatus('daemon'),
|
|
372
|
+
httpListenerStatus: createAgentDependencyStatus('httpListener'),
|
|
377
373
|
};
|
|
378
|
-
systemMessageRouter.high('[Startup] GoodVibes Agent does not start or restart connected GoodVibes
|
|
374
|
+
systemMessageRouter.high('[Startup] GoodVibes Agent does not start or restart the connected GoodVibes host. Start it from GoodVibes TUI or the owning host, then refresh status.');
|
|
379
375
|
requestRender();
|
|
380
|
-
return
|
|
376
|
+
return inspectAgentDependencies();
|
|
381
377
|
},
|
|
382
378
|
};
|
|
383
379
|
deferredStartup.schedule({
|
|
@@ -452,8 +448,8 @@ export async function bootstrapRuntime(
|
|
|
452
448
|
});
|
|
453
449
|
bootstrapUnsubs.push(() => mcpAutoReload.stop());
|
|
454
450
|
if (configManager.get('automation.enabled')) {
|
|
455
|
-
logger.warn('Local automation startup is disabled in GoodVibes Agent; use connected-
|
|
456
|
-
systemMessageRouter.low('[Startup] Local automation
|
|
451
|
+
logger.warn('Local automation startup is disabled in GoodVibes Agent; use connected-host observability instead.');
|
|
452
|
+
systemMessageRouter.low('[Startup] Local automation execution is disabled in GoodVibes Agent; use read-only automation observability or explicit connected-host actions.');
|
|
457
453
|
}
|
|
458
454
|
|
|
459
455
|
// ── Phase 12: Session:start lifecycle hook ─────────────────────────────
|
|
@@ -554,12 +550,6 @@ export async function bootstrapRuntime(
|
|
|
554
550
|
},
|
|
555
551
|
};
|
|
556
552
|
|
|
557
|
-
// ── Phase 12b: Operator intervention wiring (feature-gated) ──────────────
|
|
558
|
-
// Keep service-owned control-plane state internal. GoodVibes Agent does not
|
|
559
|
-
// expose the local ops-control panel; operator control is surfaced
|
|
560
|
-
// through Agent-owned status, approvals, automation, and delegation flows.
|
|
561
|
-
ctx.commandContext.ops.acpManager = acpManager;
|
|
562
|
-
|
|
563
553
|
// Wire exit from options if provided; otherwise main.ts binds the shell bridge.
|
|
564
554
|
if (options?.exit) {
|
|
565
555
|
ctx.commandContext.exit = options.exit;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
type JsonRecord = Record<string, unknown>;
|
|
6
|
+
|
|
7
|
+
export interface ConnectedHostOperatorToken {
|
|
8
|
+
readonly path: string;
|
|
9
|
+
readonly present: boolean;
|
|
10
|
+
readonly token: string | null;
|
|
11
|
+
readonly error?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isRecord(value: unknown): value is JsonRecord {
|
|
15
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function connectedHostOperatorTokenPath(homeDirectory: string): string {
|
|
19
|
+
return join(homeDirectory, '.goodvibes', 'daemon', 'operator-tokens.json');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function readConnectedHostOperatorToken(homeDirectory: string): ConnectedHostOperatorToken {
|
|
23
|
+
const path = connectedHostOperatorTokenPath(homeDirectory);
|
|
24
|
+
if (!existsSync(path)) return { path, present: false, token: null };
|
|
25
|
+
try {
|
|
26
|
+
const parsed = JSON.parse(readFileSync(path, 'utf-8')) as unknown;
|
|
27
|
+
const token = isRecord(parsed) && typeof parsed.token === 'string' && parsed.token.trim().length > 0
|
|
28
|
+
? parsed.token
|
|
29
|
+
: null;
|
|
30
|
+
return { path, present: true, token };
|
|
31
|
+
} catch (error) {
|
|
32
|
+
return { path, present: true, token: null, error: error instanceof Error ? error.message : String(error) };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function connectedHostOperatorTokenFingerprint(token: string): string {
|
|
37
|
+
return createHash('sha256').update(token).digest('hex').slice(0, 12);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function connectedHostTokenRequiredMessage(path: string): string {
|
|
41
|
+
return [
|
|
42
|
+
'Connected-host operator token is required.',
|
|
43
|
+
` token path ${path}`,
|
|
44
|
+
' Agent does not create or rotate connected-host auth tokens.',
|
|
45
|
+
' Provision or repair connected-host access through the owning GoodVibes host, then rerun this command.',
|
|
46
|
+
].join('\n');
|
|
47
|
+
}
|
|
@@ -12,8 +12,8 @@ export type { InspectableDomain } from '@/runtime/index.ts';
|
|
|
12
12
|
export { HealthPanel } from '@/runtime/index.ts';
|
|
13
13
|
export { DivergencePanel } from '@/runtime/index.ts';
|
|
14
14
|
export { ReplayPanel } from '@/runtime/index.ts';
|
|
15
|
-
export {
|
|
16
|
-
export type {
|
|
15
|
+
export { PolicyDiagnosticsPanel } from './policy.ts';
|
|
16
|
+
export type { PolicyDiagnosticsSnapshot } from './policy.ts';
|
|
17
17
|
export { ToolContractsPanel } from '@/runtime/index.ts';
|
|
18
18
|
export { TransportPanel } from '@/runtime/index.ts';
|
|
19
19
|
export type { TransportPanelSnapshot } from '@/runtime/index.ts';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Panel resource diagnostics panel data provider.
|
|
3
3
|
*
|
|
4
|
-
* Polls the shared
|
|
4
|
+
* Polls the shared shell ComponentHealthMonitor and produces PanelResourceSnapshot
|
|
5
5
|
* values for the diagnostics panel to render.
|
|
6
6
|
*/
|
|
7
7
|
import type { ComponentHealthMonitor } from '../../perf/panel-health-monitor.ts';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Policy diagnostics
|
|
2
|
+
* Policy diagnostics data provider.
|
|
3
3
|
*
|
|
4
4
|
* Wraps a `PolicyRegistry` and optionally a `DivergencePanel` to expose
|
|
5
5
|
* combined policy state (current bundle, candidate, simulation status,
|
|
@@ -24,7 +24,7 @@ import { logger } from '@pellux/goodvibes-sdk/platform/utils';
|
|
|
24
24
|
/**
|
|
25
25
|
* A point-in-time snapshot of policy state for diagnostics rendering.
|
|
26
26
|
*/
|
|
27
|
-
export interface
|
|
27
|
+
export interface PolicyDiagnosticsSnapshot {
|
|
28
28
|
/** The currently enforced bundle, or null if no policy is active. */
|
|
29
29
|
current: PolicyBundleVersion | null;
|
|
30
30
|
/** The pending candidate bundle, or null if none loaded. */
|
|
@@ -48,12 +48,12 @@ export interface PolicyPanelSnapshot {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
51
|
+
* PolicyDiagnosticsPanel — diagnostics data provider for the policy registry.
|
|
52
52
|
*
|
|
53
53
|
* Usage:
|
|
54
54
|
* ```ts
|
|
55
55
|
* const registry = new PolicyRegistry();
|
|
56
|
-
* const panel = new
|
|
56
|
+
* const panel = new PolicyDiagnosticsPanel(registry, divergencePanel);
|
|
57
57
|
*
|
|
58
58
|
* panel.subscribe(() => {
|
|
59
59
|
* const snap = panel.getSnapshot();
|
|
@@ -67,7 +67,7 @@ export interface PolicyPanelSnapshot {
|
|
|
67
67
|
* panel.dispose();
|
|
68
68
|
* ```
|
|
69
69
|
*/
|
|
70
|
-
export class
|
|
70
|
+
export class PolicyDiagnosticsPanel {
|
|
71
71
|
private readonly _registry: PolicyRegistry;
|
|
72
72
|
private readonly _divergencePanel: DivergencePanel | null;
|
|
73
73
|
private readonly _config: PanelConfig;
|
|
@@ -118,7 +118,7 @@ export class PolicyPanel {
|
|
|
118
118
|
/**
|
|
119
119
|
* getSnapshot — Returns the current combined policy + divergence snapshot.
|
|
120
120
|
*/
|
|
121
|
-
public getSnapshot():
|
|
121
|
+
public getSnapshot(): PolicyDiagnosticsSnapshot {
|
|
122
122
|
const current = this._registry.getCurrent();
|
|
123
123
|
const candidate = this._registry.getCandidate();
|
|
124
124
|
const rawHistory = this._registry.getHistory();
|
|
@@ -170,7 +170,7 @@ export class PolicyPanel {
|
|
|
170
170
|
try {
|
|
171
171
|
cb();
|
|
172
172
|
} catch (err) {
|
|
173
|
-
logger.warn(`[
|
|
173
|
+
logger.warn(`[PolicyDiagnosticsPanel] subscriber error: ${err}`);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
}
|