@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
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type ProvenanceLinkKind,
|
|
18
18
|
} from '@pellux/goodvibes-sdk/platform/state';
|
|
19
19
|
import { assertNoSecretLikeMemoryText } from '../agent/memory-safety.ts';
|
|
20
|
+
import { formatAgentRecordReference, formatAgentRecordReviewState } from '../agent/record-labels.ts';
|
|
20
21
|
import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
|
|
21
22
|
import type { CliCommandOutput } from './types.ts';
|
|
22
23
|
import type { CliCommandRuntime } from './management.ts';
|
|
@@ -172,12 +173,12 @@ function isProvenanceKind(value: string): value is ProvenanceLinkKind {
|
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
function requireClass(value: string | undefined): MemoryClass {
|
|
175
|
-
if (!value || !isMemoryClass(value)) throw new Error(`Invalid memory class "${value ?? ''}". Valid
|
|
176
|
+
if (!value || !isMemoryClass(value)) throw new Error(`Invalid memory class "${value ?? ''}". Valid values ${VALID_CLASSES.join(', ')}`);
|
|
176
177
|
return value;
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
function requireScope(value: string | undefined): MemoryScope {
|
|
180
|
-
if (!value || !isMemoryScope(value)) throw new Error(`Invalid memory scope "${value ?? ''}". Valid
|
|
181
|
+
if (!value || !isMemoryScope(value)) throw new Error(`Invalid memory scope "${value ?? ''}". Valid values ${VALID_SCOPES.join(', ')}`);
|
|
181
182
|
return value;
|
|
182
183
|
}
|
|
183
184
|
|
|
@@ -217,23 +218,23 @@ async function withMemory<T>(runtime: CliCommandRuntime, fn: (context: MemoryCon
|
|
|
217
218
|
}
|
|
218
219
|
|
|
219
220
|
function renderRecordLine(record: MemoryRecord, semanticEntry?: MemorySemanticSearchResult): string {
|
|
220
|
-
const tags = record.tags.length > 0 ? `
|
|
221
|
-
const score = semanticEntry ? `
|
|
222
|
-
return ` ${record.id} ${record.scope}/${record.cls} ${record.reviewState} ${record.confidence}%${score}${tags} ${record.summary}`;
|
|
221
|
+
const tags = record.tags.length > 0 ? ` tags ${record.tags.join(', ')}` : '';
|
|
222
|
+
const score = semanticEntry ? ` similarity ${Math.round(semanticEntry.similarity * 100)}%` : '';
|
|
223
|
+
return ` ${record.id} ${record.scope}/${record.cls} ${formatAgentRecordReviewState(record.reviewState)} ${record.confidence}%${score}${tags} ${record.summary}`;
|
|
223
224
|
}
|
|
224
225
|
|
|
225
226
|
function renderRecordList(title: string, path: string, records: readonly MemoryRecord[], semanticResults: readonly MemorySemanticSearchResult[] = []): string {
|
|
226
227
|
if (records.length === 0) {
|
|
227
228
|
return [
|
|
228
229
|
title,
|
|
229
|
-
` store
|
|
230
|
+
` store ${path}`,
|
|
230
231
|
' No Agent memory records found.',
|
|
231
232
|
' Add one with: goodvibes-agent memory add fact "Useful durable fact" --scope project',
|
|
232
233
|
].join('\n');
|
|
233
234
|
}
|
|
234
235
|
return [
|
|
235
236
|
`${title} (${records.length})`,
|
|
236
|
-
` store
|
|
237
|
+
` store ${path}`,
|
|
237
238
|
...records.map((record) => renderRecordLine(record, semanticResults.find((entry) => entry.record.id === record.id))),
|
|
238
239
|
].join('\n');
|
|
239
240
|
}
|
|
@@ -243,7 +244,7 @@ function renderRecord(record: MemoryRecord, links: readonly MemoryLink[]): strin
|
|
|
243
244
|
`Memory ${record.id}`,
|
|
244
245
|
` scope: ${record.scope}`,
|
|
245
246
|
` class: ${record.cls}`,
|
|
246
|
-
` review: ${record.reviewState}`,
|
|
247
|
+
` review: ${formatAgentRecordReviewState(record.reviewState)}`,
|
|
247
248
|
` confidence: ${record.confidence}`,
|
|
248
249
|
` tags: ${record.tags.join(', ') || '(none)'}`,
|
|
249
250
|
` created: ${timestamp(record.createdAt)}`,
|
|
@@ -253,9 +254,9 @@ function renderRecord(record: MemoryRecord, links: readonly MemoryLink[]): strin
|
|
|
253
254
|
'',
|
|
254
255
|
record.summary,
|
|
255
256
|
record.detail ? `\n${record.detail}` : '',
|
|
256
|
-
record.provenance.length > 0 ? '\nProvenance
|
|
257
|
-
...record.provenance.map((entry) => ` ${
|
|
258
|
-
links.length > 0 ? '\nLinks
|
|
257
|
+
record.provenance.length > 0 ? '\nProvenance' : '',
|
|
258
|
+
...record.provenance.map((entry) => ` ${formatAgentRecordReference(entry)}`),
|
|
259
|
+
links.length > 0 ? '\nLinks' : '',
|
|
259
260
|
...links.map((link) => ` ${link.fromId} -> ${link.toId} [${link.relation}]`),
|
|
260
261
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
261
262
|
}
|
|
@@ -283,7 +284,7 @@ function provenanceFromOptions(options: ParsedOptions): readonly ProvenanceLink[
|
|
|
283
284
|
addProvenance(provenance, 'turn', optionValue(options, 'turn'));
|
|
284
285
|
addProvenance(provenance, 'task', optionValue(options, 'task'));
|
|
285
286
|
addProvenance(provenance, 'file', optionValue(options, 'file'));
|
|
286
|
-
if (provenance.length === 0) provenance.push({ kind: 'event', ref: '
|
|
287
|
+
if (provenance.length === 0) provenance.push({ kind: 'event', ref: 'Command' });
|
|
287
288
|
return provenance;
|
|
288
289
|
}
|
|
289
290
|
|
|
@@ -306,7 +307,7 @@ function usage(): string {
|
|
|
306
307
|
' handoff-inspect <path>',
|
|
307
308
|
' vector [status|doctor|rebuild]',
|
|
308
309
|
'',
|
|
309
|
-
'Agent memory is local to GoodVibes Agent and never falls back to default
|
|
310
|
+
'Agent memory is local to GoodVibes Agent and never falls back to default knowledge or non-Agent knowledge segments.',
|
|
310
311
|
].join('\n');
|
|
311
312
|
}
|
|
312
313
|
|
|
@@ -391,11 +392,11 @@ function writeBundle(path: string, bundle: MemoryBundle): void {
|
|
|
391
392
|
function renderBundleInspection(path: string, bundle: MemoryBundle): string {
|
|
392
393
|
return [
|
|
393
394
|
'Agent memory handoff bundle',
|
|
394
|
-
` path
|
|
395
|
-
` scope
|
|
396
|
-
` records
|
|
397
|
-
` links
|
|
398
|
-
...bundle.records.slice(0, 20).map((record) => ` ${record.id} ${record.scope}/${record.cls} ${record.reviewState} ${record.summary}`),
|
|
395
|
+
` path ${path}`,
|
|
396
|
+
` scope ${bundle.scope}`,
|
|
397
|
+
` records ${bundle.recordCount}`,
|
|
398
|
+
` links ${bundle.linkCount}`,
|
|
399
|
+
...bundle.records.slice(0, 20).map((record) => ` ${record.id} ${record.scope}/${record.cls} ${formatAgentRecordReviewState(record.reviewState)} ${record.summary}`),
|
|
399
400
|
bundle.records.length > 20 ? ` ... ${bundle.records.length - 20} more` : '',
|
|
400
401
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
401
402
|
}
|
|
@@ -441,7 +442,7 @@ async function handleAdd(runtime: CliCommandRuntime, context: MemoryContext, arg
|
|
|
441
442
|
assertNoSecretLikeMemoryText([summary, detail ?? '', ...(tags ?? [])]);
|
|
442
443
|
const reviewState = optionValue(options, 'review-state');
|
|
443
444
|
if (reviewState !== undefined && !isReviewState(reviewState)) {
|
|
444
|
-
return failure(runtime, 'invalid_memory_command', `Invalid review state "${reviewState}". Valid
|
|
445
|
+
return failure(runtime, 'invalid_memory_command', `Invalid review state "${reviewState}". Valid values ${VALID_REVIEW_STATES.join(', ')}`, 2);
|
|
445
446
|
}
|
|
446
447
|
const record = await context.registry.add({
|
|
447
448
|
scope: optionalScope(optionValue(options, 'scope')) ?? 'project',
|
|
@@ -456,14 +457,17 @@ async function handleAdd(runtime: CliCommandRuntime, context: MemoryContext, arg
|
|
|
456
457
|
reviewedBy: optionValue(options, 'by'),
|
|
457
458
|
},
|
|
458
459
|
});
|
|
459
|
-
return success(runtime, 'agent.memory.add', record,
|
|
460
|
+
return success(runtime, 'agent.memory.add', record, [
|
|
461
|
+
'Agent memory added',
|
|
462
|
+
` id ${record.id}`,
|
|
463
|
+
].join('\n'));
|
|
460
464
|
}
|
|
461
465
|
|
|
462
466
|
async function handleShow(runtime: CliCommandRuntime, context: MemoryContext, args: readonly string[]): Promise<CliCommandOutput> {
|
|
463
467
|
const id = args[0];
|
|
464
468
|
if (!id) return failure(runtime, 'invalid_memory_command', 'Usage: goodvibes-agent memory show <id>', 2);
|
|
465
469
|
const record = context.registry.get(id);
|
|
466
|
-
if (!record) return failure(runtime, 'memory_not_found', `Memory record not found
|
|
470
|
+
if (!record) return failure(runtime, 'memory_not_found', `Memory record not found ${id}`, 1);
|
|
467
471
|
return success(runtime, 'agent.memory.show', { record, links: context.registry.linksFor(id) }, renderRecord(record, context.registry.linksFor(id)));
|
|
468
472
|
}
|
|
469
473
|
|
|
@@ -485,8 +489,13 @@ async function handleReview(runtime: CliCommandRuntime, context: MemoryContext,
|
|
|
485
489
|
reviewedBy: optionValue(options, 'by') ?? 'operator',
|
|
486
490
|
staleReason: optionValue(options, 'reason'),
|
|
487
491
|
});
|
|
488
|
-
if (!record) return failure(runtime, 'memory_not_found', `Memory record not found
|
|
489
|
-
return success(runtime, 'agent.memory.review', record,
|
|
492
|
+
if (!record) return failure(runtime, 'memory_not_found', `Memory record not found ${id}`, 1);
|
|
493
|
+
return success(runtime, 'agent.memory.review', record, [
|
|
494
|
+
'Agent memory reviewed',
|
|
495
|
+
` id ${record.id}`,
|
|
496
|
+
` review ${formatAgentRecordReviewState(record.reviewState)}`,
|
|
497
|
+
` confidence ${record.confidence}%`,
|
|
498
|
+
].join('\n'));
|
|
490
499
|
}
|
|
491
500
|
|
|
492
501
|
async function handleReviewShortcut(runtime: CliCommandRuntime, context: MemoryContext, state: Extract<MemoryReviewState, 'stale' | 'contradicted'>, args: readonly string[]): Promise<CliCommandOutput> {
|
|
@@ -499,8 +508,11 @@ async function handleReviewShortcut(runtime: CliCommandRuntime, context: MemoryC
|
|
|
499
508
|
reviewedBy: 'operator',
|
|
500
509
|
staleReason: reasonParts.join(' '),
|
|
501
510
|
});
|
|
502
|
-
if (!record) return failure(runtime, 'memory_not_found', `Memory record not found
|
|
503
|
-
return success(runtime, `agent.memory.${state}`, record,
|
|
511
|
+
if (!record) return failure(runtime, 'memory_not_found', `Memory record not found ${id}`, 1);
|
|
512
|
+
return success(runtime, `agent.memory.${state}`, record, [
|
|
513
|
+
`Agent memory marked ${state}`,
|
|
514
|
+
` id ${record.id}`,
|
|
515
|
+
].join('\n'));
|
|
504
516
|
}
|
|
505
517
|
|
|
506
518
|
async function handlePromote(runtime: CliCommandRuntime, context: MemoryContext, args: readonly string[]): Promise<CliCommandOutput> {
|
|
@@ -509,8 +521,12 @@ async function handlePromote(runtime: CliCommandRuntime, context: MemoryContext,
|
|
|
509
521
|
if (!id || !scopeRaw) return failure(runtime, 'invalid_memory_command', 'Usage: goodvibes-agent memory promote <id> <session|project|team> --yes', 2);
|
|
510
522
|
if (!hasFlag(options, 'yes')) return failure(runtime, 'confirmation_required', `Refusing to promote memory record ${id} without --yes.`, 2);
|
|
511
523
|
const record = context.registry.update(id, { scope: requireScope(scopeRaw) });
|
|
512
|
-
if (!record) return failure(runtime, 'memory_not_found', `Memory record not found
|
|
513
|
-
return success(runtime, 'agent.memory.promote', record,
|
|
524
|
+
if (!record) return failure(runtime, 'memory_not_found', `Memory record not found ${id}`, 1);
|
|
525
|
+
return success(runtime, 'agent.memory.promote', record, [
|
|
526
|
+
'Agent memory promoted',
|
|
527
|
+
` id ${record.id}`,
|
|
528
|
+
` scope ${record.scope}`,
|
|
529
|
+
].join('\n'));
|
|
514
530
|
}
|
|
515
531
|
|
|
516
532
|
async function handleLink(runtime: CliCommandRuntime, context: MemoryContext, args: readonly string[]): Promise<CliCommandOutput> {
|
|
@@ -520,7 +536,12 @@ async function handleLink(runtime: CliCommandRuntime, context: MemoryContext, ar
|
|
|
520
536
|
if (!hasFlag(options, 'yes')) return failure(runtime, 'confirmation_required', `Refusing to link memory records ${fromId} and ${toId} without --yes.`, 2);
|
|
521
537
|
const link = await context.registry.link(fromId, toId, relation);
|
|
522
538
|
if (!link) return failure(runtime, 'memory_link_failed', 'Memory link failed; check that both records exist.', 1);
|
|
523
|
-
return success(runtime, 'agent.memory.link', link,
|
|
539
|
+
return success(runtime, 'agent.memory.link', link, [
|
|
540
|
+
'Agent memory linked',
|
|
541
|
+
` from ${fromId}`,
|
|
542
|
+
` to ${toId}`,
|
|
543
|
+
` relation ${relation}`,
|
|
544
|
+
].join('\n'));
|
|
524
545
|
}
|
|
525
546
|
|
|
526
547
|
async function handleDelete(runtime: CliCommandRuntime, context: MemoryContext, args: readonly string[]): Promise<CliCommandOutput> {
|
|
@@ -528,8 +549,11 @@ async function handleDelete(runtime: CliCommandRuntime, context: MemoryContext,
|
|
|
528
549
|
const id = options.positionals[0];
|
|
529
550
|
if (!id) return failure(runtime, 'invalid_memory_command', 'Usage: goodvibes-agent memory delete <id> --yes', 2);
|
|
530
551
|
if (!hasFlag(options, 'yes')) return failure(runtime, 'confirmation_required', `Refusing to delete memory record ${id} without --yes.`, 2);
|
|
531
|
-
if (!context.registry.delete(id)) return failure(runtime, 'memory_not_found', `Memory record not found
|
|
532
|
-
return success(runtime, 'agent.memory.delete', { id },
|
|
552
|
+
if (!context.registry.delete(id)) return failure(runtime, 'memory_not_found', `Memory record not found ${id}`, 1);
|
|
553
|
+
return success(runtime, 'agent.memory.delete', { id }, [
|
|
554
|
+
`Agent memory deleted: ${id}`,
|
|
555
|
+
` id ${id}`,
|
|
556
|
+
].join('\n'));
|
|
533
557
|
}
|
|
534
558
|
|
|
535
559
|
async function handleExport(runtime: CliCommandRuntime, context: MemoryContext, args: readonly string[]): Promise<CliCommandOutput> {
|
|
@@ -541,7 +565,12 @@ async function handleExport(runtime: CliCommandRuntime, context: MemoryContext,
|
|
|
541
565
|
const path = resolvePath(runtime, pathArg);
|
|
542
566
|
const bundle = context.registry.exportBundle(filter);
|
|
543
567
|
writeBundle(path, bundle);
|
|
544
|
-
return success(runtime, 'agent.memory.export', { path, bundle },
|
|
568
|
+
return success(runtime, 'agent.memory.export', { path, bundle }, [
|
|
569
|
+
'Agent memory exported',
|
|
570
|
+
` records ${bundle.recordCount}`,
|
|
571
|
+
` links ${bundle.linkCount}`,
|
|
572
|
+
` path ${path}`,
|
|
573
|
+
].join('\n'));
|
|
545
574
|
}
|
|
546
575
|
|
|
547
576
|
async function handleImport(runtime: CliCommandRuntime, context: MemoryContext, args: readonly string[]): Promise<CliCommandOutput> {
|
|
@@ -552,7 +581,12 @@ async function handleImport(runtime: CliCommandRuntime, context: MemoryContext,
|
|
|
552
581
|
const path = resolvePath(runtime, pathArg);
|
|
553
582
|
const bundle = readBundle(path);
|
|
554
583
|
const result = await context.registry.importBundle(bundle);
|
|
555
|
-
return success(runtime, 'agent.memory.import', { path, result },
|
|
584
|
+
return success(runtime, 'agent.memory.import', { path, result }, [
|
|
585
|
+
`Agent memory imported: ${result.importedRecords} record${result.importedRecords === 1 ? '' : 's'}`,
|
|
586
|
+
` records: ${result.importedRecords}`,
|
|
587
|
+
` links: ${result.importedLinks}`,
|
|
588
|
+
` skipped: ${result.skippedRecords}`,
|
|
589
|
+
].join('\n'));
|
|
556
590
|
}
|
|
557
591
|
|
|
558
592
|
async function handleInspect(runtime: CliCommandRuntime, args: readonly string[]): Promise<CliCommandOutput> {
|
package/src/cli/parser.ts
CHANGED
|
@@ -58,7 +58,40 @@ const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
|
|
|
58
58
|
version: 'version',
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
const
|
|
61
|
+
const BLOCKED_PRODUCT_COMMAND_HINTS: Readonly<Partial<Record<string, (binary: string) => string>>> = {
|
|
62
|
+
app: (binary) => `Unsupported command: app. Launch the Agent TUI with "${binary}" and no command.`,
|
|
63
|
+
bridge: () => 'Unsupported command: bridge. GoodVibes Agent connects to an externally managed GoodVibes host and does not expose bridge processes.',
|
|
64
|
+
'control-plane': () => 'Unsupported command: control-plane. GoodVibes Agent can inspect connected-host posture, but it does not manage host endpoints.',
|
|
65
|
+
controlplane: () => 'Unsupported command: controlplane. GoodVibes Agent can inspect connected-host posture, but it does not manage host endpoints.',
|
|
66
|
+
cp: () => 'Unsupported command: cp. GoodVibes Agent can inspect connected-host posture, but it does not manage host endpoints.',
|
|
67
|
+
daemon: () => 'Unsupported command: daemon. GoodVibes Agent connects to an externally managed GoodVibes host and does not start or manage host processes.',
|
|
68
|
+
'http-listener': () => 'Unsupported command: http-listener. GoodVibes Agent does not start listeners or expose inbound host endpoints.',
|
|
69
|
+
launch: (binary) => `Unsupported command: launch. Launch the Agent TUI with "${binary}" and no command.`,
|
|
70
|
+
listener: () => 'Unsupported command: listener. GoodVibes Agent does not start listeners or expose inbound host endpoints.',
|
|
71
|
+
remote: () => 'Unsupported command: remote. GoodVibes Agent uses explicit connected-host routes and does not manage remote host transport.',
|
|
72
|
+
serve: () => 'Unsupported command: serve. GoodVibes Agent connects to an externally managed GoodVibes host and does not start server processes.',
|
|
73
|
+
server: () => 'Unsupported command: server. GoodVibes Agent connects to an externally managed GoodVibes host and does not start server processes.',
|
|
74
|
+
service: () => 'Unsupported command: service. GoodVibes Agent keeps host lifecycle ownership outside this product.',
|
|
75
|
+
services: () => 'Unsupported command: services. GoodVibes Agent keeps host lifecycle ownership outside this product.',
|
|
76
|
+
start: (binary) => `Unsupported command: start. Launch the Agent TUI with "${binary}" and no command; Agent does not start connected-host processes.`,
|
|
77
|
+
surface: () => 'Unsupported command: surface. GoodVibes Agent does not manage connected-host surfaces.',
|
|
78
|
+
surfaces: () => 'Unsupported command: surfaces. GoodVibes Agent does not manage connected-host surfaces.',
|
|
79
|
+
tui: (binary) => `Unsupported command: tui. Launch the Agent TUI with "${binary}" and no command.`,
|
|
80
|
+
web: () => 'Unsupported command: web. GoodVibes Agent does not start web servers or expose browser routes.',
|
|
81
|
+
webhook: () => 'Unsupported command: webhook. GoodVibes Agent can send explicit channel messages, but it does not create webhook listeners.',
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export function listGoodVibesCliCommandTokens(): readonly string[] {
|
|
85
|
+
return Object.keys(COMMAND_ALIASES).sort();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function listGoodVibesCliCommands(): readonly GoodVibesCliCommand[] {
|
|
89
|
+
return [...new Set<GoodVibesCliCommand>(['tui', ...Object.values(COMMAND_ALIASES)])].sort();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function listBlockedGoodVibesCliCommandTokens(): readonly string[] {
|
|
93
|
+
return Object.keys(BLOCKED_PRODUCT_COMMAND_HINTS).sort();
|
|
94
|
+
}
|
|
62
95
|
|
|
63
96
|
function createDefaultFlags(): GoodVibesCliFlags {
|
|
64
97
|
return {
|
|
@@ -200,7 +233,7 @@ export function parseGoodVibesCli(
|
|
|
200
233
|
if (!token.startsWith('-') || token === '-') {
|
|
201
234
|
if (!sawCommand) {
|
|
202
235
|
const commandToken = token.toLowerCase();
|
|
203
|
-
if (
|
|
236
|
+
if (BLOCKED_PRODUCT_COMMAND_HINTS[commandToken]) {
|
|
204
237
|
command = 'unknown';
|
|
205
238
|
rawCommand = token;
|
|
206
239
|
sawCommand = true;
|
|
@@ -373,7 +406,8 @@ export function parseGoodVibesCli(
|
|
|
373
406
|
}
|
|
374
407
|
|
|
375
408
|
if (rawCommand !== undefined && command === 'unknown') {
|
|
376
|
-
|
|
409
|
+
const blockedHint = BLOCKED_PRODUCT_COMMAND_HINTS[rawCommand.toLowerCase()];
|
|
410
|
+
errors.push(blockedHint ? blockedHint(binary) : `Unknown command ${rawCommand}`);
|
|
377
411
|
}
|
|
378
412
|
|
|
379
413
|
return {
|
|
@@ -2,17 +2,21 @@ import {
|
|
|
2
2
|
createAgentRuntimeProfile,
|
|
3
3
|
createAgentRuntimeProfileFromDiscovered,
|
|
4
4
|
createAgentRuntimeProfileTemplateFromDiscovered,
|
|
5
|
+
clearAgentRuntimeProfileSelection,
|
|
5
6
|
deleteAgentRuntimeProfile,
|
|
6
7
|
exportAgentRuntimeProfileTemplate,
|
|
7
8
|
importAgentRuntimeProfileTemplate,
|
|
8
9
|
isAgentRuntimeProfileTemplateId,
|
|
9
10
|
listAgentRuntimeProfiles,
|
|
10
11
|
listAgentRuntimeProfileTemplates,
|
|
12
|
+
readAgentRuntimeProfileSelection,
|
|
11
13
|
resolveAgentRuntimeProfileHome,
|
|
14
|
+
setAgentRuntimeProfileSelection,
|
|
12
15
|
type AgentRuntimeProfileTemplateId,
|
|
13
16
|
type AgentRuntimeProfileCommandResult,
|
|
14
17
|
type AgentRuntimeProfileInfo,
|
|
15
18
|
} from '../agent/runtime-profile.ts';
|
|
19
|
+
import { formatAgentRecordSource } from '../agent/record-labels.ts';
|
|
16
20
|
import type { CliCommandOutput, GoodVibesCliParseResult } from './types.ts';
|
|
17
21
|
|
|
18
22
|
interface ProfilesCommandRuntime {
|
|
@@ -53,7 +57,7 @@ function parseTemplate(args: readonly string[]): AgentRuntimeProfileTemplateId |
|
|
|
53
57
|
if (!raw || raw === 'blank') return undefined;
|
|
54
58
|
const normalized = raw.trim().toLowerCase().replace(/_/g, '-');
|
|
55
59
|
if (isAgentRuntimeProfileTemplateId(normalized)) return normalized;
|
|
56
|
-
throw new Error(`Unknown Agent starter profile template
|
|
60
|
+
throw new Error(`Unknown Agent starter profile template ${raw}. Use profiles templates to list starters.`);
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
function parseCsvFlag(args: readonly string[], names: readonly string[]): readonly string[] | undefined {
|
|
@@ -63,16 +67,21 @@ function parseCsvFlag(args: readonly string[], names: readonly string[]): readon
|
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
function profileLine(profile: AgentRuntimeProfileInfo): string {
|
|
66
|
-
const created = profile.createdAt ? ` created
|
|
70
|
+
const created = profile.createdAt ? ` created ${profile.createdAt}` : '';
|
|
67
71
|
const starter = profile.starterTemplateId ? ` starter=${profile.starterTemplateId}` : '';
|
|
68
|
-
return ` ${profile.id} home
|
|
72
|
+
return ` ${profile.id} home ${profile.homeDirectory}${created}${starter}`;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
function renderProfilesResult(result: AgentRuntimeProfileCommandResult): string {
|
|
72
76
|
if (!result.ok) return result.error ?? 'Agent profile command failed.';
|
|
73
77
|
if (result.kind === 'agent.profiles.list') {
|
|
74
78
|
const profiles = result.data?.profiles ?? [];
|
|
75
|
-
if (profiles.length === 0)
|
|
79
|
+
if (profiles.length === 0) {
|
|
80
|
+
return [
|
|
81
|
+
'No Agent profiles',
|
|
82
|
+
' next goodvibes-agent profiles create <name> --template <id> --yes',
|
|
83
|
+
].join('\n');
|
|
84
|
+
}
|
|
76
85
|
return [
|
|
77
86
|
`Agent profiles (${profiles.length})`,
|
|
78
87
|
...profiles.map(profileLine),
|
|
@@ -83,49 +92,71 @@ function renderProfilesResult(result: AgentRuntimeProfileCommandResult): string
|
|
|
83
92
|
return [
|
|
84
93
|
`Agent starter profile templates (${templates.length})`,
|
|
85
94
|
...templates.map((template) => [
|
|
86
|
-
` ${template.id} ${template.name} [${template.source}]`,
|
|
95
|
+
` ${template.id} ${template.name} [${formatAgentRecordSource(template.source).toLowerCase()}]`,
|
|
87
96
|
` ${template.description}`,
|
|
88
|
-
` persona
|
|
89
|
-
` skills
|
|
90
|
-
` routines
|
|
97
|
+
` persona ${template.personaName}`,
|
|
98
|
+
` skills ${template.skillNames.join(', ')}`,
|
|
99
|
+
` routines ${template.routineNames.join(', ')}`,
|
|
91
100
|
].join('\n')),
|
|
92
|
-
'Use
|
|
93
|
-
'Export/edit/import
|
|
101
|
+
'Use goodvibes-agent profiles create <name> --template <id> --yes',
|
|
102
|
+
'Export/edit/import with goodvibes-agent profiles templates export <id> <path> --yes',
|
|
94
103
|
].join('\n');
|
|
95
104
|
}
|
|
96
105
|
if (result.kind === 'agent.profiles.template.export' && result.data?.template && result.data.path) {
|
|
97
106
|
return [
|
|
98
107
|
`Agent starter template exported: ${result.data.template.id}`,
|
|
99
|
-
` path
|
|
100
|
-
' edit the JSON, then import it with
|
|
108
|
+
` path ${result.data.path}`,
|
|
109
|
+
' edit the JSON, then import it with goodvibes-agent profiles templates import <path> --yes',
|
|
101
110
|
].join('\n');
|
|
102
111
|
}
|
|
103
112
|
if (result.kind === 'agent.profiles.template.import' && result.data?.template) {
|
|
104
113
|
return [
|
|
105
114
|
`Agent starter template imported: ${result.data.template.id}`,
|
|
106
|
-
` name
|
|
107
|
-
`
|
|
108
|
-
` use
|
|
115
|
+
` name ${result.data.template.name}`,
|
|
116
|
+
` origin ${formatAgentRecordSource(result.data.template.source)}`,
|
|
117
|
+
` use goodvibes-agent profiles create <name> --template ${result.data.template.id} --yes`,
|
|
109
118
|
].join('\n');
|
|
110
119
|
}
|
|
111
120
|
if (result.kind === 'agent.profiles.template.from_discovered' && result.data?.template) {
|
|
112
121
|
return [
|
|
113
122
|
`Agent starter template created from discovered behavior: ${result.data.template.id}`,
|
|
114
|
-
` name
|
|
115
|
-
` persona
|
|
116
|
-
` skills
|
|
117
|
-
` routines
|
|
118
|
-
` use
|
|
123
|
+
` name ${result.data.template.name}`,
|
|
124
|
+
` persona ${result.data.template.personaName}`,
|
|
125
|
+
` skills ${result.data.template.skillNames.join(', ')}`,
|
|
126
|
+
` routines ${result.data.template.routineNames.join(', ')}`,
|
|
127
|
+
` use goodvibes-agent profiles create <name> --template ${result.data.template.id} --yes`,
|
|
128
|
+
].join('\n');
|
|
129
|
+
}
|
|
130
|
+
if (result.kind === 'agent.profiles.default') {
|
|
131
|
+
const selected = result.data?.selectedProfile;
|
|
132
|
+
if (!selected) {
|
|
133
|
+
return [
|
|
134
|
+
'No default Agent profile selected',
|
|
135
|
+
' next goodvibes-agent profiles use <name> --yes',
|
|
136
|
+
].join('\n');
|
|
137
|
+
}
|
|
138
|
+
return [
|
|
139
|
+
`Default Agent profile: ${selected.id}${selected.exists ? '' : ' (missing)'}`,
|
|
140
|
+
` home ${selected.homeDirectory}`,
|
|
141
|
+
selected.selectedAt ? ` selected ${selected.selectedAt}` : '',
|
|
142
|
+
` next launch: ${result.data?.nextCommand ?? 'goodvibes-agent'}`,
|
|
143
|
+
selected.exists ? '' : ' fix create the profile again or clear it with goodvibes-agent profiles default clear --yes',
|
|
144
|
+
].filter(Boolean).join('\n');
|
|
145
|
+
}
|
|
146
|
+
if (result.kind === 'agent.profiles.default.clear') {
|
|
147
|
+
return [
|
|
148
|
+
'Default Agent profile cleared',
|
|
149
|
+
' next launch uses the base Agent home unless --agent-profile is provided',
|
|
119
150
|
].join('\n');
|
|
120
151
|
}
|
|
121
152
|
if (result.kind === 'agent.profiles.create_from_discovered' && result.data?.profile && result.data.template) {
|
|
122
153
|
return [
|
|
123
154
|
`Agent profile created from discovered behavior: ${result.data.profile.id}`,
|
|
124
|
-
` home
|
|
155
|
+
` home ${result.data.profile.homeDirectory}`,
|
|
125
156
|
` starter: ${result.data.template.id}`,
|
|
126
|
-
` persona
|
|
127
|
-
` skills
|
|
128
|
-
` routines
|
|
157
|
+
` persona ${result.data.template.personaName}`,
|
|
158
|
+
` skills ${result.data.template.skillNames.join(', ')}`,
|
|
159
|
+
` routines ${result.data.template.routineNames.join(', ')}`,
|
|
129
160
|
` launch: ${result.data.nextCommand ?? `goodvibes-agent --agent-profile ${result.data.profile.id}`}`,
|
|
130
161
|
].join('\n');
|
|
131
162
|
}
|
|
@@ -134,16 +165,19 @@ function renderProfilesResult(result: AgentRuntimeProfileCommandResult): string
|
|
|
134
165
|
const template = result.data?.appliedTemplate;
|
|
135
166
|
return [
|
|
136
167
|
`Agent profile created: ${profile.id}`,
|
|
137
|
-
` home
|
|
168
|
+
` home ${profile.homeDirectory}`,
|
|
138
169
|
...(template ? [
|
|
139
170
|
` starter: ${template.id} (${template.name})`,
|
|
140
171
|
` seeded: ${template.personaIds.length} persona, ${template.skillIds.length} skills, ${template.routineIds.length} routine`,
|
|
141
172
|
] : []),
|
|
142
|
-
` use
|
|
173
|
+
` use ${result.data?.nextCommand ?? `goodvibes-agent --agent-profile ${profile.id}`}`,
|
|
143
174
|
].join('\n');
|
|
144
175
|
}
|
|
145
176
|
if (result.kind === 'agent.profiles.delete' && profile) {
|
|
146
|
-
return
|
|
177
|
+
return [
|
|
178
|
+
`Agent profile deleted: ${profile.id}`,
|
|
179
|
+
` id ${profile.id}`,
|
|
180
|
+
].join('\n');
|
|
147
181
|
}
|
|
148
182
|
return 'Agent profile command completed.';
|
|
149
183
|
}
|
|
@@ -296,6 +330,107 @@ export async function handleProfilesCommand(runtime: ProfilesCommandRuntime): Pr
|
|
|
296
330
|
};
|
|
297
331
|
}
|
|
298
332
|
|
|
333
|
+
if (sub === 'default') {
|
|
334
|
+
const target = values[0];
|
|
335
|
+
if (target === 'clear' || target === 'none' || target === 'base') {
|
|
336
|
+
if (!hasYes(rawRest)) {
|
|
337
|
+
const result: AgentRuntimeProfileCommandResult = {
|
|
338
|
+
ok: false,
|
|
339
|
+
kind: 'agent.profiles.error',
|
|
340
|
+
error: 'Refusing to clear the default Agent profile without --yes.',
|
|
341
|
+
};
|
|
342
|
+
return {
|
|
343
|
+
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
344
|
+
exitCode: 2,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
clearAgentRuntimeProfileSelection(runtime.homeDirectory);
|
|
348
|
+
const result: AgentRuntimeProfileCommandResult = {
|
|
349
|
+
ok: true,
|
|
350
|
+
kind: 'agent.profiles.default.clear',
|
|
351
|
+
};
|
|
352
|
+
return {
|
|
353
|
+
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
354
|
+
exitCode: 0,
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
if (target) {
|
|
358
|
+
if (!hasYes(rawRest)) {
|
|
359
|
+
const result: AgentRuntimeProfileCommandResult = {
|
|
360
|
+
ok: false,
|
|
361
|
+
kind: 'agent.profiles.error',
|
|
362
|
+
error: `Refusing to set default Agent profile ${target} without --yes.`,
|
|
363
|
+
};
|
|
364
|
+
return {
|
|
365
|
+
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
366
|
+
exitCode: 2,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
const selected = setAgentRuntimeProfileSelection(runtime.homeDirectory, target);
|
|
370
|
+
const result: AgentRuntimeProfileCommandResult = {
|
|
371
|
+
ok: true,
|
|
372
|
+
kind: 'agent.profiles.default',
|
|
373
|
+
data: {
|
|
374
|
+
selectedProfile: selected,
|
|
375
|
+
nextCommand: 'goodvibes-agent',
|
|
376
|
+
},
|
|
377
|
+
};
|
|
378
|
+
return {
|
|
379
|
+
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
380
|
+
exitCode: 0,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
const selected = readAgentRuntimeProfileSelection(runtime.homeDirectory);
|
|
384
|
+
const result: AgentRuntimeProfileCommandResult = {
|
|
385
|
+
ok: true,
|
|
386
|
+
kind: 'agent.profiles.default',
|
|
387
|
+
data: selected ? { selectedProfile: selected, nextCommand: 'goodvibes-agent' } : undefined,
|
|
388
|
+
};
|
|
389
|
+
return {
|
|
390
|
+
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
391
|
+
exitCode: 0,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (sub === 'use' || sub === 'select' || sub === 'switch') {
|
|
396
|
+
const name = values[0];
|
|
397
|
+
if (!name) {
|
|
398
|
+
const result: AgentRuntimeProfileCommandResult = {
|
|
399
|
+
ok: false,
|
|
400
|
+
kind: 'agent.profiles.error',
|
|
401
|
+
error: 'Usage: goodvibes-agent profiles use <name> --yes',
|
|
402
|
+
};
|
|
403
|
+
return {
|
|
404
|
+
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
405
|
+
exitCode: 2,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
if (!hasYes(rawRest)) {
|
|
409
|
+
const result: AgentRuntimeProfileCommandResult = {
|
|
410
|
+
ok: false,
|
|
411
|
+
kind: 'agent.profiles.error',
|
|
412
|
+
error: `Refusing to set default Agent profile ${name} without --yes.`,
|
|
413
|
+
};
|
|
414
|
+
return {
|
|
415
|
+
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
416
|
+
exitCode: 2,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
const selected = setAgentRuntimeProfileSelection(runtime.homeDirectory, name);
|
|
420
|
+
const result: AgentRuntimeProfileCommandResult = {
|
|
421
|
+
ok: true,
|
|
422
|
+
kind: 'agent.profiles.default',
|
|
423
|
+
data: {
|
|
424
|
+
selectedProfile: selected,
|
|
425
|
+
nextCommand: 'goodvibes-agent',
|
|
426
|
+
},
|
|
427
|
+
};
|
|
428
|
+
return {
|
|
429
|
+
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
430
|
+
exitCode: 0,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
299
434
|
if (sub === 'show' || sub === 'path' || sub === 'home') {
|
|
300
435
|
const name = values[0];
|
|
301
436
|
if (!name) {
|
|
@@ -317,7 +452,7 @@ export async function handleProfilesCommand(runtime: ProfilesCommandRuntime): Pr
|
|
|
317
452
|
data: { profile: info },
|
|
318
453
|
};
|
|
319
454
|
const starter = info.starterTemplateId ? [` starter: ${info.starterTemplateId} (${info.starterTemplateName ?? info.starterTemplateId})`] : [];
|
|
320
|
-
const text = [`Agent profile: ${profile.id}`, ` home
|
|
455
|
+
const text = [`Agent profile: ${profile.id}`, ` home ${profile.homeDirectory}`, ...starter, ` use goodvibes-agent --agent-profile ${profile.id}`].join('\n');
|
|
321
456
|
return {
|
|
322
457
|
output: runtime.cli.flags.outputFormat === 'json' ? JSON.stringify(result, null, 2) : text,
|
|
323
458
|
exitCode: 0,
|
|
@@ -453,8 +588,8 @@ export async function handleProfilesCommand(runtime: ProfilesCommandRuntime): Pr
|
|
|
453
588
|
: {
|
|
454
589
|
ok: false,
|
|
455
590
|
kind: 'agent.profiles.error',
|
|
456
|
-
error: `Agent profile not found
|
|
457
|
-
|
|
591
|
+
error: `Agent profile not found ${resolution.id}`,
|
|
592
|
+
};
|
|
458
593
|
return {
|
|
459
594
|
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
460
595
|
exitCode: deleted ? 0 : 1,
|
|
@@ -464,7 +599,7 @@ export async function handleProfilesCommand(runtime: ProfilesCommandRuntime): Pr
|
|
|
464
599
|
const result: AgentRuntimeProfileCommandResult = {
|
|
465
600
|
ok: false,
|
|
466
601
|
kind: 'agent.profiles.error',
|
|
467
|
-
error: 'Usage: goodvibes-agent profiles [list|templates|show <name>|create <name> [--template <id>] --yes|delete <name> --yes]',
|
|
602
|
+
error: 'Usage: goodvibes-agent profiles [list|templates|default [<name>|clear] --yes|use <name> --yes|show <name>|create <name> [--template <id>] --yes|delete <name> --yes]',
|
|
468
603
|
};
|
|
469
604
|
return {
|
|
470
605
|
output: renderProfilesOutput(result, runtime.cli.flags.outputFormat),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProviderAuthRouteDescriptor } from '@pellux/goodvibes-sdk/platform/providers';
|
|
2
|
+
import { formatProviderAuthRouteId, formatProviderAuthRouteLabel } from '../provider-auth-route-display.ts';
|
|
2
3
|
|
|
3
4
|
function routeUsable(route: ProviderAuthRouteDescriptor): boolean {
|
|
4
5
|
return route.usable ?? route.configured;
|
|
@@ -18,5 +19,5 @@ export function formatProviderAuthRoute(route: ProviderAuthRouteDescriptor): str
|
|
|
18
19
|
route.freshness,
|
|
19
20
|
].filter((part): part is string => Boolean(part));
|
|
20
21
|
const detail = route.detail?.trim();
|
|
21
|
-
return `${route.label} [${route.route}; ${status.join(', ')}]${detail ? ` - ${detail}` : ''}`;
|
|
22
|
+
return `${formatProviderAuthRouteLabel(route.route, route.label)} [${formatProviderAuthRouteId(route.route)}; ${status.join(', ')}]${detail ? ` - ${detail}` : ''}`;
|
|
22
23
|
}
|