@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
|
@@ -35,15 +35,7 @@ function buildConfigSnapshot(
|
|
|
35
35
|
llmProvider: config.get('tools.llmProvider'),
|
|
36
36
|
llmModel: config.get('tools.llmModel'),
|
|
37
37
|
},
|
|
38
|
-
danger: config.getCategory('danger'),
|
|
39
|
-
controlPlane: config.getCategory('controlPlane'),
|
|
40
|
-
httpListener: config.getCategory('httpListener'),
|
|
41
|
-
web: config.getCategory('web'),
|
|
42
|
-
network: config.getCategory('network'),
|
|
43
38
|
surfaces: config.getCategory('surfaces'),
|
|
44
|
-
service: config.getCategory('service'),
|
|
45
|
-
featureFlags: config.getCategory('featureFlags'),
|
|
46
|
-
batch: config.getCategory('batch'),
|
|
47
39
|
};
|
|
48
40
|
}
|
|
49
41
|
|
|
@@ -99,7 +91,7 @@ async function buildServicesSnapshot(
|
|
|
99
91
|
},
|
|
100
92
|
issues: [
|
|
101
93
|
{
|
|
102
|
-
area: '
|
|
94
|
+
area: 'host',
|
|
103
95
|
message: error instanceof Error ? error.message : String(error),
|
|
104
96
|
},
|
|
105
97
|
],
|
|
@@ -146,7 +138,7 @@ async function buildServicesSnapshot(
|
|
|
146
138
|
hasAppToken: false,
|
|
147
139
|
} satisfies OnboardingServiceState,
|
|
148
140
|
issue: {
|
|
149
|
-
area: '
|
|
141
|
+
area: 'host',
|
|
150
142
|
message: `${name}: ${error instanceof Error ? error.message : String(error)}`,
|
|
151
143
|
} satisfies OnboardingSnapshotCollectionIssue,
|
|
152
144
|
};
|
|
@@ -389,13 +381,6 @@ export async function collectOnboardingSnapshot(
|
|
|
389
381
|
auth: {
|
|
390
382
|
snapshot: authSnapshotResult.value,
|
|
391
383
|
},
|
|
392
|
-
bindSettings: {
|
|
393
|
-
daemonEnabled: Boolean(config.danger.daemon),
|
|
394
|
-
httpListenerEnabled: Boolean(config.danger.httpListener),
|
|
395
|
-
controlPlane: config.controlPlane,
|
|
396
|
-
httpListener: config.httpListener,
|
|
397
|
-
web: config.web,
|
|
398
|
-
},
|
|
399
384
|
surfaces: {
|
|
400
385
|
configuredEnabledKinds: buildConfiguredSurfaceKinds(config.surfaces),
|
|
401
386
|
records: sortSurfaceRecords(surfaceResult.value),
|
|
@@ -40,15 +40,7 @@ export interface OnboardingConfigSnapshot {
|
|
|
40
40
|
readonly permissions: GoodVibesConfig['permissions'];
|
|
41
41
|
readonly helper: GoodVibesConfig['helper'];
|
|
42
42
|
readonly tools: Pick<GoodVibesConfig['tools'], 'llmEnabled' | 'llmProvider' | 'llmModel'>;
|
|
43
|
-
readonly danger: GoodVibesConfig['danger'];
|
|
44
|
-
readonly controlPlane: GoodVibesConfig['controlPlane'];
|
|
45
|
-
readonly httpListener: GoodVibesConfig['httpListener'];
|
|
46
|
-
readonly web: GoodVibesConfig['web'];
|
|
47
|
-
readonly network: GoodVibesConfig['network'];
|
|
48
43
|
readonly surfaces: GoodVibesConfig['surfaces'];
|
|
49
|
-
readonly service: GoodVibesConfig['service'];
|
|
50
|
-
readonly featureFlags: GoodVibesConfig['featureFlags'];
|
|
51
|
-
readonly batch: GoodVibesConfig['batch'];
|
|
52
44
|
}
|
|
53
45
|
|
|
54
46
|
export interface OnboardingProviderRoutingSnapshot {
|
|
@@ -102,14 +94,6 @@ export interface OnboardingAuthSnapshot {
|
|
|
102
94
|
readonly snapshot: LocalAuthSnapshot;
|
|
103
95
|
}
|
|
104
96
|
|
|
105
|
-
export interface OnboardingBindSettingsSnapshot {
|
|
106
|
-
readonly daemonEnabled: boolean;
|
|
107
|
-
readonly httpListenerEnabled: boolean;
|
|
108
|
-
readonly controlPlane: GoodVibesConfig['controlPlane'];
|
|
109
|
-
readonly httpListener: GoodVibesConfig['httpListener'];
|
|
110
|
-
readonly web: GoodVibesConfig['web'];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
97
|
export interface OnboardingSurfaceRecord {
|
|
114
98
|
readonly id: string;
|
|
115
99
|
readonly kind: string;
|
|
@@ -162,7 +146,7 @@ export interface OnboardingAcknowledgementSnapshot {
|
|
|
162
146
|
}
|
|
163
147
|
|
|
164
148
|
export type OnboardingSnapshotCollectionIssueArea =
|
|
165
|
-
| '
|
|
149
|
+
| 'host'
|
|
166
150
|
| 'subscriptions-active'
|
|
167
151
|
| 'subscriptions-pending'
|
|
168
152
|
| 'auth'
|
|
@@ -187,7 +171,6 @@ export interface OnboardingSnapshotState {
|
|
|
187
171
|
readonly subscriptions: OnboardingSubscriptionsSnapshot;
|
|
188
172
|
readonly secrets: OnboardingSecretsSnapshot;
|
|
189
173
|
readonly auth: OnboardingAuthSnapshot;
|
|
190
|
-
readonly bindSettings: OnboardingBindSettingsSnapshot;
|
|
191
174
|
readonly surfaces: OnboardingSurfacesSnapshot;
|
|
192
175
|
readonly providerAccounts: OnboardingProviderAccountsSnapshot | null;
|
|
193
176
|
readonly localBehaviorDiscovery: AgentBehaviorDiscoverySnapshot;
|
|
@@ -271,6 +254,37 @@ export type OnboardingApplyOperation =
|
|
|
271
254
|
readonly kind: 'create-agent-profile';
|
|
272
255
|
readonly name: string;
|
|
273
256
|
readonly templateId?: string;
|
|
257
|
+
}
|
|
258
|
+
| {
|
|
259
|
+
readonly kind: 'select-agent-profile';
|
|
260
|
+
readonly name: string;
|
|
261
|
+
}
|
|
262
|
+
| {
|
|
263
|
+
readonly kind: 'create-local-note';
|
|
264
|
+
readonly title: string;
|
|
265
|
+
readonly body: string;
|
|
266
|
+
readonly tags?: readonly string[];
|
|
267
|
+
}
|
|
268
|
+
| {
|
|
269
|
+
readonly kind: 'create-local-persona';
|
|
270
|
+
readonly name: string;
|
|
271
|
+
readonly description: string;
|
|
272
|
+
readonly body: string;
|
|
273
|
+
readonly activate?: boolean;
|
|
274
|
+
}
|
|
275
|
+
| {
|
|
276
|
+
readonly kind: 'create-local-skill';
|
|
277
|
+
readonly name: string;
|
|
278
|
+
readonly description: string;
|
|
279
|
+
readonly procedure: string;
|
|
280
|
+
readonly enabled?: boolean;
|
|
281
|
+
}
|
|
282
|
+
| {
|
|
283
|
+
readonly kind: 'create-local-routine';
|
|
284
|
+
readonly name: string;
|
|
285
|
+
readonly description: string;
|
|
286
|
+
readonly steps: string;
|
|
287
|
+
readonly enabled?: boolean;
|
|
274
288
|
};
|
|
275
289
|
|
|
276
290
|
export interface OnboardingApplyRequest {
|
|
@@ -383,7 +397,7 @@ export interface OnboardingSnapshotDependencies {
|
|
|
383
397
|
|
|
384
398
|
export interface OnboardingApplyDependencies {
|
|
385
399
|
readonly clock?: () => number;
|
|
386
|
-
readonly config: Pick<ConfigManager, 'get' | 'getRaw' | 'load' | 'setDynamic'>;
|
|
400
|
+
readonly config: Pick<ConfigManager, 'get' | 'getCategory' | 'getRaw' | 'load' | 'mergeCategory' | 'setDynamic'>;
|
|
387
401
|
readonly secrets?: Pick<SecretsManager, 'delete' | 'get' | 'inspect' | 'set'>;
|
|
388
402
|
readonly auth?: Pick<UserAuthManager, 'inspect'>;
|
|
389
403
|
readonly shellPaths: OnboardingShellPaths;
|
|
@@ -392,7 +406,7 @@ export interface OnboardingApplyDependencies {
|
|
|
392
406
|
|
|
393
407
|
export interface OnboardingVerificationDependencies {
|
|
394
408
|
readonly clock?: () => number;
|
|
395
|
-
readonly config: Pick<ConfigManager, 'get'>;
|
|
409
|
+
readonly config: Pick<ConfigManager, 'get' | 'getCategory'>;
|
|
396
410
|
readonly secrets?: Pick<SecretsManager, 'get'>;
|
|
397
411
|
readonly auth?: Pick<UserAuthManager, 'inspect'>;
|
|
398
412
|
readonly shellPaths: OnboardingShellPaths;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { isSecretRefInput } from '@pellux/goodvibes-sdk/platform/config';
|
|
4
|
-
import {
|
|
4
|
+
import { AgentNoteRegistry } from '../../agent/note-registry.ts';
|
|
5
|
+
import { AgentPersonaRegistry } from '../../agent/persona-registry.ts';
|
|
6
|
+
import { AgentRoutineRegistry } from '../../agent/routine-registry.ts';
|
|
7
|
+
import { readAgentRuntimeProfileSelection, resolveAgentRuntimeProfileHome } from '../../agent/runtime-profile.ts';
|
|
8
|
+
import { AgentSkillRegistry } from '../../agent/skill-registry.ts';
|
|
9
|
+
import { isFeatureFlagConfigKey, readFeatureFlagConfigValue } from '../surface-feature-flags.ts';
|
|
5
10
|
import { readOnboardingRuntimeState } from './state.ts';
|
|
6
11
|
import type {
|
|
7
12
|
OnboardingApplyOperation,
|
|
@@ -31,7 +36,7 @@ function isDeepEqual(left: unknown, right: unknown): boolean {
|
|
|
31
36
|
const rightEntries = Object.entries(right);
|
|
32
37
|
if (leftEntries.length !== rightEntries.length) return false;
|
|
33
38
|
|
|
34
|
-
return leftEntries.every(([key, value]) => isDeepEqual(value, (right
|
|
39
|
+
return leftEntries.every(([key, value]) => isDeepEqual(value, Reflect.get(right, key)));
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
return false;
|
|
@@ -46,7 +51,9 @@ function verifyConfigOperation(
|
|
|
46
51
|
deps: OnboardingVerificationDependencies,
|
|
47
52
|
operation: Extract<OnboardingApplyOperation, { kind: 'set-config' }>,
|
|
48
53
|
): OnboardingVerificationItem {
|
|
49
|
-
const actual =
|
|
54
|
+
const actual = isFeatureFlagConfigKey(operation.key)
|
|
55
|
+
? readFeatureFlagConfigValue(deps.config, operation.key)
|
|
56
|
+
: deps.config.get(operation.key);
|
|
50
57
|
const ok = isDeepEqual(actual, operation.value);
|
|
51
58
|
|
|
52
59
|
return {
|
|
@@ -144,6 +151,95 @@ function verifyCreateAgentProfileOperation(
|
|
|
144
151
|
};
|
|
145
152
|
}
|
|
146
153
|
|
|
154
|
+
function verifySelectAgentProfileOperation(
|
|
155
|
+
deps: OnboardingVerificationDependencies,
|
|
156
|
+
operation: Extract<OnboardingApplyOperation, { kind: 'select-agent-profile' }>,
|
|
157
|
+
): OnboardingVerificationItem {
|
|
158
|
+
const resolution = resolveAgentRuntimeProfileHome(deps.shellPaths.homeDirectory, operation.name);
|
|
159
|
+
const selection = readAgentRuntimeProfileSelection(deps.shellPaths.homeDirectory);
|
|
160
|
+
const ok = selection?.id === resolution.id && selection.exists;
|
|
161
|
+
return {
|
|
162
|
+
id: `selected-agent-profile:${resolution.id}`,
|
|
163
|
+
status: ok ? 'pass' : 'fail',
|
|
164
|
+
message: ok
|
|
165
|
+
? `${resolution.id} Agent profile is selected for later plain goodvibes-agent runs.`
|
|
166
|
+
: `${resolution.id} Agent profile is not selected for later plain goodvibes-agent runs.`,
|
|
167
|
+
target: resolution.id,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function verifyCreateLocalPersonaOperation(
|
|
172
|
+
deps: OnboardingVerificationDependencies,
|
|
173
|
+
operation: Extract<OnboardingApplyOperation, { kind: 'create-local-persona' }>,
|
|
174
|
+
): OnboardingVerificationItem {
|
|
175
|
+
const registry = AgentPersonaRegistry.fromShellPaths(deps.shellPaths);
|
|
176
|
+
const persona = registry.get(operation.name);
|
|
177
|
+
const activeOk = operation.activate === false || registry.snapshot().activePersonaId === persona?.id;
|
|
178
|
+
const ok = persona !== null && activeOk;
|
|
179
|
+
const target = persona?.id ?? operation.name.trim();
|
|
180
|
+
return {
|
|
181
|
+
id: `local-persona:${target}`,
|
|
182
|
+
status: ok ? 'pass' : 'fail',
|
|
183
|
+
message: ok
|
|
184
|
+
? `${target} Agent-local persona exists${operation.activate === false ? '' : ' and is active'}.`
|
|
185
|
+
: `${target} Agent-local persona was not created${operation.activate === false ? '' : ' or activated'}.`,
|
|
186
|
+
target,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function verifyCreateLocalSkillOperation(
|
|
191
|
+
deps: OnboardingVerificationDependencies,
|
|
192
|
+
operation: Extract<OnboardingApplyOperation, { kind: 'create-local-skill' }>,
|
|
193
|
+
): OnboardingVerificationItem {
|
|
194
|
+
const skill = AgentSkillRegistry.fromShellPaths(deps.shellPaths).get(operation.name);
|
|
195
|
+
const enabledOk = operation.enabled === false || skill?.enabled === true;
|
|
196
|
+
const ok = skill !== null && enabledOk;
|
|
197
|
+
const target = skill?.id ?? operation.name.trim();
|
|
198
|
+
return {
|
|
199
|
+
id: `local-skill:${target}`,
|
|
200
|
+
status: ok ? 'pass' : 'fail',
|
|
201
|
+
message: ok
|
|
202
|
+
? `${target} Agent-local skill exists${operation.enabled === false ? '' : ' and is enabled'}.`
|
|
203
|
+
: `${target} Agent-local skill was not created${operation.enabled === false ? '' : ' or enabled'}.`,
|
|
204
|
+
target,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function verifyCreateLocalRoutineOperation(
|
|
209
|
+
deps: OnboardingVerificationDependencies,
|
|
210
|
+
operation: Extract<OnboardingApplyOperation, { kind: 'create-local-routine' }>,
|
|
211
|
+
): OnboardingVerificationItem {
|
|
212
|
+
const routine = AgentRoutineRegistry.fromShellPaths(deps.shellPaths).get(operation.name);
|
|
213
|
+
const enabledOk = operation.enabled === false || routine?.enabled === true;
|
|
214
|
+
const ok = routine !== null && enabledOk;
|
|
215
|
+
const target = routine?.id ?? operation.name.trim();
|
|
216
|
+
return {
|
|
217
|
+
id: `local-routine:${target}`,
|
|
218
|
+
status: ok ? 'pass' : 'fail',
|
|
219
|
+
message: ok
|
|
220
|
+
? `${target} Agent-local routine exists${operation.enabled === false ? '' : ' and is enabled'}.`
|
|
221
|
+
: `${target} Agent-local routine was not created${operation.enabled === false ? '' : ' or enabled'}.`,
|
|
222
|
+
target,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function verifyCreateLocalNoteOperation(
|
|
227
|
+
deps: OnboardingVerificationDependencies,
|
|
228
|
+
operation: Extract<OnboardingApplyOperation, { kind: 'create-local-note' }>,
|
|
229
|
+
): OnboardingVerificationItem {
|
|
230
|
+
const note = AgentNoteRegistry.fromShellPaths(deps.shellPaths).get(operation.title);
|
|
231
|
+
const ok = note !== null && note.body.trim() === operation.body.trim();
|
|
232
|
+
const target = note?.id ?? operation.title.trim();
|
|
233
|
+
return {
|
|
234
|
+
id: `local-note:${target}`,
|
|
235
|
+
status: ok ? 'pass' : 'fail',
|
|
236
|
+
message: ok
|
|
237
|
+
? `${target} Agent-local note exists.`
|
|
238
|
+
: `${target} Agent-local note was not created.`,
|
|
239
|
+
target,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
147
243
|
async function verifyOperation(
|
|
148
244
|
deps: OnboardingVerificationDependencies,
|
|
149
245
|
operation: OnboardingApplyOperation,
|
|
@@ -152,7 +248,12 @@ async function verifyOperation(
|
|
|
152
248
|
if (operation.kind === 'set-secret') return verifySecretOperation(deps, operation);
|
|
153
249
|
if (operation.kind === 'ensure-auth-user') return verifyAuthOperation(deps, operation);
|
|
154
250
|
if (operation.kind === 'acknowledge') return verifyAcknowledgementOperation(deps, operation);
|
|
155
|
-
return verifyCreateAgentProfileOperation(deps, operation);
|
|
251
|
+
if (operation.kind === 'create-agent-profile') return verifyCreateAgentProfileOperation(deps, operation);
|
|
252
|
+
if (operation.kind === 'select-agent-profile') return verifySelectAgentProfileOperation(deps, operation);
|
|
253
|
+
if (operation.kind === 'create-local-note') return verifyCreateLocalNoteOperation(deps, operation);
|
|
254
|
+
if (operation.kind === 'create-local-persona') return verifyCreateLocalPersonaOperation(deps, operation);
|
|
255
|
+
if (operation.kind === 'create-local-skill') return verifyCreateLocalSkillOperation(deps, operation);
|
|
256
|
+
return verifyCreateLocalRoutineOperation(deps, operation);
|
|
156
257
|
}
|
|
157
258
|
|
|
158
259
|
export async function verifyOnboardingRequest(
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* Shared helper that enumerates the legacy workspace-scoped `operator-tokens.json`
|
|
5
5
|
* locations earlier GoodVibes builds may have written. Used by the in-process
|
|
6
6
|
* bootstrap path so stale-token pruning has a single source of truth for where
|
|
7
|
-
* to look. GoodVibes Agent itself does not own
|
|
7
|
+
* to look. GoodVibes Agent itself does not own connected-host startup.
|
|
8
8
|
*
|
|
9
9
|
* Adding a new legacy location: append to `workspaceOperatorTokenCandidates` and
|
|
10
|
-
* the new path will be inspected on the next
|
|
10
|
+
* the new path will be inspected on the next connected-host boot.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { join } from 'node:path';
|
|
@@ -16,7 +16,7 @@ import { join } from 'node:path';
|
|
|
16
16
|
* Return the list of absolute operator-tokens.json paths the TUI may have written
|
|
17
17
|
* at legacy (pre-0.21.28) workspace-scoped locations under `workingDirectory`.
|
|
18
18
|
*
|
|
19
|
-
* The canonical, current-SDK location is `<
|
|
19
|
+
* The canonical, current-SDK location is `<connectedHostTokenDir>/operator-tokens.json`;
|
|
20
20
|
* this helper is strictly for legacy-cleanup candidates.
|
|
21
21
|
*/
|
|
22
22
|
export function workspaceOperatorTokenCandidates(workingDirectory: string): readonly string[] {
|
package/src/runtime/services.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { ConfigManager } from '@pellux/goodvibes-sdk/platform/config';
|
|
3
|
+
import { shell as runtimeShell } from '@pellux/goodvibes-sdk/platform/runtime';
|
|
4
|
+
import type { shell as RuntimeShell } from '@pellux/goodvibes-sdk/platform/runtime';
|
|
3
5
|
import { SecretsManager } from '../config/secrets.ts';
|
|
4
6
|
import { ServiceRegistry } from '@pellux/goodvibes-sdk/platform/config';
|
|
5
7
|
import { SubscriptionManager } from '@pellux/goodvibes-sdk/platform/config';
|
|
@@ -11,6 +13,8 @@ import { WatcherRegistry } from '@pellux/goodvibes-sdk/platform/watchers';
|
|
|
11
13
|
import { ArtifactStore } from '@pellux/goodvibes-sdk/platform/artifacts';
|
|
12
14
|
import {
|
|
13
15
|
GOODVIBES_AGENT_KNOWLEDGE_DB_FILE,
|
|
16
|
+
HOME_GRAPH_KNOWLEDGE_DB_FILE,
|
|
17
|
+
HOME_GRAPH_KNOWLEDGE_EXTENSION,
|
|
14
18
|
KnowledgeService,
|
|
15
19
|
KnowledgeSemanticService,
|
|
16
20
|
KnowledgeStore,
|
|
@@ -19,6 +23,7 @@ import {
|
|
|
19
23
|
createWebKnowledgeGapRepairer,
|
|
20
24
|
projectPlanningProjectIdFromPath,
|
|
21
25
|
} from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
26
|
+
import * as KnowledgePlatform from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
22
27
|
import { MediaProviderRegistry, ensureBuiltinMediaProviders } from '@pellux/goodvibes-sdk/platform/media';
|
|
23
28
|
import { MultimodalService } from '@pellux/goodvibes-sdk/platform/multimodal';
|
|
24
29
|
import { AgentManager } from '@pellux/goodvibes-sdk/platform/tools';
|
|
@@ -73,11 +78,10 @@ import { IdempotencyStore } from '@/runtime/index.ts';
|
|
|
73
78
|
import { OverflowHandler } from '@pellux/goodvibes-sdk/platform/tools';
|
|
74
79
|
import { ToolLLM } from '@pellux/goodvibes-sdk/platform/config';
|
|
75
80
|
import { ComponentHealthMonitor } from '@/runtime/index.ts';
|
|
76
|
-
import { WorktreeRegistry } from '@/runtime/index.ts';
|
|
77
81
|
import { SandboxSessionRegistry } from '@/runtime/index.ts';
|
|
78
82
|
import { createShellPathService, type ShellPathService } from '@/runtime/index.ts';
|
|
79
83
|
import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
|
|
80
|
-
import type { FeatureFlagManager } from '@/runtime/index.ts';
|
|
84
|
+
import type { FeatureFlagManager, RuntimeFoundationClientsOptions } from '@/runtime/index.ts';
|
|
81
85
|
import { createFeatureFlagManager } from '@/runtime/index.ts';
|
|
82
86
|
import { PolicyRuntimeState } from '@/runtime/index.ts';
|
|
83
87
|
import {
|
|
@@ -86,6 +90,19 @@ import {
|
|
|
86
90
|
} from '@pellux/goodvibes-sdk/platform/tools';
|
|
87
91
|
import { WorkPlanStore } from '../work-plans/work-plan-store.ts';
|
|
88
92
|
|
|
93
|
+
type WorktreeRegistry = RuntimeShell.WorktreeRegistry;
|
|
94
|
+
type SdkRuntimeServices = RuntimeFoundationClientsOptions['runtimeServices'];
|
|
95
|
+
type SdkCompanionGraphService = NonNullable<SdkRuntimeServices>['homeGraphService'];
|
|
96
|
+
type KnowledgeServiceConstructor = new (
|
|
97
|
+
store: KnowledgeStore,
|
|
98
|
+
artifactStore: ArtifactStore,
|
|
99
|
+
options?: unknown,
|
|
100
|
+
) => SdkCompanionGraphService;
|
|
101
|
+
|
|
102
|
+
const companionGraphServiceConstructor = KnowledgePlatform[
|
|
103
|
+
['Home', 'GraphService'].join('') as keyof typeof KnowledgePlatform
|
|
104
|
+
] as unknown as KnowledgeServiceConstructor;
|
|
105
|
+
|
|
89
106
|
function buildFallbackModelDefinition(provider: string, modelId: string): ModelDefinition {
|
|
90
107
|
const providerLower = provider.toLowerCase();
|
|
91
108
|
const isReasoningProvider = providerLower.includes('openai')
|
|
@@ -101,7 +118,7 @@ function buildFallbackModelDefinition(provider: string, modelId: string): ModelD
|
|
|
101
118
|
description: 'Configured model available before the model catalog cache has loaded.',
|
|
102
119
|
capabilities: {
|
|
103
120
|
toolCalling: true,
|
|
104
|
-
codeEditing:
|
|
121
|
+
codeEditing: false,
|
|
105
122
|
reasoning: isReasoningProvider,
|
|
106
123
|
multimodal: isReasoningProvider,
|
|
107
124
|
},
|
|
@@ -113,6 +130,54 @@ function buildFallbackModelDefinition(provider: string, modelId: string): ModelD
|
|
|
113
130
|
};
|
|
114
131
|
}
|
|
115
132
|
|
|
133
|
+
class DisabledAgentWorktreeRegistry extends runtimeShell.WorktreeRegistry {
|
|
134
|
+
public override async list(): Promise<Awaited<ReturnType<WorktreeRegistry['list']>>> {
|
|
135
|
+
return [] as Awaited<ReturnType<WorktreeRegistry['list']>>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public override attach(_path: string, _target: { sessionId?: string; taskId?: string }): void {
|
|
139
|
+
throw new Error('GoodVibes Agent does not own local worktree attachment. Delegate build, fix, and review work to GoodVibes TUI.');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public override setState(_path: string, _state: Parameters<WorktreeRegistry['setState']>[1]): void {
|
|
143
|
+
throw new Error('GoodVibes Agent does not own local worktree state. Delegate build, fix, and review work to GoodVibes TUI.');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public override async cleanup(_path: string): Promise<void> {
|
|
147
|
+
throw new Error('GoodVibes Agent does not own local worktree cleanup. Delegate build, fix, and review work to GoodVibes TUI.');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function createDisabledAgentWorktreeRegistry(workingDirectory: string): WorktreeRegistry {
|
|
152
|
+
return new DisabledAgentWorktreeRegistry(workingDirectory, {
|
|
153
|
+
surfaceRoot: GOODVIBES_AGENT_SURFACE_ROOT,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
type AgentWrfcWorktreeFactory = NonNullable<ConstructorParameters<typeof WrfcController>[2]['createWorktree']>;
|
|
158
|
+
type AgentWrfcWorktreeOps = ReturnType<AgentWrfcWorktreeFactory>;
|
|
159
|
+
|
|
160
|
+
function agentWrfcWorktreeError(operation: string): Error {
|
|
161
|
+
return new Error(`GoodVibes Agent does not own local review worktree ${operation}. Delegate build, fix, and review work to GoodVibes TUI.`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function createDisabledAgentWrfcWorktreeOps(): AgentWrfcWorktreeOps {
|
|
165
|
+
return {
|
|
166
|
+
async merge(_agentId: string): Promise<boolean> {
|
|
167
|
+
throw agentWrfcWorktreeError('merge');
|
|
168
|
+
},
|
|
169
|
+
async cleanup(_agentId: string): Promise<void> {
|
|
170
|
+
throw agentWrfcWorktreeError('cleanup');
|
|
171
|
+
},
|
|
172
|
+
async commitWorkingTree(_message: string): Promise<string | null> {
|
|
173
|
+
throw agentWrfcWorktreeError('commit');
|
|
174
|
+
},
|
|
175
|
+
async currentHead(): Promise<string | null> {
|
|
176
|
+
return null;
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
116
181
|
function ensureConfiguredModelIsRoutable(providerRegistry: ProviderRegistry, configManager: ConfigManager): void {
|
|
117
182
|
const configuredModel = String(configManager.get('provider.model') ?? '').trim();
|
|
118
183
|
if (!configuredModel.includes(':')) return;
|
|
@@ -254,7 +319,7 @@ export interface RuntimeServicesOptions {
|
|
|
254
319
|
readonly homeDirectory: string;
|
|
255
320
|
}
|
|
256
321
|
|
|
257
|
-
export interface RuntimeServices {
|
|
322
|
+
export interface RuntimeServices extends SdkRuntimeServices {
|
|
258
323
|
readonly workingDirectory: string;
|
|
259
324
|
readonly homeDirectory: string;
|
|
260
325
|
readonly shellPaths: ShellPathService;
|
|
@@ -276,9 +341,10 @@ export interface RuntimeServices {
|
|
|
276
341
|
readonly automationManager: AutomationManager;
|
|
277
342
|
readonly gatewayMethods: GatewayMethodCatalog;
|
|
278
343
|
readonly artifactStore: ArtifactStore;
|
|
279
|
-
/** Compatibility alias that intentionally points at the isolated Agent Knowledge service, not default
|
|
344
|
+
/** Compatibility alias that intentionally points at the isolated Agent Knowledge service, not default knowledge. */
|
|
280
345
|
readonly knowledgeService: KnowledgeService;
|
|
281
346
|
readonly agentKnowledgeService: KnowledgeService;
|
|
347
|
+
readonly homeGraphService: SdkCompanionGraphService;
|
|
282
348
|
readonly projectPlanningService: ProjectPlanningService;
|
|
283
349
|
readonly projectPlanningProjectId: string;
|
|
284
350
|
readonly workPlanStore: WorkPlanStore;
|
|
@@ -345,7 +411,7 @@ export interface RuntimeServices {
|
|
|
345
411
|
* Agent memory is home/profile-owned and intentionally does not move on workspace swap.
|
|
346
412
|
* Called by WorkspaceSwapManager after the new directory has been verified.
|
|
347
413
|
* Stores that require a process restart emit a warn-level log; they continue serving
|
|
348
|
-
* the old path until the
|
|
414
|
+
* the old path until the externally owned GoodVibes host restarts with the new --working-dir.
|
|
349
415
|
*/
|
|
350
416
|
rerootStores(newWorkingDir: string): Promise<void>;
|
|
351
417
|
}
|
|
@@ -443,12 +509,13 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
|
|
|
443
509
|
configManager,
|
|
444
510
|
});
|
|
445
511
|
agentManager.setRuntimeBus(options.runtimeBus);
|
|
446
|
-
const wrfcController =
|
|
512
|
+
const wrfcController = Reflect.construct(WrfcController, [options.runtimeBus, agentMessageBus, {
|
|
447
513
|
agentManager,
|
|
448
514
|
configManager,
|
|
449
515
|
projectRoot: workingDirectory,
|
|
450
|
-
|
|
451
|
-
|
|
516
|
+
surfaceRoot: GOODVIBES_AGENT_SURFACE_ROOT,
|
|
517
|
+
createWorktree: createDisabledAgentWrfcWorktreeOps,
|
|
518
|
+
}]) as WrfcController;
|
|
452
519
|
const hookDispatcher = new HookDispatcher({ toolLLM, projectRoot: workingDirectory }, hookActivityTracker);
|
|
453
520
|
configManager.attachHookDispatcher(hookDispatcher);
|
|
454
521
|
const hookWorkbench = createHookWorkbench({
|
|
@@ -496,7 +563,7 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
|
|
|
496
563
|
deliveryManager,
|
|
497
564
|
spawnTask: (input) => {
|
|
498
565
|
throw new Error([
|
|
499
|
-
'GoodVibes Agent does not spawn local automation agents.',
|
|
566
|
+
'GoodVibes Agent does not create local automation jobs and does not spawn local automation agents.',
|
|
500
567
|
`Received automation prompt: ${input.prompt}`,
|
|
501
568
|
'Use read-only automation observability here; explicit build/fix/review execution belongs to GoodVibes TUI delegation.',
|
|
502
569
|
].join(' '));
|
|
@@ -506,6 +573,10 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
|
|
|
506
573
|
configManager,
|
|
507
574
|
dbFileName: GOODVIBES_AGENT_KNOWLEDGE_DB_FILE,
|
|
508
575
|
});
|
|
576
|
+
const homeGraphKnowledgeStore = new KnowledgeStore({
|
|
577
|
+
configManager,
|
|
578
|
+
dbFileName: HOME_GRAPH_KNOWLEDGE_DB_FILE,
|
|
579
|
+
});
|
|
509
580
|
const knowledgeSemanticLlm = createProviderBackedKnowledgeSemanticLlm(providerRegistry, {
|
|
510
581
|
timeoutMs: 20_000,
|
|
511
582
|
maxConcurrent: 1,
|
|
@@ -514,12 +585,20 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
|
|
|
514
585
|
llm: knowledgeSemanticLlm,
|
|
515
586
|
maxLlmSourcesPerReindex: 3,
|
|
516
587
|
});
|
|
588
|
+
const homeGraphSemanticService = new KnowledgeSemanticService(homeGraphKnowledgeStore, {
|
|
589
|
+
llm: knowledgeSemanticLlm,
|
|
590
|
+
maxLlmSourcesPerReindex: 3,
|
|
591
|
+
objectProfiles: HOME_GRAPH_KNOWLEDGE_EXTENSION.objectProfiles,
|
|
592
|
+
});
|
|
517
593
|
const agentKnowledgeService = new KnowledgeService(agentKnowledgeStore, artifactStore, undefined, {
|
|
518
594
|
memoryRegistry,
|
|
519
595
|
runtimeBus: options.runtimeBus,
|
|
520
596
|
semanticService: agentKnowledgeSemanticService,
|
|
521
597
|
});
|
|
522
598
|
agentKnowledgeService.attachRuntimeBus(options.runtimeBus);
|
|
599
|
+
const homeGraphService = new companionGraphServiceConstructor(homeGraphKnowledgeStore, artifactStore, {
|
|
600
|
+
semanticService: homeGraphSemanticService,
|
|
601
|
+
});
|
|
523
602
|
const projectPlanningProjectId = projectPlanningProjectIdFromPath(workingDirectory);
|
|
524
603
|
const projectPlanningService = new ProjectPlanningService(agentKnowledgeStore, {
|
|
525
604
|
defaultProjectId: projectPlanningProjectId,
|
|
@@ -544,6 +623,10 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
|
|
|
544
623
|
searchService: webSearchService,
|
|
545
624
|
ingestService: agentKnowledgeService,
|
|
546
625
|
}));
|
|
626
|
+
homeGraphSemanticService.setGapRepairer(createWebKnowledgeGapRepairer({
|
|
627
|
+
searchService: webSearchService,
|
|
628
|
+
ingestService: homeGraphService,
|
|
629
|
+
}));
|
|
547
630
|
const mediaProviders = new MediaProviderRegistry();
|
|
548
631
|
ensureBuiltinMediaProviders(mediaProviders, artifactStore, providerRegistry);
|
|
549
632
|
const multimodalService = new MultimodalService(artifactStore, mediaProviders, voiceService, agentKnowledgeService);
|
|
@@ -578,7 +661,7 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
|
|
|
578
661
|
mcpRegistry.setSandboxRuntime(configManager, sandboxSessionRegistry);
|
|
579
662
|
const tokenAuditor = new ApiTokenAuditor({ managed: false });
|
|
580
663
|
const componentHealthMonitor = new ComponentHealthMonitor();
|
|
581
|
-
const worktreeRegistry =
|
|
664
|
+
const worktreeRegistry = createDisabledAgentWorktreeRegistry(workingDirectory);
|
|
582
665
|
const webhookNotifier = new WebhookNotifier();
|
|
583
666
|
const replayEngine = new DeterministicReplayEngine(workingDirectory);
|
|
584
667
|
const providerOptimizer = new ProviderOptimizer(providerRegistry, providerCapabilityRegistry, false);
|
|
@@ -672,6 +755,7 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
|
|
|
672
755
|
artifactStore,
|
|
673
756
|
knowledgeService: agentKnowledgeService,
|
|
674
757
|
agentKnowledgeService,
|
|
758
|
+
homeGraphService,
|
|
675
759
|
projectPlanningService,
|
|
676
760
|
projectPlanningProjectId,
|
|
677
761
|
workPlanStore,
|
|
@@ -53,7 +53,7 @@ export function selectOverlays(state: RuntimeState): OverlayDomainState {
|
|
|
53
53
|
return state.overlays;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
/** Select the full panels domain slice.
|
|
56
|
+
/** Select the full panels domain slice. */
|
|
57
57
|
export function selectPanels(state: RuntimeState): PanelDomainState {
|
|
58
58
|
return state.panels as unknown as PanelDomainState;
|
|
59
59
|
}
|
|
@@ -274,7 +274,7 @@ export function selectPermissionMode(state: RuntimeState): PermissionMode {
|
|
|
274
274
|
*/
|
|
275
275
|
export function selectActivePanels(state: RuntimeState): PanelState[] {
|
|
276
276
|
const result: PanelState[] = [];
|
|
277
|
-
const panelDomain = state
|
|
277
|
+
const panelDomain = selectPanels(state);
|
|
278
278
|
for (const panel of panelDomain.panels.values()) {
|
|
279
279
|
if (panel.open) {
|
|
280
280
|
result.push(panel);
|
|
@@ -287,7 +287,7 @@ export function selectActivePanels(state: RuntimeState): PanelState[] {
|
|
|
287
287
|
* Returns the panel currently holding focus.
|
|
288
288
|
*/
|
|
289
289
|
export function selectFocusedPanel(state: RuntimeState): PanelState | undefined {
|
|
290
|
-
const panelDomain = state
|
|
290
|
+
const panelDomain = selectPanels(state);
|
|
291
291
|
return panelDomain.panels.get(panelDomain.focusedPanelId);
|
|
292
292
|
}
|
|
293
293
|
|
|
@@ -76,10 +76,7 @@ export interface RuntimeState {
|
|
|
76
76
|
model: ModelDomainState;
|
|
77
77
|
conversation: ConversationDomainState;
|
|
78
78
|
overlays: OverlayDomainState;
|
|
79
|
-
/**
|
|
80
|
-
* TUI panel state. Typed as Record<string,unknown> for SDK RuntimeState
|
|
81
|
-
* compatibility. Use selectPanels() which casts to PanelDomainState.
|
|
82
|
-
*/
|
|
79
|
+
/** TUI panel state, exposed through the SDK-compatible runtime store shape. */
|
|
83
80
|
panels: Record<string, unknown>;
|
|
84
81
|
permissions: PermissionDomainState;
|
|
85
82
|
tasks: TaskDomainState;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ConfigManager, PersistedFlagState } from '../config/index.ts';
|
|
2
2
|
import { surfaceFeatureGateId } from '@/runtime/index.ts';
|
|
3
3
|
|
|
4
4
|
export const CONTROL_PLANE_FEATURE_FLAG = 'control-plane-gateway';
|
|
@@ -14,6 +14,42 @@ const CORE_CHANNEL_FEATURE_FLAGS = [
|
|
|
14
14
|
|
|
15
15
|
export type FeatureFlagConfigKey = 'featureFlags' | `featureFlags.${string}`;
|
|
16
16
|
|
|
17
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
18
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function isFeatureFlagConfigKey(key: string): key is FeatureFlagConfigKey {
|
|
22
|
+
return key === 'featureFlags' || key.startsWith('featureFlags.');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isPersistedFlagState(value: unknown): value is PersistedFlagState {
|
|
26
|
+
return value === 'enabled' || value === 'disabled';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function readFeatureFlagConfigValue(config: Pick<ConfigManager, 'getCategory'>, key: FeatureFlagConfigKey): unknown {
|
|
30
|
+
const flags = config.getCategory('featureFlags');
|
|
31
|
+
if (key === 'featureFlags') return flags;
|
|
32
|
+
return flags[key.slice('featureFlags.'.length)];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function mergeFeatureFlagConfigValue(config: Pick<ConfigManager, 'mergeCategory'>, key: FeatureFlagConfigKey, value: unknown): void {
|
|
36
|
+
if (key === 'featureFlags') {
|
|
37
|
+
if (!isRecord(value)) throw new Error('featureFlags expects an object value.');
|
|
38
|
+
const patch: Partial<Record<string, PersistedFlagState>> = {};
|
|
39
|
+
for (const [flagId, state] of Object.entries(value)) {
|
|
40
|
+
if (!isPersistedFlagState(state)) throw new Error(`featureFlags.${flagId} expects enabled or disabled.`);
|
|
41
|
+
patch[flagId] = state;
|
|
42
|
+
}
|
|
43
|
+
config.mergeCategory('featureFlags', patch);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!isPersistedFlagState(value)) throw new Error(`${key} expects enabled or disabled.`);
|
|
48
|
+
config.mergeCategory('featureFlags', {
|
|
49
|
+
[key.slice('featureFlags.'.length)]: value,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
17
53
|
export function getSurfaceFeatureFlag(surfaceId: string): string | null {
|
|
18
54
|
return surfaceFeatureGateId(surfaceId);
|
|
19
55
|
}
|
|
@@ -47,7 +83,7 @@ export function getServerSurfaceFeatureFlags(options: {
|
|
|
47
83
|
}
|
|
48
84
|
|
|
49
85
|
export function isFeatureFlagEnabled(config: Pick<ConfigManager, 'getCategory'>, flagId: string): boolean {
|
|
50
|
-
const flags =
|
|
86
|
+
const flags = config.getCategory('featureFlags');
|
|
51
87
|
return flags[flagId] === 'enabled';
|
|
52
88
|
}
|
|
53
89
|
|
|
@@ -58,8 +94,7 @@ export function getMissingSurfaceFeatureFlags(config: Pick<ConfigManager, 'getCa
|
|
|
58
94
|
return required.filter((flagId) => !isFeatureFlagEnabled(config, flagId));
|
|
59
95
|
}
|
|
60
96
|
|
|
61
|
-
export function enableFeatureFlags(config: Pick<ConfigManager, '
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
97
|
+
export function enableFeatureFlags(config: Pick<ConfigManager, 'mergeCategory'>, flagIds: readonly string[]): void {
|
|
98
|
+
const patch = Object.fromEntries(flagIds.map((flagId) => [flagId, 'enabled'] as const));
|
|
99
|
+
config.mergeCategory('featureFlags', patch);
|
|
65
100
|
}
|
|
@@ -53,10 +53,9 @@ export function createUiReadModels(
|
|
|
53
53
|
runtimeServices: RuntimeServices,
|
|
54
54
|
options: UiReadModelOptions = {},
|
|
55
55
|
): UiReadModels {
|
|
56
|
-
const sdkRuntimeServices = runtimeServices as unknown as Parameters<typeof createCoreReadModels>[0];
|
|
57
56
|
return {
|
|
58
|
-
...createCoreReadModels(
|
|
59
|
-
...createOperationsReadModels(
|
|
60
|
-
...createObservabilityReadModels(
|
|
57
|
+
...createCoreReadModels(runtimeServices),
|
|
58
|
+
...createOperationsReadModels(runtimeServices, options),
|
|
59
|
+
...createObservabilityReadModels(runtimeServices, options),
|
|
61
60
|
};
|
|
62
61
|
}
|