@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
|
@@ -3,6 +3,7 @@ import { dirname } from 'node:path';
|
|
|
3
3
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
4
4
|
import { listBuiltinSubscriptionProviders } from '@pellux/goodvibes-sdk/platform/config';
|
|
5
5
|
import { buildAuthInspectionSnapshot, inspectProviderAuth } from '@/runtime/index.ts';
|
|
6
|
+
import { formatAgentRecordSource } from '../../agent/record-labels.ts';
|
|
6
7
|
import { requireSecretsManager, requireServiceRegistry, requireShellPaths, requireSubscriptionManager } from './runtime-services.ts';
|
|
7
8
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
8
9
|
|
|
@@ -18,78 +19,15 @@ interface AuthReviewBundle {
|
|
|
18
19
|
function inspectAuthBundle(bundle: AuthReviewBundle): string {
|
|
19
20
|
return [
|
|
20
21
|
'Auth Review Bundle',
|
|
21
|
-
`
|
|
22
|
-
`
|
|
23
|
-
` stored secrets
|
|
24
|
-
` active subscriptions
|
|
25
|
-
` pending subscriptions
|
|
22
|
+
` exported at ${new Date(bundle.exportedAt).toISOString()}`,
|
|
23
|
+
` connected host auth ${bundle.externalRuntimeAuth}`,
|
|
24
|
+
` stored secrets ${bundle.secretKeys.length}`,
|
|
25
|
+
` active subscriptions ${bundle.activeSubscriptions.length}`,
|
|
26
|
+
` pending subscriptions ${bundle.pendingSubscriptions.length}`,
|
|
26
27
|
].join('\n');
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry): void {
|
|
30
|
-
registry.register({
|
|
31
|
-
name: 'login',
|
|
32
|
-
description: 'Front-door login flow for provider subscriptions',
|
|
33
|
-
usage: 'provider <name> start|finish <code> --yes',
|
|
34
|
-
async handler(args, ctx) {
|
|
35
|
-
const parsed = stripYesFlag(args);
|
|
36
|
-
const commandArgs = [...parsed.rest];
|
|
37
|
-
const target = (commandArgs[0] ?? '').toLowerCase();
|
|
38
|
-
if (target === 'provider') {
|
|
39
|
-
const provider = commandArgs[1];
|
|
40
|
-
const mode = commandArgs[2]?.toLowerCase();
|
|
41
|
-
if (!provider || !mode) {
|
|
42
|
-
ctx.print('Usage: /login provider <name> start|finish <code> --yes');
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
if (!parsed.yes) {
|
|
46
|
-
requireYesFlag(ctx, `${mode} provider subscription login for ${provider}`, '/login provider <name> start|finish <code> --yes');
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (ctx.executeCommand) {
|
|
50
|
-
await ctx.executeCommand('subscription', ['login', provider, mode, ...commandArgs.slice(3), '--yes']);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
ctx.print(`Use /subscription login ${provider} ${mode}${commandArgs[3] ? ` ${commandArgs[3]}` : ''} --yes`);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
if (target === 'service' || target === 'runtime' || target === 'listener' || target === 'daemon') {
|
|
57
|
-
ctx.print([
|
|
58
|
-
'Connected-service login is outside GoodVibes Agent.',
|
|
59
|
-
'Agent does not create, exchange, store, rotate, revoke, or clear connected-service sessions.',
|
|
60
|
-
'Use the owning GoodVibes host for connected-service auth administration.',
|
|
61
|
-
'Agent login supports provider subscriptions only: /login provider <name> start|finish <code> --yes.',
|
|
62
|
-
].join('\n'));
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
ctx.print('Usage: /login provider <name> start|finish <code> --yes');
|
|
66
|
-
},
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
registry.register({
|
|
70
|
-
name: 'logout',
|
|
71
|
-
description: 'Front-door logout flow for provider subscription sessions and supported overrides',
|
|
72
|
-
usage: 'provider <name> --yes',
|
|
73
|
-
async handler(args, ctx) {
|
|
74
|
-
const parsed = stripYesFlag(args);
|
|
75
|
-
const commandArgs = [...parsed.rest];
|
|
76
|
-
const target = (commandArgs[0] ?? '').toLowerCase();
|
|
77
|
-
if (target !== 'provider' || !commandArgs[1]) {
|
|
78
|
-
ctx.print('Usage: /logout provider <name> --yes');
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
if (!parsed.yes) {
|
|
82
|
-
requireYesFlag(ctx, `log out provider subscription ${commandArgs[1]}`, '/logout provider <name> --yes');
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (ctx.executeCommand) {
|
|
86
|
-
await ctx.executeCommand('subscription', ['logout', commandArgs[1], '--yes']);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
ctx.print(`Use /subscription logout ${commandArgs[1]} --yes`);
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
|
|
93
31
|
registry.register({
|
|
94
32
|
name: 'auth',
|
|
95
33
|
description: 'Review provider auth posture and export redacted auth review bundles',
|
|
@@ -100,18 +38,18 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
100
38
|
const sub = commandArgs[0] ?? 'review';
|
|
101
39
|
if (sub === 'local') {
|
|
102
40
|
ctx.print([
|
|
103
|
-
'Connected-
|
|
104
|
-
'Agent connects to GoodVibes
|
|
105
|
-
'Use the owning GoodVibes host for connected-
|
|
41
|
+
'Connected-host auth management is outside GoodVibes Agent.',
|
|
42
|
+
'Agent connects to a GoodVibes host owned outside this package and does not create, delete, rotate, revoke, or clear connected-host auth users, sessions, or bootstrap credentials.',
|
|
43
|
+
'Use the owning GoodVibes host for connected-host auth administration.',
|
|
106
44
|
'Agent auth commands available here: /auth review, /auth show <provider>, /auth repair <provider>, /auth bundle export <path> --yes, /auth bundle inspect <path>.',
|
|
107
45
|
].join('\n'));
|
|
108
46
|
return;
|
|
109
47
|
}
|
|
110
48
|
if (sub === 'login') {
|
|
111
49
|
ctx.print([
|
|
112
|
-
'Connected-
|
|
113
|
-
'Agent does not create, exchange, store, rotate, revoke, or clear connected-
|
|
114
|
-
'Use the owning GoodVibes host for connected-
|
|
50
|
+
'Connected-host login is outside GoodVibes Agent.',
|
|
51
|
+
'Agent does not create, exchange, store, rotate, revoke, or clear connected-host sessions.',
|
|
52
|
+
'Use the owning GoodVibes host for connected-host auth administration.',
|
|
115
53
|
].join('\n'));
|
|
116
54
|
return;
|
|
117
55
|
}
|
|
@@ -129,12 +67,12 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
129
67
|
const builtinProviders = listBuiltinSubscriptionProviders().map((entry) => entry.provider);
|
|
130
68
|
ctx.print([
|
|
131
69
|
'Auth Review',
|
|
132
|
-
' connected
|
|
133
|
-
` stored secrets
|
|
134
|
-
` built-in providers
|
|
135
|
-
` active subscriptions
|
|
136
|
-
` pending subscriptions
|
|
137
|
-
...snapshot.providers.map((provider) => ` ${provider.provider}
|
|
70
|
+
' connected host auth managed outside goodvibes-agent',
|
|
71
|
+
` stored secrets ${snapshot.secretKeyCount}`,
|
|
72
|
+
` built-in providers ${builtinProviders.length}${builtinProviders.length > 0 ? ` (${builtinProviders.join(', ')})` : ''}`,
|
|
73
|
+
` active subscriptions ${snapshot.activeSubscriptions}${snapshot.activeSubscriptions > 0 ? ` (${snapshot.providers.filter((provider) => provider.activeSubscription).map((provider) => provider.provider).join(', ')})` : ''}`,
|
|
74
|
+
` pending subscriptions ${snapshot.pendingSubscriptions}${snapshot.pendingSubscriptions > 0 ? ` (${snapshot.providers.filter((provider) => provider.pendingLogin).map((provider) => provider.provider).join(', ')})` : ''}`,
|
|
75
|
+
...snapshot.providers.map((provider) => ` ${provider.provider} auth ${provider.freshness} finish manual configured ${provider.configured ? 'yes' : 'no'}`),
|
|
138
76
|
].join('\n'));
|
|
139
77
|
return;
|
|
140
78
|
}
|
|
@@ -152,19 +90,18 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
152
90
|
});
|
|
153
91
|
ctx.print([
|
|
154
92
|
`Auth Provider ${provider}`,
|
|
155
|
-
` configured
|
|
156
|
-
...(inspection.source ? [`
|
|
157
|
-
` freshness
|
|
158
|
-
|
|
159
|
-
...(inspection.redirectUri ? [`
|
|
160
|
-
|
|
161
|
-
`
|
|
162
|
-
`
|
|
163
|
-
`
|
|
164
|
-
...(inspection.
|
|
165
|
-
...
|
|
166
|
-
...inspection.
|
|
167
|
-
...inspection.nextActions.map((action) => ` next: ${action}`),
|
|
93
|
+
` configured ${inspection.configured ? 'yes' : 'no'}`,
|
|
94
|
+
...(inspection.source ? [` origin ${formatAgentRecordSource(inspection.source)}`] : []),
|
|
95
|
+
` freshness ${inspection.freshness}`,
|
|
96
|
+
' finish mode explicit manual',
|
|
97
|
+
...(inspection.redirectUri ? [` redirect URI ${inspection.redirectUri}`] : []),
|
|
98
|
+
` active subscription ${inspection.activeSubscription ? 'yes' : 'no'}`,
|
|
99
|
+
` pending login ${inspection.pendingLogin ? 'yes' : 'no'}`,
|
|
100
|
+
` ambient API key override ${inspection.overrideAmbientApiKeys ? 'yes' : 'no'}`,
|
|
101
|
+
...(inspection.tokenType ? [` token type ${inspection.tokenType}`] : []),
|
|
102
|
+
...(inspection.expiresAt ? [` expires at ${new Date(inspection.expiresAt).toISOString()}`] : []),
|
|
103
|
+
...inspection.issues.map((issue) => ` issue ${issue}`),
|
|
104
|
+
...inspection.nextActions.map((action) => ` next ${action}`),
|
|
168
105
|
].join('\n'));
|
|
169
106
|
return;
|
|
170
107
|
}
|
|
@@ -182,12 +119,12 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
182
119
|
});
|
|
183
120
|
ctx.print([
|
|
184
121
|
`Auth Repair ${provider}`,
|
|
185
|
-
` configured
|
|
186
|
-
` freshness
|
|
187
|
-
|
|
188
|
-
...inspection.issues.map((issue) => ` issue
|
|
122
|
+
` configured ${inspection.configured ? 'yes' : 'no'}`,
|
|
123
|
+
` freshness ${inspection.freshness}`,
|
|
124
|
+
' finish mode explicit manual',
|
|
125
|
+
...inspection.issues.map((issue) => ` issue ${issue}`),
|
|
189
126
|
...(inspection.nextActions.length > 0
|
|
190
|
-
? [' next
|
|
127
|
+
? [' next', ...inspection.nextActions.map((action) => ` ${action}`)]
|
|
191
128
|
: [' No active repair actions suggested.']),
|
|
192
129
|
].join('\n'));
|
|
193
130
|
return;
|
|
@@ -68,7 +68,7 @@ function formatTrustReview(bundle: TrustReviewBundle): string {
|
|
|
68
68
|
'Trust Review',
|
|
69
69
|
` permission mode: ${bundle.permissionMode}`,
|
|
70
70
|
` secrets stored: ${bundle.secretKeys.length}`,
|
|
71
|
-
` configured
|
|
71
|
+
` configured integrations: ${bundle.serviceNames.length}`,
|
|
72
72
|
` plugins: ${bundle.pluginSummary.total} (trusted ${bundle.pluginSummary.trusted}, limited ${bundle.pluginSummary.limited}, untrusted ${bundle.pluginSummary.untrusted}, quarantined ${bundle.pluginSummary.quarantined})`,
|
|
73
73
|
` MCP servers: ${bundle.mcpSummary.total} (constrained ${bundle.mcpSummary.constrained}, ask-on-risk ${bundle.mcpSummary.askOnRisk}, allow-all ${bundle.mcpSummary.allowAll}, blocked ${bundle.mcpSummary.blocked}, quarantined ${bundle.mcpSummary.quarantined})`,
|
|
74
74
|
].join('\n');
|
|
@@ -81,7 +81,7 @@ function inspectTrustBundle(path: string): string {
|
|
|
81
81
|
` captured: ${new Date(parsed.capturedAt).toISOString()}`,
|
|
82
82
|
` permission mode: ${parsed.permissionMode}`,
|
|
83
83
|
` secrets stored: ${parsed.secretKeys.length}`,
|
|
84
|
-
` configured
|
|
84
|
+
` configured integrations: ${parsed.serviceNames.length}`,
|
|
85
85
|
` plugins: ${parsed.pluginSummary.total}`,
|
|
86
86
|
` MCP servers: ${parsed.mcpSummary.total}`,
|
|
87
87
|
].join('\n');
|
|
@@ -2,13 +2,34 @@ import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
|
2
2
|
import type {
|
|
3
3
|
ProviderAccountRecord,
|
|
4
4
|
ProviderAccountSnapshot,
|
|
5
|
-
|
|
5
|
+
ProviderAuthRoute,
|
|
6
|
+
ProviderRouteRecord,
|
|
7
|
+
} from '../../panels/provider-account-snapshot.ts';
|
|
8
|
+
import { buildProviderAccountSnapshot } from '../../panels/provider-account-snapshot.ts';
|
|
6
9
|
import {
|
|
7
|
-
|
|
10
|
+
requireProvider,
|
|
11
|
+
requireServiceRegistry,
|
|
12
|
+
requireSubscriptionManager,
|
|
8
13
|
} from './runtime-services.ts';
|
|
14
|
+
import { formatProviderAuthRouteId } from '../../provider-auth-route-display.ts';
|
|
15
|
+
|
|
16
|
+
function formatRouteList(routes: readonly ProviderAuthRoute[]): string {
|
|
17
|
+
return routes.map((route) => formatProviderAuthRouteId(route)).join(', ');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function formatRouteRecord(route: ProviderRouteRecord): string {
|
|
21
|
+
return `${formatProviderAuthRouteId(route.route)} ${route.usable ? 'usable' : 'blocked'} auth ${route.freshness} ${route.detail}`;
|
|
22
|
+
}
|
|
9
23
|
|
|
10
24
|
async function loadProviderAccountSnapshot(context: CommandContext): Promise<ProviderAccountSnapshot> {
|
|
11
|
-
return await
|
|
25
|
+
return await buildProviderAccountSnapshot({
|
|
26
|
+
providerModels: requireProvider(context).providerRegistry,
|
|
27
|
+
services: requireServiceRegistry(context),
|
|
28
|
+
subscriptions: requireSubscriptionManager(context),
|
|
29
|
+
environment: {
|
|
30
|
+
hasEnvironmentVariable: (name: string) => Boolean(process.env[name]),
|
|
31
|
+
},
|
|
32
|
+
});
|
|
12
33
|
}
|
|
13
34
|
|
|
14
35
|
function findProviderAccountRecord(
|
|
@@ -28,7 +49,7 @@ export function registerProviderAccountsRuntimeCommands(registry: CommandRegistr
|
|
|
28
49
|
async handler(args, ctx) {
|
|
29
50
|
const sub = (args[0] ?? 'review').toLowerCase();
|
|
30
51
|
if (sub === 'panel' || sub === 'open') {
|
|
31
|
-
ctx.print('
|
|
52
|
+
ctx.print('Open Agent Workspace -> Setup -> Provider accounts for the workspace view, or run /accounts review for compact command output.');
|
|
32
53
|
return;
|
|
33
54
|
}
|
|
34
55
|
const snapshot = await loadProviderAccountSnapshot(ctx);
|
|
@@ -36,16 +57,16 @@ export function registerProviderAccountsRuntimeCommands(registry: CommandRegistr
|
|
|
36
57
|
const providerId = args[1];
|
|
37
58
|
const record = findProviderAccountRecord(snapshot, providerId);
|
|
38
59
|
if (!record) {
|
|
39
|
-
ctx.print(providerId ? `Unknown provider account
|
|
60
|
+
ctx.print(providerId ? `Unknown provider account ${providerId}` : 'Usage: /accounts routes <provider>');
|
|
40
61
|
return;
|
|
41
62
|
}
|
|
42
63
|
ctx.print([
|
|
43
64
|
`Provider Routes ${record.providerId}`,
|
|
44
|
-
` preferred
|
|
45
|
-
` active
|
|
46
|
-
` reason
|
|
47
|
-
...record.routeRecords.map((route) => ` ${route
|
|
48
|
-
...record.routeRecords.flatMap((route) => route.issues.map((issue) => ` issue
|
|
65
|
+
` preferred route ${formatProviderAuthRouteId(record.preferredRoute)}`,
|
|
66
|
+
` active route ${formatProviderAuthRouteId(record.activeRoute)}`,
|
|
67
|
+
` reason ${record.activeRouteReason}`,
|
|
68
|
+
...record.routeRecords.map((route) => ` ${formatRouteRecord(route)}`),
|
|
69
|
+
...record.routeRecords.flatMap((route) => route.issues.map((issue) => ` issue ${issue}`)),
|
|
49
70
|
].join('\n'));
|
|
50
71
|
return;
|
|
51
72
|
}
|
|
@@ -53,17 +74,17 @@ export function registerProviderAccountsRuntimeCommands(registry: CommandRegistr
|
|
|
53
74
|
const providerId = args[1];
|
|
54
75
|
const record = findProviderAccountRecord(snapshot, providerId);
|
|
55
76
|
if (!record) {
|
|
56
|
-
ctx.print(providerId ? `Unknown provider account
|
|
77
|
+
ctx.print(providerId ? `Unknown provider account ${providerId}` : 'Usage: /accounts repair <provider>');
|
|
57
78
|
return;
|
|
58
79
|
}
|
|
59
80
|
ctx.print([
|
|
60
81
|
`Provider Account Repair ${record.providerId}`,
|
|
61
|
-
` active route
|
|
62
|
-
` preferred route
|
|
63
|
-
...(record.fallbackRisk ? [`
|
|
64
|
-
...(record.issues.map((issue) => ` issue
|
|
82
|
+
` active route ${formatProviderAuthRouteId(record.activeRoute)}`,
|
|
83
|
+
` preferred route ${formatProviderAuthRouteId(record.preferredRoute)}`,
|
|
84
|
+
...(record.fallbackRisk ? [` routing risk ${record.fallbackRisk}`] : []),
|
|
85
|
+
...(record.issues.map((issue) => ` issue ${issue}`)),
|
|
65
86
|
...(record.recommendedActions.length > 0
|
|
66
|
-
? [' next
|
|
87
|
+
? [' next', ...record.recommendedActions.map((action) => ` ${action}`)]
|
|
67
88
|
: [' No active repair actions suggested.']),
|
|
68
89
|
].join('\n'));
|
|
69
90
|
return;
|
|
@@ -72,39 +93,39 @@ export function registerProviderAccountsRuntimeCommands(registry: CommandRegistr
|
|
|
72
93
|
const providerId = args[1];
|
|
73
94
|
const record = findProviderAccountRecord(snapshot, providerId);
|
|
74
95
|
if (!record) {
|
|
75
|
-
ctx.print(providerId ? `Unknown provider account
|
|
96
|
+
ctx.print(providerId ? `Unknown provider account ${providerId}` : 'Usage: /accounts show <provider>');
|
|
76
97
|
return;
|
|
77
98
|
}
|
|
78
99
|
ctx.print([
|
|
79
100
|
`Provider Account ${record.providerId}`,
|
|
80
|
-
`
|
|
81
|
-
`
|
|
82
|
-
`
|
|
83
|
-
` configured
|
|
84
|
-
`
|
|
85
|
-
`
|
|
86
|
-
`
|
|
87
|
-
`
|
|
88
|
-
`
|
|
89
|
-
...(record.fallbackRoute ? [`
|
|
90
|
-
...(record.fallbackRisk ? [`
|
|
91
|
-
...(record.expiresAt ? [`
|
|
92
|
-
...record.routeRecords.map((route) => ` route ${route
|
|
93
|
-
...record.routeRecords.flatMap((route) => route.issues.map((issue) => ` issue
|
|
94
|
-
...record.usageWindows.map((entry) => ` window
|
|
95
|
-
...record.issues.map((issue) => ` issue
|
|
96
|
-
...record.notes.map((note) => ` note
|
|
97
|
-
...record.recommendedActions.map((action) => ` next
|
|
101
|
+
` preferred route ${formatProviderAuthRouteId(record.preferredRoute)}`,
|
|
102
|
+
` active route ${formatProviderAuthRouteId(record.activeRoute)}`,
|
|
103
|
+
` auth freshness ${record.authFreshness}`,
|
|
104
|
+
` configured ${record.configured ? 'yes' : 'no'}`,
|
|
105
|
+
` OAuth ready ${record.oauthReady ? 'yes' : 'no'}`,
|
|
106
|
+
` pending login ${record.pendingLogin ? 'yes' : 'no'}`,
|
|
107
|
+
` available routes ${formatRouteList(record.availableRoutes)}`,
|
|
108
|
+
` model count ${record.modelCount}`,
|
|
109
|
+
` route reason ${record.activeRouteReason}`,
|
|
110
|
+
...(record.fallbackRoute ? [` fallback route ${formatProviderAuthRouteId(record.fallbackRoute)}`] : []),
|
|
111
|
+
...(record.fallbackRisk ? [` routing risk ${record.fallbackRisk}`] : []),
|
|
112
|
+
...(record.expiresAt ? [` expires at ${new Date(record.expiresAt).toISOString()}`] : []),
|
|
113
|
+
...record.routeRecords.map((route) => ` route ${formatRouteRecord(route)}`),
|
|
114
|
+
...record.routeRecords.flatMap((route) => route.issues.map((issue) => ` issue ${issue}`)),
|
|
115
|
+
...record.usageWindows.map((entry) => ` window ${entry.label} — ${entry.detail}`),
|
|
116
|
+
...record.issues.map((issue) => ` issue ${issue}`),
|
|
117
|
+
...record.notes.map((note) => ` note ${note}`),
|
|
118
|
+
...record.recommendedActions.map((action) => ` next ${action}`),
|
|
98
119
|
].join('\n'));
|
|
99
120
|
return;
|
|
100
121
|
}
|
|
101
122
|
ctx.print([
|
|
102
123
|
'Provider Account Review',
|
|
103
|
-
` providers
|
|
104
|
-
` configured
|
|
105
|
-
` issues
|
|
124
|
+
` providers ${snapshot.providers.length}`,
|
|
125
|
+
` configured ${snapshot.configuredCount}`,
|
|
126
|
+
` issues ${snapshot.issueCount}`,
|
|
106
127
|
...snapshot.providers.map((record) => (
|
|
107
|
-
` ${record.providerId} active
|
|
128
|
+
` ${record.providerId} active route ${formatProviderAuthRouteId(record.activeRoute)} preferred route ${formatProviderAuthRouteId(record.preferredRoute)} auth ${record.authFreshness} models ${record.modelCount} issues ${record.issues.length}`
|
|
108
129
|
)),
|
|
109
130
|
].join('\n'));
|
|
110
131
|
},
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
2
|
import { networkInterfaces } from 'node:os';
|
|
4
3
|
import {
|
|
5
4
|
buildCompanionConnectionInfo,
|
|
5
|
+
type CompanionConnectionInfo,
|
|
6
6
|
encodeConnectionPayload,
|
|
7
|
-
formatConnectionBlock,
|
|
8
7
|
generateQrMatrix,
|
|
9
|
-
getOrCreateCompanionToken,
|
|
10
8
|
renderQrToString,
|
|
11
9
|
} from '@pellux/goodvibes-sdk/platform/pairing';
|
|
12
10
|
import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../../config/surface.ts';
|
|
13
11
|
import { resolveRuntimeEndpointBinding } from '../../cli/endpoints.ts';
|
|
12
|
+
import { connectedHostOperatorTokenFingerprint, connectedHostTokenRequiredMessage, readConnectedHostOperatorToken } from '../../runtime/connected-host-auth.ts';
|
|
14
13
|
import { requirePlatform, requireShellPaths } from './runtime-services.ts';
|
|
15
14
|
|
|
16
15
|
function getLocalNetworkIp(): string {
|
|
@@ -32,28 +31,70 @@ function urlHostForBindHost(host: string): string {
|
|
|
32
31
|
return host || '127.0.0.1';
|
|
33
32
|
}
|
|
34
33
|
|
|
34
|
+
function formatTokenLine(token: string, showToken: boolean): string {
|
|
35
|
+
if (showToken) return `Token: ${token}`;
|
|
36
|
+
return `Token: present sha256:${connectedHostOperatorTokenFingerprint(token)} (hidden in text; QR contains pairing payload)`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function formatAgentPairingBlock(info: CompanionConnectionInfo, qr: string, showToken: boolean): string {
|
|
40
|
+
return [
|
|
41
|
+
`GoodVibes Agent companion pairing v${info.version}`,
|
|
42
|
+
'━━━━━━━━━━━━━━━━━━━━━━━━',
|
|
43
|
+
`Connected host: ${info.url}`,
|
|
44
|
+
`Surface: ${info.surface}`,
|
|
45
|
+
`User: ${info.username}`,
|
|
46
|
+
formatTokenLine(info.token, showToken),
|
|
47
|
+
'',
|
|
48
|
+
'Scan to connect:',
|
|
49
|
+
'',
|
|
50
|
+
qr,
|
|
51
|
+
'',
|
|
52
|
+
showToken
|
|
53
|
+
? 'Manual token display was explicitly confirmed for this command.'
|
|
54
|
+
: 'For manual setup, rerun /pair --show-token --yes to print the token once.',
|
|
55
|
+
'Agent is waiting for the companion app to connect to the owning GoodVibes host.',
|
|
56
|
+
].join('\n');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function shouldShowToken(args: readonly string[]): boolean {
|
|
60
|
+
return args.includes('--show-token') || args.includes('--manual-token');
|
|
61
|
+
}
|
|
62
|
+
|
|
35
63
|
export function registerQrcodeRuntimeCommands(registry: CommandRegistry): void {
|
|
36
64
|
registry.register({
|
|
37
65
|
name: 'qrcode',
|
|
38
66
|
aliases: ['qr', 'pair'],
|
|
39
67
|
description: 'Print companion pairing details and a QR code',
|
|
40
68
|
usage: '',
|
|
41
|
-
handler(
|
|
69
|
+
handler(args, ctx) {
|
|
42
70
|
const shellPaths = requireShellPaths(ctx);
|
|
43
71
|
const configManager = requirePlatform(ctx).configManager;
|
|
44
|
-
const
|
|
45
|
-
|
|
72
|
+
const tokenRecord = readConnectedHostOperatorToken(shellPaths.homeDirectory);
|
|
73
|
+
if (!tokenRecord.token) {
|
|
74
|
+
ctx.print(connectedHostTokenRequiredMessage(tokenRecord.path));
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
46
77
|
const binding = resolveRuntimeEndpointBinding(configManager, 'controlPlane');
|
|
47
|
-
const
|
|
78
|
+
const connectedHostUrl = `http://${urlHostForBindHost(binding.host)}:${binding.port}`;
|
|
48
79
|
const info = buildCompanionConnectionInfo({
|
|
49
|
-
daemonUrl,
|
|
80
|
+
daemonUrl: connectedHostUrl,
|
|
50
81
|
token: tokenRecord.token,
|
|
51
82
|
username: 'admin',
|
|
52
83
|
surface: GOODVIBES_AGENT_PAIRING_SURFACE,
|
|
53
84
|
});
|
|
54
85
|
const payload = encodeConnectionPayload(info);
|
|
55
86
|
const qr = renderQrToString(generateQrMatrix(payload));
|
|
56
|
-
|
|
87
|
+
const showToken = shouldShowToken(args);
|
|
88
|
+
if (showToken && !args.includes('--yes')) {
|
|
89
|
+
ctx.print([
|
|
90
|
+
'Manual companion token display requires confirmation.',
|
|
91
|
+
' rerun: /pair --show-token --yes',
|
|
92
|
+
` token fingerprint: sha256:${connectedHostOperatorTokenFingerprint(tokenRecord.token)}`,
|
|
93
|
+
' QR pairing remains available without printing the raw token.',
|
|
94
|
+
].join('\n'));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
ctx.print(formatAgentPairingBlock(info, qr, showToken));
|
|
57
98
|
},
|
|
58
99
|
});
|
|
59
100
|
}
|
|
@@ -31,7 +31,7 @@ export function handleRecallExport(args: string[], context: CommandContext): voi
|
|
|
31
31
|
if (scopeIdx !== -1 && commandArgs[scopeIdx + 1]) {
|
|
32
32
|
const scope = commandArgs[scopeIdx + 1];
|
|
33
33
|
if (!isValidScope(scope)) {
|
|
34
|
-
context.print(`[memory] Unknown scope "${scope}". Valid
|
|
34
|
+
context.print(`[memory] Unknown scope "${scope}". Valid values ${VALID_SCOPES.join(', ')}.`);
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
filter.scope = scope;
|
|
@@ -41,7 +41,7 @@ export function handleRecallExport(args: string[], context: CommandContext): voi
|
|
|
41
41
|
if (clsIdx !== -1 && commandArgs[clsIdx + 1]) {
|
|
42
42
|
const cls = commandArgs[clsIdx + 1];
|
|
43
43
|
if (!isValidClass(cls)) {
|
|
44
|
-
context.print(`[memory] Unknown class "${cls}". Valid
|
|
44
|
+
context.print(`[memory] Unknown class "${cls}". Valid values ${VALID_CLASSES.join(', ')}.`);
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
filter.cls = cls;
|
|
@@ -77,23 +77,23 @@ export async function handleRecallImport(args: string[], context: CommandContext
|
|
|
77
77
|
try {
|
|
78
78
|
bundle = JSON.parse(readFileSync(targetPath, 'utf-8')) as MemoryBundle;
|
|
79
79
|
} catch (error) {
|
|
80
|
-
context.print(`[memory] Failed to read memory bundle
|
|
80
|
+
context.print(`[memory] Failed to read memory bundle ${summarizeError(error)}`);
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
const result = await memory.importBundle(bundle);
|
|
85
85
|
context.print(`[memory] Imported bundle from ${targetPath}`);
|
|
86
|
-
context.print(`
|
|
87
|
-
context.print(`
|
|
86
|
+
context.print(` records imported=${result.importedRecords} skipped=${result.skippedRecords}`);
|
|
87
|
+
context.print(` links imported=${result.importedLinks}`);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
function inspectBundle(bundle: MemoryBundle): string {
|
|
91
91
|
return [
|
|
92
92
|
'Memory Handoff Review',
|
|
93
|
-
` scope
|
|
94
|
-
` records
|
|
95
|
-
` links
|
|
96
|
-
` exportedAt
|
|
93
|
+
` scope ${bundle.scope}`,
|
|
94
|
+
` records ${bundle.recordCount}`,
|
|
95
|
+
` links ${bundle.linkCount}`,
|
|
96
|
+
` exportedAt ${new Date(bundle.exportedAt).toISOString()}`,
|
|
97
97
|
].join('\n');
|
|
98
98
|
}
|
|
99
99
|
|
|
@@ -116,7 +116,7 @@ export function handleRecallHandoffExport(args: string[], context: CommandContex
|
|
|
116
116
|
const scopeIdx = commandArgs.indexOf('--scope');
|
|
117
117
|
const scopeRaw = scopeIdx !== -1 ? commandArgs[scopeIdx + 1] : 'team';
|
|
118
118
|
if (!scopeRaw || !isValidScope(scopeRaw)) {
|
|
119
|
-
context.print(`[memory] Unknown scope "${scopeRaw ?? ''}". Valid
|
|
119
|
+
context.print(`[memory] Unknown scope "${scopeRaw ?? ''}". Valid values ${VALID_SCOPES.join(', ')}.`);
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
122
|
const bundle = memory.exportBundle({ scope: scopeRaw });
|
|
@@ -137,7 +137,7 @@ export function handleRecallHandoffInspect(args: string[], context: CommandConte
|
|
|
137
137
|
const bundle = JSON.parse(readFileSync(targetPath, 'utf-8')) as MemoryBundle;
|
|
138
138
|
context.print(inspectBundle(bundle));
|
|
139
139
|
} catch (error) {
|
|
140
|
-
context.print(`[memory] Failed to inspect handoff bundle
|
|
140
|
+
context.print(`[memory] Failed to inspect handoff bundle ${summarizeError(error)}`);
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CommandContext } from '../command-registry.ts';
|
|
2
2
|
import type { ProvenanceLink } from '@pellux/goodvibes-sdk/platform/state';
|
|
3
|
+
import { formatAgentRecordReferences } from '../../agent/record-labels.ts';
|
|
3
4
|
import {
|
|
4
5
|
buildIncidentMemoryAddOptions,
|
|
5
6
|
buildMcpSecurityMemoryAddOptions,
|
|
@@ -17,7 +18,7 @@ export async function handleRecallAdd(args: string[], context: CommandContext):
|
|
|
17
18
|
|
|
18
19
|
const cls = args[0];
|
|
19
20
|
if (!cls || !isValidClass(cls)) {
|
|
20
|
-
context.print(`[memory] Invalid class "${cls ?? ''}". Valid
|
|
21
|
+
context.print(`[memory] Invalid class "${cls ?? ''}". Valid values ${VALID_CLASSES.join(', ')}.`);
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -36,7 +37,7 @@ export async function handleRecallAdd(args: string[], context: CommandContext):
|
|
|
36
37
|
const scope = scopeRaw && isValidScope(scopeRaw) ? scopeRaw : 'project';
|
|
37
38
|
|
|
38
39
|
if (scopeRaw && !isValidScope(scopeRaw)) {
|
|
39
|
-
context.print(`[memory] Invalid scope "${scopeRaw}". Valid
|
|
40
|
+
context.print(`[memory] Invalid scope "${scopeRaw}". Valid values ${VALID_SCOPES.join(', ')}.`);
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -60,12 +61,13 @@ export async function handleRecallAdd(args: string[], context: CommandContext):
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
const record = await memory.add({ scope, cls, summary, detail, tags, provenance });
|
|
63
|
-
context.print(`[memory] Added ${cls}
|
|
64
|
-
context.print(`
|
|
65
|
-
context.print(`
|
|
66
|
-
|
|
64
|
+
context.print(`[memory] Added ${cls}`);
|
|
65
|
+
context.print(` id ${record.id}`);
|
|
66
|
+
context.print(` scope ${record.scope}`);
|
|
67
|
+
context.print(` summary ${record.summary}`);
|
|
68
|
+
if (record.tags.length) context.print(` tags ${record.tags.join(', ')}`);
|
|
67
69
|
if (record.provenance.length) {
|
|
68
|
-
context.print(`
|
|
70
|
+
context.print(` origin ${formatAgentRecordReferences(record.provenance)}`);
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
|
|
@@ -87,12 +89,12 @@ export async function handleRecallCapture(args: string[], context: CommandContex
|
|
|
87
89
|
? context.extensions.forensicsRegistry.latest()
|
|
88
90
|
: context.extensions.forensicsRegistry.getById(requestedId);
|
|
89
91
|
if (!report) {
|
|
90
|
-
context.print(`[memory] Incident not found
|
|
92
|
+
context.print(`[memory] Incident not found ${requestedId ?? 'latest'}`);
|
|
91
93
|
return;
|
|
92
94
|
}
|
|
93
95
|
const bundle = context.extensions.forensicsRegistry.buildBundle(report.id);
|
|
94
96
|
if (!bundle) {
|
|
95
|
-
context.print(`[memory] Failed to build incident bundle
|
|
97
|
+
context.print(`[memory] Failed to build incident bundle ${report.id}`);
|
|
96
98
|
return;
|
|
97
99
|
}
|
|
98
100
|
const record = await memory.add(buildIncidentMemoryAddOptions(bundle));
|
|
@@ -119,7 +121,7 @@ export async function handleRecallCapture(args: string[], context: CommandContex
|
|
|
119
121
|
}
|
|
120
122
|
const server = context.extensions.mcpRegistry.listServerSecurity().find((entry) => entry.name === serverName);
|
|
121
123
|
if (!server) {
|
|
122
|
-
context.print(`[memory] MCP server not found
|
|
124
|
+
context.print(`[memory] MCP server not found ${serverName}`);
|
|
123
125
|
return;
|
|
124
126
|
}
|
|
125
127
|
const record = await memory.add(buildMcpSecurityMemoryAddOptions(server));
|
|
@@ -139,7 +141,7 @@ export async function handleRecallCapture(args: string[], context: CommandContex
|
|
|
139
141
|
}
|
|
140
142
|
const plugin = pluginManager.list().find((entry) => entry.name === pluginName);
|
|
141
143
|
if (!plugin) {
|
|
142
|
-
context.print(`[memory] Plugin not found
|
|
144
|
+
context.print(`[memory] Plugin not found ${pluginName}`);
|
|
143
145
|
return;
|
|
144
146
|
}
|
|
145
147
|
const quarantineReason = pluginManager.getQuarantineRecord(plugin.name)?.reason;
|