@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
|
@@ -6,7 +6,7 @@ export interface AgentKnowledgeFailureLike {
|
|
|
6
6
|
readonly error: string;
|
|
7
7
|
readonly baseUrl: string;
|
|
8
8
|
readonly route: string;
|
|
9
|
-
readonly
|
|
9
|
+
readonly connectedHostVersion?: string;
|
|
10
10
|
readonly expectedSdkVersion?: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -42,6 +42,15 @@ function yesNo(value: boolean): string {
|
|
|
42
42
|
return value ? 'yes' : 'no';
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export function formatAgentKnowledgeFailureKind(kind: string): string {
|
|
46
|
+
if (kind === 'auth_required') return 'authorization required';
|
|
47
|
+
if (kind === 'connected_host_unavailable') return 'connected host unavailable';
|
|
48
|
+
if (kind === 'connected_host_route_unavailable') return 'connected host route unavailable';
|
|
49
|
+
if (kind === 'connected_host_error') return 'connected host error';
|
|
50
|
+
if (kind === 'version_mismatch') return 'version mismatch';
|
|
51
|
+
return kind.replace(/[_-]+/g, ' ');
|
|
52
|
+
}
|
|
53
|
+
|
|
45
54
|
function sourceLine(value: unknown): string {
|
|
46
55
|
const record = isRecord(value) ? value : {};
|
|
47
56
|
const title = cleanInline(record.title)
|
|
@@ -65,9 +74,9 @@ function resultLine(value: unknown): string {
|
|
|
65
74
|
const snippet = cleanInline(record.snippet) || cleanInline(record.summary) || cleanInline(record.text);
|
|
66
75
|
const parts = [
|
|
67
76
|
`[${type}] ${title}`,
|
|
68
|
-
id && id !== title ? `id
|
|
69
|
-
score !== null ? `score
|
|
70
|
-
url ? `url
|
|
77
|
+
id && id !== title ? `id ${id}` : '',
|
|
78
|
+
score !== null ? `score ${score.toFixed(3)}` : '',
|
|
79
|
+
url ? `url ${url}` : '',
|
|
71
80
|
].filter((part) => part.length > 0);
|
|
72
81
|
return snippet ? `${parts.join(' ')}\n ${snippet}` : parts.join(' ');
|
|
73
82
|
}
|
|
@@ -82,9 +91,9 @@ function nodeLine(value: unknown): string {
|
|
|
82
91
|
const summary = cleanInline(record.summary);
|
|
83
92
|
const parts = [
|
|
84
93
|
`[${kind}] ${title}`,
|
|
85
|
-
id && id !== title ? `id
|
|
86
|
-
status ? `status
|
|
87
|
-
confidence !== null ? `confidence
|
|
94
|
+
id && id !== title ? `id ${id}` : '',
|
|
95
|
+
status ? `status ${status}` : '',
|
|
96
|
+
confidence !== null ? `confidence ${confidence}` : '',
|
|
88
97
|
].filter((part) => part.length > 0);
|
|
89
98
|
return summary ? `${parts.join(' ')}\n ${summary}` : parts.join(' ');
|
|
90
99
|
}
|
|
@@ -96,7 +105,7 @@ function issueLine(value: unknown): string {
|
|
|
96
105
|
const code = cleanInline(record.code) || 'issue';
|
|
97
106
|
const status = cleanInline(record.status);
|
|
98
107
|
const message = cleanInline(record.message);
|
|
99
|
-
const suffix = status ? ` status
|
|
108
|
+
const suffix = status ? ` status ${status}` : '';
|
|
100
109
|
return ` - ${id} [${severity}] ${code}${suffix}${message ? ` - ${message}` : ''}`;
|
|
101
110
|
}
|
|
102
111
|
|
|
@@ -106,10 +115,14 @@ function connectorLine(value: unknown): string {
|
|
|
106
115
|
const name = cleanInline(record.displayName) || id;
|
|
107
116
|
const sourceType = cleanInline(record.sourceType);
|
|
108
117
|
const description = cleanInline(record.description);
|
|
109
|
-
const suffix = sourceType ? `
|
|
118
|
+
const suffix = sourceType ? ` source type ${sourceType}` : '';
|
|
110
119
|
return description ? ` - ${id} ${name}${suffix}\n ${description}` : ` - ${id} ${name}${suffix}`;
|
|
111
120
|
}
|
|
112
121
|
|
|
122
|
+
function relatedKnowledgeCountsLine(relatedEdges: number, linkedSources: number, linkedNodes: number): string {
|
|
123
|
+
return ` related edges ${relatedEdges} linked sources ${linkedSources} linked nodes ${linkedNodes}`;
|
|
124
|
+
}
|
|
125
|
+
|
|
113
126
|
export function formatStatus(data: unknown): string {
|
|
114
127
|
const record = isRecord(data) ? data : {};
|
|
115
128
|
const ready = readBoolean(record, 'ready');
|
|
@@ -120,13 +133,13 @@ export function formatStatus(data: unknown): string {
|
|
|
120
133
|
const storagePath = readString(record, 'storagePath');
|
|
121
134
|
return [
|
|
122
135
|
'Agent Knowledge status',
|
|
123
|
-
` ready
|
|
124
|
-
` sources
|
|
125
|
-
` nodes
|
|
126
|
-
` edges
|
|
127
|
-
` issues
|
|
128
|
-
storagePath ? ` storage
|
|
129
|
-
' route
|
|
136
|
+
` ready ${ready === null ? 'unknown' : yesNo(ready)}`,
|
|
137
|
+
` sources ${sourceCount ?? 'unknown'}`,
|
|
138
|
+
` nodes ${nodeCount ?? 'unknown'}`,
|
|
139
|
+
` edges ${edgeCount ?? 'unknown'}`,
|
|
140
|
+
` issues ${issueCount ?? 'unknown'}`,
|
|
141
|
+
storagePath ? ` storage ${storagePath}` : null,
|
|
142
|
+
' route /api/goodvibes-agent/knowledge/status',
|
|
130
143
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
131
144
|
}
|
|
132
145
|
|
|
@@ -137,7 +150,7 @@ export function formatEntityList(data: unknown, kind: 'sources' | 'nodes' | 'iss
|
|
|
137
150
|
return [
|
|
138
151
|
`Agent Knowledge ${kind}`,
|
|
139
152
|
' no records',
|
|
140
|
-
` route
|
|
153
|
+
` route /api/goodvibes-agent/knowledge/${kind}`,
|
|
141
154
|
].join('\n');
|
|
142
155
|
}
|
|
143
156
|
const format = kind === 'sources'
|
|
@@ -163,29 +176,29 @@ export function formatItem(data: unknown, id: string): string {
|
|
|
163
176
|
const linkedNodes = readArray(record, 'linkedNodes').length;
|
|
164
177
|
if (source) {
|
|
165
178
|
return [
|
|
166
|
-
`Agent Knowledge item
|
|
179
|
+
`Agent Knowledge item ${id}`,
|
|
167
180
|
` ${sourceLine(source)}`,
|
|
168
|
-
|
|
181
|
+
relatedKnowledgeCountsLine(relatedEdges, linkedSources, linkedNodes),
|
|
169
182
|
].join('\n');
|
|
170
183
|
}
|
|
171
184
|
if (node) {
|
|
172
185
|
return [
|
|
173
|
-
`Agent Knowledge item
|
|
186
|
+
`Agent Knowledge item ${id}`,
|
|
174
187
|
` ${nodeLine(node)}`,
|
|
175
|
-
|
|
188
|
+
relatedKnowledgeCountsLine(relatedEdges, linkedSources, linkedNodes),
|
|
176
189
|
].join('\n');
|
|
177
190
|
}
|
|
178
191
|
if (issue) {
|
|
179
192
|
return [
|
|
180
|
-
`Agent Knowledge item
|
|
193
|
+
`Agent Knowledge item ${id}`,
|
|
181
194
|
issueLine(issue),
|
|
182
|
-
|
|
195
|
+
relatedKnowledgeCountsLine(relatedEdges, linkedSources, linkedNodes),
|
|
183
196
|
].join('\n');
|
|
184
197
|
}
|
|
185
198
|
return [
|
|
186
|
-
`Agent Knowledge item
|
|
199
|
+
`Agent Knowledge item ${id}`,
|
|
187
200
|
' not found',
|
|
188
|
-
' route
|
|
201
|
+
' route /api/goodvibes-agent/knowledge/items/{id}',
|
|
189
202
|
].join('\n');
|
|
190
203
|
}
|
|
191
204
|
|
|
@@ -201,7 +214,7 @@ export function formatMap(data: unknown): string {
|
|
|
201
214
|
` nodes: ${nodes.length}`,
|
|
202
215
|
` edges: ${edges.length}`,
|
|
203
216
|
` issues: ${issues.length}`,
|
|
204
|
-
' route
|
|
217
|
+
' route /api/goodvibes-agent/knowledge/map',
|
|
205
218
|
].join('\n');
|
|
206
219
|
}
|
|
207
220
|
|
|
@@ -212,7 +225,7 @@ export function formatConnectors(data: unknown): string {
|
|
|
212
225
|
return [
|
|
213
226
|
'Agent Knowledge connectors',
|
|
214
227
|
' no connectors',
|
|
215
|
-
' route
|
|
228
|
+
' route /api/goodvibes-agent/knowledge/connectors',
|
|
216
229
|
].join('\n');
|
|
217
230
|
}
|
|
218
231
|
return [
|
|
@@ -231,13 +244,13 @@ export function formatConnector(data: unknown, id: string): string {
|
|
|
231
244
|
const capabilities = readArray(connector, 'capabilities').map(cleanInline).filter(Boolean);
|
|
232
245
|
const examples = readArray(connector, 'examples');
|
|
233
246
|
return [
|
|
234
|
-
`Agent Knowledge connector
|
|
235
|
-
` name
|
|
236
|
-
sourceType ? `
|
|
237
|
-
description ? ` description
|
|
247
|
+
`Agent Knowledge connector ${connectorId}`,
|
|
248
|
+
` name ${name}`,
|
|
249
|
+
sourceType ? ` source type ${sourceType}` : null,
|
|
250
|
+
description ? ` description ${description}` : null,
|
|
238
251
|
capabilities.length > 0 ? ` capabilities: ${capabilities.join(', ')}` : null,
|
|
239
|
-
` examples
|
|
240
|
-
' route
|
|
252
|
+
` examples ${examples.length}`,
|
|
253
|
+
' route /api/goodvibes-agent/knowledge/connectors/{id}',
|
|
241
254
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
242
255
|
}
|
|
243
256
|
|
|
@@ -248,10 +261,10 @@ export function formatConnectorDoctor(data: unknown, id: string): string {
|
|
|
248
261
|
const checks = readArray(record, 'checks');
|
|
249
262
|
const hints = readArray(record, 'hints').map(cleanInline).filter(Boolean);
|
|
250
263
|
return [
|
|
251
|
-
`Agent Knowledge connector doctor
|
|
252
|
-
` ready
|
|
253
|
-
summary ? ` summary
|
|
254
|
-
checks.length > 0 ? ' checks
|
|
264
|
+
`Agent Knowledge connector doctor ${cleanInline(record.connectorId) || id}`,
|
|
265
|
+
` ready ${ready === null ? 'unknown' : yesNo(ready)}`,
|
|
266
|
+
summary ? ` summary ${summary}` : null,
|
|
267
|
+
checks.length > 0 ? ' checks' : null,
|
|
255
268
|
...checks.slice(0, 10).map((check) => {
|
|
256
269
|
const item = isRecord(check) ? check : {};
|
|
257
270
|
const checkId = cleanInline(item.id) || 'check';
|
|
@@ -260,9 +273,9 @@ export function formatConnectorDoctor(data: unknown, id: string): string {
|
|
|
260
273
|
const detail = cleanInline(item.detail);
|
|
261
274
|
return ` - ${checkId} [${status}] ${label}${detail ? ` - ${detail}` : ''}`;
|
|
262
275
|
}),
|
|
263
|
-
hints.length > 0 ? ' hints
|
|
276
|
+
hints.length > 0 ? ' hints' : null,
|
|
264
277
|
...hints.slice(0, 8).map((hint) => ` - ${hint}`),
|
|
265
|
-
' route
|
|
278
|
+
' route /api/goodvibes-agent/knowledge/connectors/{id}/doctor',
|
|
266
279
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
267
280
|
}
|
|
268
281
|
|
|
@@ -276,16 +289,16 @@ export function formatAsk(data: unknown, query: string): string {
|
|
|
276
289
|
const facts = readArray(answer, 'facts');
|
|
277
290
|
const gaps = readArray(answer, 'gaps');
|
|
278
291
|
const lines = [
|
|
279
|
-
`Agent Knowledge answer
|
|
292
|
+
`Agent Knowledge answer ${query}`,
|
|
280
293
|
text,
|
|
281
294
|
'',
|
|
282
|
-
`confidence
|
|
295
|
+
`confidence ${confidence ?? 'unknown'}${synthesized === null ? '' : ` synthesized ${yesNo(synthesized)}`}`,
|
|
283
296
|
];
|
|
284
297
|
if (sources.length > 0) {
|
|
285
|
-
lines.push('', 'Sources
|
|
298
|
+
lines.push('', 'Sources', ...sources.slice(0, 8).map((source) => ` - ${sourceLine(source)}`));
|
|
286
299
|
}
|
|
287
|
-
if (facts.length > 0) lines.push('', `Facts
|
|
288
|
-
if (gaps.length > 0) lines.push('', `Gaps
|
|
300
|
+
if (facts.length > 0) lines.push('', `Facts ${facts.length}`);
|
|
301
|
+
if (gaps.length > 0) lines.push('', `Gaps ${gaps.length}`);
|
|
289
302
|
return lines.join('\n');
|
|
290
303
|
}
|
|
291
304
|
|
|
@@ -295,13 +308,13 @@ export function formatSearch(data: unknown, query: string): string {
|
|
|
295
308
|
const results = items.length > 0 ? items : readArray(record, 'results');
|
|
296
309
|
if (results.length === 0) {
|
|
297
310
|
return [
|
|
298
|
-
`Agent Knowledge search
|
|
311
|
+
`Agent Knowledge search ${query}`,
|
|
299
312
|
' no results',
|
|
300
|
-
' route
|
|
313
|
+
' route /api/goodvibes-agent/knowledge/search',
|
|
301
314
|
].join('\n');
|
|
302
315
|
}
|
|
303
316
|
return [
|
|
304
|
-
`Agent Knowledge search
|
|
317
|
+
`Agent Knowledge search ${query}`,
|
|
305
318
|
...results.slice(0, 10).map((result, index) => ` ${index + 1}. ${resultLine(result)}`),
|
|
306
319
|
].join('\n');
|
|
307
320
|
}
|
|
@@ -320,10 +333,10 @@ export function formatIngest(
|
|
|
320
333
|
const artifactId = cleanInline(record.artifactId);
|
|
321
334
|
return [
|
|
322
335
|
`Agent Knowledge ${label} accepted`,
|
|
323
|
-
` source
|
|
324
|
-
` ${targetLabel}
|
|
336
|
+
` knowledge source ${sourceId || '(pending)'}`,
|
|
337
|
+
` ${targetLabel} ${canonicalUri}`,
|
|
325
338
|
artifactId ? ` artifact: ${artifactId}` : null,
|
|
326
|
-
` route
|
|
339
|
+
` route ${route}`,
|
|
327
340
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
328
341
|
}
|
|
329
342
|
|
|
@@ -335,11 +348,11 @@ export function formatBatchIngest(data: unknown, label: string): string {
|
|
|
335
348
|
const errors = readArray(record, 'errors');
|
|
336
349
|
return [
|
|
337
350
|
`Agent Knowledge ${label} accepted`,
|
|
338
|
-
` imported
|
|
339
|
-
` failed
|
|
340
|
-
` sources
|
|
351
|
+
` imported ${imported ?? sources.length}`,
|
|
352
|
+
` failed ${failed ?? errors.length}`,
|
|
353
|
+
` sources ${sources.length}`,
|
|
341
354
|
...sources.slice(0, 5).map((source) => ` - ${sourceLine(source)}`),
|
|
342
|
-
...(errors.length > 0 ? [' errors
|
|
355
|
+
...(errors.length > 0 ? [' errors', ...errors.slice(0, 5).map((error) => ` - ${cleanInline(error)}`)] : []),
|
|
343
356
|
].join('\n');
|
|
344
357
|
}
|
|
345
358
|
|
|
@@ -348,29 +361,29 @@ export function formatReindex(data: unknown): string {
|
|
|
348
361
|
const status = isRecord(record.status) ? record.status : {};
|
|
349
362
|
return [
|
|
350
363
|
'Agent Knowledge reindex complete',
|
|
351
|
-
` sources
|
|
352
|
-
` nodes
|
|
353
|
-
` edges
|
|
354
|
-
` issues
|
|
355
|
-
' route
|
|
364
|
+
` sources ${readNumber(status, 'sourceCount') ?? 'unknown'}`,
|
|
365
|
+
` nodes ${readNumber(status, 'nodeCount') ?? 'unknown'}`,
|
|
366
|
+
` edges ${readNumber(status, 'edgeCount') ?? 'unknown'}`,
|
|
367
|
+
` issues ${readNumber(status, 'issueCount') ?? 'unknown'}`,
|
|
368
|
+
' route /api/goodvibes-agent/knowledge/reindex',
|
|
356
369
|
].join('\n');
|
|
357
370
|
}
|
|
358
371
|
|
|
359
372
|
export function formatFailure(failure: AgentKnowledgeFailureLike, json: boolean): string {
|
|
360
373
|
if (json) return JSON.stringify(failure, null, 2);
|
|
361
374
|
return [
|
|
362
|
-
`Agent Knowledge error
|
|
375
|
+
`Agent Knowledge error ${failure.kind} (${formatAgentKnowledgeFailureKind(failure.kind)})`,
|
|
363
376
|
` ${failure.error}`,
|
|
364
|
-
`
|
|
365
|
-
` route
|
|
366
|
-
failure.kind === 'version_mismatch' && failure.
|
|
367
|
-
? ` versions
|
|
377
|
+
` connected host ${failure.baseUrl}`,
|
|
378
|
+
` route ${failure.route}`,
|
|
379
|
+
failure.kind === 'version_mismatch' && failure.connectedHostVersion && failure.expectedSdkVersion
|
|
380
|
+
? ` versions connected host ${failure.connectedHostVersion}; expected ${failure.expectedSdkVersion}`
|
|
368
381
|
: null,
|
|
369
382
|
failure.kind === 'version_mismatch'
|
|
370
|
-
? ' next
|
|
383
|
+
? ' next update the connected GoodVibes host so /status matches the Agent SDK pin.'
|
|
371
384
|
: null,
|
|
372
|
-
failure.kind === '
|
|
373
|
-
? ' next
|
|
385
|
+
failure.kind === 'connected_host_route_unavailable'
|
|
386
|
+
? ' next update the connected GoodVibes host to the SDK version required by this Agent package.'
|
|
374
387
|
: null,
|
|
375
388
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
376
389
|
}
|
|
@@ -3,24 +3,30 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { createBrowserAgentSdk } from '@pellux/goodvibes-sdk/browser/agent';
|
|
4
4
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
5
5
|
import { SDK_VERSION, VERSION } from '../version.ts';
|
|
6
|
-
import type {
|
|
7
|
-
import type { DaemonCallMethod } from './agent-knowledge-methods.ts';
|
|
6
|
+
import type { ConnectedHostCallMethod } from './agent-knowledge-methods.ts';
|
|
8
7
|
|
|
9
8
|
export type JsonRecord = Record<string, unknown>;
|
|
10
9
|
|
|
11
|
-
export interface
|
|
10
|
+
export interface AgentKnowledgeConnection {
|
|
12
11
|
readonly baseUrl: string;
|
|
13
12
|
readonly token: string | null;
|
|
14
13
|
readonly tokenPath: string;
|
|
15
14
|
}
|
|
16
15
|
|
|
16
|
+
export interface AgentKnowledgeConnectionRuntime {
|
|
17
|
+
readonly configManager: {
|
|
18
|
+
get(key: string): unknown;
|
|
19
|
+
};
|
|
20
|
+
readonly homeDirectory: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
export interface AgentKnowledgeFailure {
|
|
18
24
|
readonly ok: false;
|
|
19
|
-
readonly kind: '
|
|
25
|
+
readonly kind: 'connected_host_unavailable' | 'auth_required' | 'version_mismatch' | 'connected_host_route_unavailable' | 'connected_host_error';
|
|
20
26
|
readonly error: string;
|
|
21
27
|
readonly baseUrl: string;
|
|
22
28
|
readonly route: string;
|
|
23
|
-
readonly
|
|
29
|
+
readonly connectedHostVersion?: string;
|
|
24
30
|
readonly expectedSdkVersion?: string;
|
|
25
31
|
}
|
|
26
32
|
|
|
@@ -46,7 +52,7 @@ export function readPackageMetadata(): { readonly version: string; readonly sdkV
|
|
|
46
52
|
return { version: VERSION, sdkVersion: SDK_VERSION };
|
|
47
53
|
}
|
|
48
54
|
|
|
49
|
-
export function
|
|
55
|
+
export function resolveConnectedHostConnection(runtime: AgentKnowledgeConnectionRuntime): AgentKnowledgeConnection {
|
|
50
56
|
const host = String(runtime.configManager.get('controlPlane.host') ?? '127.0.0.1');
|
|
51
57
|
const port = Number(runtime.configManager.get('controlPlane.port') ?? 3421);
|
|
52
58
|
const baseUrl = `http://${host}:${Number.isFinite(port) ? port : 3421}`;
|
|
@@ -61,7 +67,7 @@ export function resolveDaemonConnection(runtime: CliCommandRuntime): AgentDaemon
|
|
|
61
67
|
}
|
|
62
68
|
}
|
|
63
69
|
|
|
64
|
-
export async function
|
|
70
|
+
export async function fetchConnectedHostStatus(connection: AgentKnowledgeConnection): Promise<{ readonly ok: boolean; readonly status: number; readonly body: unknown }> {
|
|
65
71
|
try {
|
|
66
72
|
const response = await fetch(`${connection.baseUrl}/status`, {
|
|
67
73
|
headers: connection.token ? { authorization: `Bearer ${connection.token}` } : undefined,
|
|
@@ -79,7 +85,7 @@ export async function fetchDaemonStatus(connection: AgentDaemonConnection): Prom
|
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
|
|
82
|
-
export async function classifyKnowledgeError(error: unknown, connection:
|
|
88
|
+
export async function classifyKnowledgeError(error: unknown, connection: AgentKnowledgeConnection, route: string): Promise<AgentKnowledgeFailure> {
|
|
83
89
|
const message = summarizeError(error);
|
|
84
90
|
const lower = message.toLowerCase();
|
|
85
91
|
if (lower.includes('401') || lower.includes('unauthorized') || lower.includes('auth')) {
|
|
@@ -87,29 +93,29 @@ export async function classifyKnowledgeError(error: unknown, connection: AgentDa
|
|
|
87
93
|
}
|
|
88
94
|
if (lower.includes('404') || lower.includes('not found')) {
|
|
89
95
|
const metadata = readPackageMetadata();
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
96
|
+
const connectedHost = await fetchConnectedHostStatus(connection);
|
|
97
|
+
const connectedHostRecord = isRecord(connectedHost.body) ? connectedHost.body : {};
|
|
98
|
+
const connectedHostVersion = readString(connectedHostRecord, 'version') ?? 'unknown';
|
|
99
|
+
if (connectedHost.ok && connectedHostVersion !== metadata.sdkVersion) {
|
|
94
100
|
return {
|
|
95
101
|
ok: false,
|
|
96
102
|
kind: 'version_mismatch',
|
|
97
|
-
error: `Connected GoodVibes
|
|
103
|
+
error: `Connected GoodVibes host SDK version ${connectedHostVersion} does not match Agent SDK pin ${metadata.sdkVersion}; Agent Knowledge route is unavailable.`,
|
|
98
104
|
baseUrl: connection.baseUrl,
|
|
99
105
|
route,
|
|
100
|
-
|
|
106
|
+
connectedHostVersion,
|
|
101
107
|
expectedSdkVersion: metadata.sdkVersion,
|
|
102
108
|
};
|
|
103
109
|
}
|
|
104
|
-
return { ok: false, kind: '
|
|
110
|
+
return { ok: false, kind: 'connected_host_route_unavailable', error: message, baseUrl: connection.baseUrl, route };
|
|
105
111
|
}
|
|
106
112
|
if (lower.includes('fetch') || lower.includes('connect') || lower.includes('econnrefused')) {
|
|
107
|
-
return { ok: false, kind: '
|
|
113
|
+
return { ok: false, kind: 'connected_host_unavailable', error: message, baseUrl: connection.baseUrl, route };
|
|
108
114
|
}
|
|
109
|
-
return { ok: false, kind: '
|
|
115
|
+
return { ok: false, kind: 'connected_host_error', error: message, baseUrl: connection.baseUrl, route };
|
|
110
116
|
}
|
|
111
117
|
|
|
112
|
-
export function createAgentSdk(connection:
|
|
118
|
+
export function createAgentSdk(connection: AgentKnowledgeConnection) {
|
|
113
119
|
return createBrowserAgentSdk({
|
|
114
120
|
baseUrl: connection.baseUrl,
|
|
115
121
|
authToken: connection.token,
|
|
@@ -117,7 +123,7 @@ export function createAgentSdk(connection: AgentDaemonConnection) {
|
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
export async function postAgentKnowledgeJson<TData>(
|
|
120
|
-
connection:
|
|
126
|
+
connection: AgentKnowledgeConnection,
|
|
121
127
|
route: string,
|
|
122
128
|
body: JsonRecord,
|
|
123
129
|
): Promise<TData> {
|
|
@@ -164,7 +170,7 @@ function queryRoute(route: string, query: JsonRecord): string {
|
|
|
164
170
|
}
|
|
165
171
|
|
|
166
172
|
export async function getAgentKnowledgeJson<TData>(
|
|
167
|
-
connection:
|
|
173
|
+
connection: AgentKnowledgeConnection,
|
|
168
174
|
route: string,
|
|
169
175
|
query: JsonRecord = {},
|
|
170
176
|
): Promise<TData> {
|
|
@@ -211,22 +217,22 @@ export function findDisallowedKnowledgeScopeFlag(args: readonly string[]): strin
|
|
|
211
217
|
export function formatScopeFlagRejection(flag: string): string {
|
|
212
218
|
return [
|
|
213
219
|
`Agent Knowledge is isolated; ${flag} is not accepted.`,
|
|
214
|
-
'GoodVibes Agent must not use default
|
|
220
|
+
'GoodVibes Agent must not use default knowledge or non-Agent product spaces.',
|
|
215
221
|
'Use only /api/goodvibes-agent/knowledge/* Agent-owned routes.',
|
|
216
222
|
].join('\n');
|
|
217
223
|
}
|
|
218
224
|
|
|
219
225
|
export async function runKnowledgeCall<TData>(
|
|
220
|
-
runtime:
|
|
221
|
-
method:
|
|
222
|
-
call: (connection:
|
|
226
|
+
runtime: AgentKnowledgeConnectionRuntime,
|
|
227
|
+
method: ConnectedHostCallMethod,
|
|
228
|
+
call: (connection: AgentKnowledgeConnection) => Promise<TData>,
|
|
223
229
|
): Promise<AgentKnowledgeResult<TData>> {
|
|
224
|
-
const connection =
|
|
230
|
+
const connection = resolveConnectedHostConnection(runtime);
|
|
225
231
|
if (!connection.token) {
|
|
226
232
|
return {
|
|
227
233
|
ok: false,
|
|
228
234
|
kind: 'auth_required',
|
|
229
|
-
error: `No
|
|
235
|
+
error: `No connected-host operator token found at ${connection.tokenPath}`,
|
|
230
236
|
baseUrl: connection.baseUrl,
|
|
231
237
|
route: method.route,
|
|
232
238
|
};
|
|
@@ -8,7 +8,6 @@ import { createRuntimeStore } from '../runtime/store/index.ts';
|
|
|
8
8
|
import { getOnboardingCheckMarkerPath } from '../runtime/onboarding/index.ts';
|
|
9
9
|
import { CONFIG_SCHEMA } from '../config/index.ts';
|
|
10
10
|
import { SecretsManager } from '../config/secrets.ts';
|
|
11
|
-
import type { ConfigKey } from '../config/index.ts';
|
|
12
11
|
import type { CliCommandRuntime } from './management.ts';
|
|
13
12
|
import type { CliCommandOutput } from './types.ts';
|
|
14
13
|
import { getPackageVersion } from './help.ts';
|
|
@@ -35,14 +34,20 @@ function getNestedValue(source: unknown, key: string): unknown {
|
|
|
35
34
|
let cursor = source;
|
|
36
35
|
for (const part of key.split('.')) {
|
|
37
36
|
if (cursor == null || typeof cursor !== 'object') return undefined;
|
|
38
|
-
cursor = (cursor
|
|
37
|
+
cursor = Reflect.get(cursor, part);
|
|
39
38
|
}
|
|
40
39
|
return cursor;
|
|
41
40
|
}
|
|
42
41
|
|
|
42
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
43
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
43
46
|
function readJsonFile(path: string): { readonly ok: true; readonly value: Record<string, unknown> } | { readonly ok: false; readonly error: string } {
|
|
44
47
|
try {
|
|
45
|
-
|
|
48
|
+
const value = JSON.parse(readFileSync(path, 'utf-8')) as unknown;
|
|
49
|
+
if (!isRecord(value)) return { ok: false, error: 'Bundle file must contain a JSON object.' };
|
|
50
|
+
return { ok: true, value };
|
|
46
51
|
} catch (error) {
|
|
47
52
|
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
48
53
|
}
|
|
@@ -128,11 +133,11 @@ export async function handleBundleCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
128
133
|
if (!path) return { output: `Usage: ${runtime.cli.binary} bundle inspect <path>`, exitCode: 2 };
|
|
129
134
|
const sourcePath = shellPaths.resolveWorkspacePath(path);
|
|
130
135
|
const parsed = readJsonFile(sourcePath);
|
|
131
|
-
if (!parsed.ok) return { output: `Invalid bundle JSON
|
|
136
|
+
if (!parsed.ok) return { output: `Invalid bundle JSON ${parsed.error}`, exitCode: 1 };
|
|
132
137
|
const summary = inspectBundle(sourcePath, parsed.value);
|
|
133
138
|
return {
|
|
134
139
|
output: formatJsonOrText(runtime, summary, [
|
|
135
|
-
'GoodVibes bundle',
|
|
140
|
+
'GoodVibes Agent support bundle',
|
|
136
141
|
` type: ${summary.type}`,
|
|
137
142
|
` version: ${summary.version}`,
|
|
138
143
|
` path: ${summary.path}`,
|
|
@@ -191,8 +196,8 @@ export async function handleBundleCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
191
196
|
output: formatJsonOrText(runtime, {
|
|
192
197
|
path: targetPath,
|
|
193
198
|
redactedConfigPaths: redactedConfig.redactedPaths,
|
|
194
|
-
|
|
195
|
-
}, `Bundle exported: ${targetPath}\n redactedConfigKeys: ${redactedConfig.redactedPaths.length}\n
|
|
199
|
+
hostIntegrationIssues: service.issues,
|
|
200
|
+
}, `Bundle exported: ${targetPath}\n redactedConfigKeys: ${redactedConfig.redactedPaths.length}\n hostIntegrationIssues: ${service.issues.length}`),
|
|
196
201
|
exitCode: 0,
|
|
197
202
|
};
|
|
198
203
|
}
|
|
@@ -202,7 +207,7 @@ export async function handleBundleCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
202
207
|
if (!path) return { output: `Usage: ${runtime.cli.binary} bundle import <path>`, exitCode: 2 };
|
|
203
208
|
const sourcePath = shellPaths.resolveWorkspacePath(path);
|
|
204
209
|
const parsed = readJsonFile(sourcePath);
|
|
205
|
-
if (!parsed.ok) return { output: `Invalid bundle JSON
|
|
210
|
+
if (!parsed.ok) return { output: `Invalid bundle JSON ${parsed.error}`, exitCode: 1 };
|
|
206
211
|
const config = parsed.value['config'];
|
|
207
212
|
if (!config || typeof config !== 'object') return { output: 'Bundle has no config object to import.', exitCode: 1 };
|
|
208
213
|
let count = 0;
|
|
@@ -214,7 +219,7 @@ export async function handleBundleCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
214
219
|
skippedRedacted++;
|
|
215
220
|
continue;
|
|
216
221
|
}
|
|
217
|
-
runtime.configManager.setDynamic(setting.key
|
|
222
|
+
runtime.configManager.setDynamic(setting.key, value);
|
|
218
223
|
count++;
|
|
219
224
|
}
|
|
220
225
|
return {
|