@pellux/goodvibes-agent 0.1.117 → 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 +13 -4
- package/README.md +35 -14
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +176073 -170980
- package/docs/README.md +11 -5
- package/docs/channels-remote-and-api.md +50 -0
- package/docs/connected-host.md +3 -3
- package/docs/getting-started.md +29 -15
- 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 +44 -9
- package/docs/tools-and-commands.md +123 -0
- package/docs/voice-and-live-tts.md +51 -0
- package/package.json +2 -5
- 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-registry.ts +15 -14
- package/src/agent/record-labels.ts +107 -0
- package/src/agent/reminder-schedule-format.ts +33 -24
- package/src/agent/reminder-schedule.ts +26 -25
- package/src/agent/routine-registry.ts +13 -12
- 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 +34 -32
- package/src/agent/routine-schedule-receipts.ts +28 -26
- package/src/agent/runtime-profile-starters.ts +2 -2
- package/src/agent/runtime-profile.ts +18 -17
- package/src/agent/skill-registry.ts +25 -24
- package/src/cli/agent-knowledge-args.ts +5 -1
- package/src/cli/agent-knowledge-command.ts +39 -33
- 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 +13 -8
- package/src/cli/config-overrides.ts +37 -36
- package/src/cli/external-runtime.ts +10 -4
- package/src/cli/help.ts +29 -11
- package/src/cli/local-library-command.ts +134 -68
- package/src/cli/management-commands.ts +98 -62
- package/src/cli/management.ts +52 -26
- package/src/cli/memory-command.ts +66 -32
- package/src/cli/parser.ts +37 -24
- package/src/cli/profiles-command.ts +52 -35
- package/src/cli/provider-auth-routes.ts +2 -1
- package/src/cli/routines-command.ts +44 -36
- package/src/cli/service-posture.ts +6 -6
- package/src/cli/status.ts +46 -121
- package/src/core/conversation-message-snapshot.ts +131 -0
- package/src/input/agent-workspace-activation.ts +33 -7
- package/src/input/agent-workspace-basic-command-editor-submission.ts +7 -3
- package/src/input/agent-workspace-basic-command-editors.ts +30 -10
- package/src/input/agent-workspace-categories.ts +276 -64
- package/src/input/agent-workspace-channel-command-editor-submission.ts +34 -0
- package/src/input/agent-workspace-channel-command-editors.ts +23 -5
- package/src/input/agent-workspace-channels.ts +35 -2
- package/src/input/agent-workspace-command-editor.ts +18 -2
- package/src/input/agent-workspace-config-reader.ts +16 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +1 -1
- package/src/input/agent-workspace-editors.ts +140 -2
- package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
- package/src/input/agent-workspace-learned-behavior.ts +2 -2
- package/src/input/agent-workspace-library-command-editor-submission.ts +1 -1
- package/src/input/agent-workspace-library-command-editors.ts +2 -2
- 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-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-editors.ts +1 -1
- package/src/input/agent-workspace-memory-editor.ts +2 -2
- package/src/input/agent-workspace-navigation.ts +38 -2
- package/src/input/agent-workspace-notify-editor-submission.ts +16 -2
- package/src/input/agent-workspace-operations-command-editor-submission.ts +63 -1
- package/src/input/agent-workspace-operations-command-editors.ts +80 -3
- package/src/input/agent-workspace-panel-route.ts +43 -0
- package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
- 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-setup.ts +22 -11
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +6 -6
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +10 -10
- package/src/input/agent-workspace-snapshot.ts +112 -13
- package/src/input/agent-workspace-task-command-editors.ts +4 -4
- package/src/input/agent-workspace-token.ts +18 -2
- package/src/input/agent-workspace-types.ts +92 -4
- package/src/input/agent-workspace-voice-media.ts +3 -6
- package/src/input/agent-workspace-web-research-editor.ts +104 -0
- package/src/input/agent-workspace.ts +136 -208
- package/src/input/command-registry.ts +4 -1
- package/src/input/commands/agent-runtime-profile-runtime.ts +45 -41
- package/src/input/commands/agent-skills-runtime.ts +83 -70
- package/src/input/commands/agent-workspace-runtime.ts +23 -7
- package/src/input/commands/brief-runtime.ts +25 -24
- package/src/input/commands/channels-runtime.ts +145 -31
- 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 +140 -115
- package/src/input/commands/knowledge.ts +57 -56
- package/src/input/commands/local-provider-runtime.ts +36 -18
- package/src/input/commands/local-runtime.ts +138 -16
- package/src/input/commands/local-setup-review.ts +7 -7
- package/src/input/commands/mcp-runtime.ts +56 -35
- 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 -17
- package/src/input/commands/personas-runtime.ts +45 -30
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +29 -29
- package/src/input/commands/provider-accounts-runtime.ts +60 -39
- package/src/input/commands/qrcode-runtime.ts +45 -6
- 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 +59 -43
- package/src/input/commands/schedule-runtime.ts +33 -20
- package/src/input/commands/security-runtime.ts +4 -4
- package/src/input/commands/session-content.ts +80 -78
- package/src/input/commands/session-workflow.ts +132 -93
- package/src/input/commands/session.ts +3 -174
- package/src/input/commands/shell-core.ts +32 -17
- package/src/input/commands/subscription-runtime.ts +53 -179
- package/src/input/commands/tasks-runtime.ts +20 -20
- package/src/input/commands/work-plan-runtime.ts +33 -8
- package/src/input/commands.ts +2 -2
- package/src/input/feed-context-factory.ts +2 -1
- 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 -1
- package/src/input/handler-feed-routes.ts +19 -12
- package/src/input/handler-feed.ts +6 -3
- package/src/input/handler-interactions.ts +7 -5
- package/src/input/handler-modal-stack.ts +3 -3
- package/src/input/handler-onboarding.ts +24 -80
- package/src/input/handler-shortcuts.ts +15 -4
- package/src/input/handler.ts +47 -17
- package/src/input/input-history.ts +5 -6
- package/src/input/keybindings.ts +22 -11
- package/src/input/onboarding/onboarding-wizard-apply.ts +13 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +147 -57
- package/src/input/onboarding/onboarding-wizard-steps.ts +46 -29
- package/src/input/onboarding/onboarding-wizard-types.ts +3 -1
- package/src/input/onboarding/onboarding-wizard.ts +68 -0
- package/src/input/profile-picker-modal.ts +31 -12
- package/src/input/session-picker-modal.ts +21 -4
- 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 +6 -52
- package/src/input/submission-intent.ts +0 -1
- package/src/input/submission-router.ts +3 -3
- package/src/main.ts +18 -8
- package/src/panels/approval-panel.ts +8 -8
- package/src/panels/automation-control-panel.ts +2 -2
- package/src/panels/base-panel.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +1 -10
- package/src/panels/builtin/session.ts +9 -9
- package/src/panels/builtin/shared.ts +2 -2
- 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 +18 -11
- 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 +45 -4
- package/src/panels/provider-health-panel.ts +5 -4
- package/src/panels/qr-panel.ts +1 -1
- 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 +3 -3
- package/src/panels/system-messages-panel.ts +1 -1
- package/src/panels/tasks-panel.ts +20 -13
- 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 +1 -1
- package/src/provider-auth-route-display.ts +9 -0
- package/src/renderer/agent-workspace-style.ts +34 -0
- package/src/renderer/agent-workspace.ts +228 -52
- package/src/renderer/autocomplete-overlay.ts +25 -6
- 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 +106 -33
- package/src/renderer/history-search-overlay.ts +19 -4
- package/src/renderer/live-tail-modal.ts +27 -5
- package/src/renderer/mcp-workspace.ts +164 -50
- package/src/renderer/model-picker-overlay.ts +58 -2
- package/src/renderer/model-workspace.ts +104 -20
- package/src/renderer/process-modal.ts +27 -6
- package/src/renderer/profile-picker-modal.ts +20 -4
- 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 +83 -50
- package/src/renderer/tool-call.ts +20 -11
- package/src/runtime/agent-runtime-events.ts +6 -6
- package/src/runtime/bootstrap-command-context.ts +7 -1
- package/src/runtime/bootstrap-command-parts.ts +9 -7
- package/src/runtime/bootstrap-core.ts +19 -1
- package/src/runtime/bootstrap-hook-bridge.ts +7 -18
- package/src/runtime/bootstrap-shell.ts +4 -4
- package/src/runtime/bootstrap.ts +31 -22
- package/src/runtime/connected-host-auth.ts +7 -2
- package/src/runtime/diagnostics/panels/index.ts +2 -2
- package/src/runtime/diagnostics/panels/policy.ts +7 -7
- package/src/runtime/index.ts +2 -1
- package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
- package/src/runtime/onboarding/apply.ts +80 -79
- package/src/runtime/onboarding/derivation.ts +5 -8
- package/src/runtime/onboarding/snapshot.ts +0 -15
- package/src/runtime/onboarding/types.ts +8 -19
- package/src/runtime/onboarding/verify.ts +32 -10
- package/src/runtime/operator-token-cleanup.ts +1 -1
- package/src/runtime/services.ts +91 -22
- 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/ui-openers.ts +3 -13
- 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 +269 -69
- 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 +8 -8
- package/src/tools/agent-work-plan-tool.ts +256 -0
- package/src/version.ts +1 -1
- package/src/input/commands/policy-dispatch.ts +0 -339
- package/src/input/commands/policy.ts +0 -13
- 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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createShellPathService } from '@/runtime/index.ts';
|
|
2
2
|
import { discoverPersonas, type DiscoveredPersonaRecord } from '../agent/persona-discovery.ts';
|
|
3
3
|
import { AgentPersonaRegistry, type AgentPersonaRecord } from '../agent/persona-registry.ts';
|
|
4
|
+
import { formatAgentRecordOrigin, formatAgentRecordReviewState } from '../agent/record-labels.ts';
|
|
4
5
|
import { discoverSkills, type SkillRecord } from '../agent/skill-discovery.ts';
|
|
5
6
|
import {
|
|
6
7
|
AgentSkillRegistry,
|
|
@@ -122,8 +123,8 @@ function shellPaths(runtime: CliCommandRuntime): ReturnType<typeof createShellPa
|
|
|
122
123
|
|
|
123
124
|
function summarizePersona(persona: AgentPersonaRecord, activePersonaId: string | null): string {
|
|
124
125
|
const active = persona.id === activePersonaId ? 'active' : 'available';
|
|
125
|
-
const tags = persona.tags.length > 0 ? `
|
|
126
|
-
return ` ${persona.id} ${active} ${persona.reviewState} ${persona.name} - ${persona.description}${tags}`;
|
|
126
|
+
const tags = persona.tags.length > 0 ? ` tags ${persona.tags.join(', ')}` : '';
|
|
127
|
+
return ` ${persona.id} ${active} ${formatAgentRecordReviewState(persona.reviewState)} ${persona.name} - ${persona.description}${tags}`;
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
function renderPersonaList(title: string, path: string, personas: readonly AgentPersonaRecord[], activePersonaId: string | null): string {
|
|
@@ -131,12 +132,13 @@ function renderPersonaList(title: string, path: string, personas: readonly Agent
|
|
|
131
132
|
return [
|
|
132
133
|
title,
|
|
133
134
|
' No local Agent personas yet.',
|
|
135
|
+
' No Agent-local personas yet.',
|
|
134
136
|
' Create one with: goodvibes-agent personas create --name <name> --description <summary> --body <instructions>',
|
|
135
137
|
].join('\n');
|
|
136
138
|
}
|
|
137
139
|
return [
|
|
138
140
|
`${title} (${personas.length})`,
|
|
139
|
-
` store
|
|
141
|
+
` store ${path}`,
|
|
140
142
|
...personas.map((persona) => summarizePersona(persona, activePersonaId)),
|
|
141
143
|
].join('\n');
|
|
142
144
|
}
|
|
@@ -144,11 +146,10 @@ function renderPersonaList(title: string, path: string, personas: readonly Agent
|
|
|
144
146
|
function renderPersona(persona: AgentPersonaRecord, activePersonaId: string | null): string {
|
|
145
147
|
return [
|
|
146
148
|
`Persona ${persona.name}`,
|
|
147
|
-
` id
|
|
149
|
+
` id ${persona.id}`,
|
|
148
150
|
` active: ${persona.id === activePersonaId ? 'yes' : 'no'}`,
|
|
149
|
-
` review: ${persona.reviewState}`,
|
|
150
|
-
`
|
|
151
|
-
` provenance: ${persona.provenance}`,
|
|
151
|
+
` review: ${formatAgentRecordReviewState(persona.reviewState)}`,
|
|
152
|
+
` origin: ${formatAgentRecordOrigin(persona.source, persona.provenance)}`,
|
|
152
153
|
` tags: ${persona.tags.join(', ') || '(none)'}`,
|
|
153
154
|
` triggers: ${persona.triggers.join(', ') || '(manual)'}`,
|
|
154
155
|
` created: ${persona.createdAt}`,
|
|
@@ -165,7 +166,7 @@ function summarizeDiscoveredPersona(persona: DiscoveredPersonaRecord): string {
|
|
|
165
166
|
const description = persona.description ? ` - ${persona.description}` : '';
|
|
166
167
|
return [
|
|
167
168
|
` ${persona.name} ${persona.origin}${description}`,
|
|
168
|
-
` path
|
|
169
|
+
` path ${persona.path}`,
|
|
169
170
|
].join('\n');
|
|
170
171
|
}
|
|
171
172
|
|
|
@@ -207,10 +208,10 @@ function discoveredPersonaFrontmatterList(persona: DiscoveredPersonaRecord, key:
|
|
|
207
208
|
|
|
208
209
|
function summarizeSkill(skill: AgentSkillRecord): string {
|
|
209
210
|
const enabled = skill.enabled ? 'enabled' : 'disabled';
|
|
210
|
-
const tags = skill.tags.length > 0 ? `
|
|
211
|
+
const tags = skill.tags.length > 0 ? ` tags ${skill.tags.join(', ')}` : '';
|
|
211
212
|
const readiness = evaluateAgentSkillReadiness(skill);
|
|
212
213
|
const ready = readiness.ready ? 'ready' : `needs ${readiness.missing.map(formatAgentSkillRequirement).join(',')}`;
|
|
213
|
-
return ` ${skill.id} ${enabled} ${skill.reviewState} ${ready} ${skill.name} - ${skill.description}${tags}`;
|
|
214
|
+
return ` ${skill.id} ${enabled} ${formatAgentRecordReviewState(skill.reviewState)} ${ready} ${skill.name} - ${skill.description}${tags}`;
|
|
214
215
|
}
|
|
215
216
|
|
|
216
217
|
function summarizeBundle(bundle: AgentSkillBundleRecord, skills: readonly AgentSkillRecord[]): string {
|
|
@@ -221,31 +222,32 @@ function summarizeBundle(bundle: AgentSkillBundleRecord, skills: readonly AgentS
|
|
|
221
222
|
...readiness.missingSkillIds.map((skillId) => `skill:${skillId}`),
|
|
222
223
|
];
|
|
223
224
|
const ready = readiness.ready ? 'ready' : `needs ${missing.join(',')}`;
|
|
224
|
-
return ` ${bundle.id} ${enabled} ${bundle.reviewState} ${ready} ${bundle.name} - ${bundle.description} skills
|
|
225
|
+
return ` ${bundle.id} ${enabled} ${formatAgentRecordReviewState(bundle.reviewState)} ${ready} ${bundle.name} - ${bundle.description} skills ${bundle.skillIds.join(',')}`;
|
|
225
226
|
}
|
|
226
227
|
|
|
227
228
|
function renderSkillList(title: string, path: string, skills: readonly AgentSkillRecord[], emptyMessage?: string): string {
|
|
228
229
|
if (skills.length === 0) {
|
|
229
230
|
return [
|
|
230
231
|
title,
|
|
231
|
-
|
|
232
|
+
emptyMessage ? '' : ' No local Agent skills yet.',
|
|
233
|
+
` ${emptyMessage ?? 'No Agent-local skills yet.'}`,
|
|
232
234
|
emptyMessage ? '' : ' Create one with: goodvibes-agent skills create --name <name> --description <summary> --procedure <steps>',
|
|
233
235
|
].filter(Boolean).join('\n');
|
|
234
236
|
}
|
|
235
237
|
return [
|
|
236
238
|
`${title} (${skills.length})`,
|
|
237
|
-
` store
|
|
239
|
+
` store ${path}`,
|
|
238
240
|
...skills.map(summarizeSkill),
|
|
239
241
|
].join('\n');
|
|
240
242
|
}
|
|
241
243
|
|
|
242
244
|
function summarizeDiscoveredSkill(skill: SkillRecord): string {
|
|
243
245
|
const description = skill.description ? ` - ${skill.description}` : '';
|
|
244
|
-
const dependencies = skill.dependencies.length > 0 ? `
|
|
245
|
-
const includes = skill.includes.length > 0 ? `
|
|
246
|
+
const dependencies = skill.dependencies.length > 0 ? ` dependencies ${skill.dependencies.join(', ')}` : '';
|
|
247
|
+
const includes = skill.includes.length > 0 ? ` includes ${skill.includes.join(', ')}` : '';
|
|
246
248
|
return [
|
|
247
249
|
` ${skill.name} ${skill.origin}${description}${dependencies}${includes}`,
|
|
248
|
-
` path
|
|
250
|
+
` path ${skill.path}`,
|
|
249
251
|
].join('\n');
|
|
250
252
|
}
|
|
251
253
|
|
|
@@ -297,13 +299,13 @@ function renderBundleList(title: string, path: string, bundles: readonly AgentSk
|
|
|
297
299
|
if (bundles.length === 0) {
|
|
298
300
|
return [
|
|
299
301
|
title,
|
|
300
|
-
` ${emptyMessage ?? 'No local
|
|
302
|
+
` ${emptyMessage ?? 'No Agent-local skill bundles yet.'}`,
|
|
301
303
|
emptyMessage ? '' : ' Create one with: goodvibes-agent skills bundle create --name <name> --description <summary> --skills <id,id>',
|
|
302
304
|
].filter(Boolean).join('\n');
|
|
303
305
|
}
|
|
304
306
|
return [
|
|
305
307
|
`${title} (${bundles.length})`,
|
|
306
|
-
` store
|
|
308
|
+
` store ${path}`,
|
|
307
309
|
...bundles.map((bundle) => summarizeBundle(bundle, skills)),
|
|
308
310
|
].join('\n');
|
|
309
311
|
}
|
|
@@ -312,14 +314,13 @@ function renderSkill(skill: AgentSkillRecord): string {
|
|
|
312
314
|
const readiness = evaluateAgentSkillReadiness(skill);
|
|
313
315
|
return [
|
|
314
316
|
`Skill ${skill.name}`,
|
|
315
|
-
` id
|
|
317
|
+
` id ${skill.id}`,
|
|
316
318
|
` enabled: ${skill.enabled ? 'yes' : 'no'}`,
|
|
317
319
|
` readiness: ${readiness.ready ? 'ready' : 'needs setup'}`,
|
|
318
320
|
` requirements: ${skill.requirements.map(formatAgentSkillRequirement).join(', ') || '(none)'}`,
|
|
319
321
|
readiness.missing.length > 0 ? ` missing: ${readiness.missing.map(formatAgentSkillRequirement).join(', ')}` : '',
|
|
320
|
-
` review: ${skill.reviewState}`,
|
|
321
|
-
`
|
|
322
|
-
` provenance: ${skill.provenance}`,
|
|
322
|
+
` review: ${formatAgentRecordReviewState(skill.reviewState)}`,
|
|
323
|
+
` origin: ${formatAgentRecordOrigin(skill.source, skill.provenance)}`,
|
|
323
324
|
` tags: ${skill.tags.join(', ') || '(none)'}`,
|
|
324
325
|
` triggers: ${skill.triggers.join(', ') || '(manual)'}`,
|
|
325
326
|
` created: ${skill.createdAt}`,
|
|
@@ -340,13 +341,12 @@ function renderBundle(bundle: AgentSkillBundleRecord, skills: readonly AgentSkil
|
|
|
340
341
|
];
|
|
341
342
|
return [
|
|
342
343
|
`Skill bundle ${bundle.name}`,
|
|
343
|
-
` id
|
|
344
|
+
` id ${bundle.id}`,
|
|
344
345
|
` enabled: ${bundle.enabled ? 'yes' : 'no'}`,
|
|
345
346
|
` readiness: ${readiness.ready ? 'ready' : 'needs setup'}`,
|
|
346
347
|
missing.length > 0 ? ` missing: ${missing.join(', ')}` : '',
|
|
347
|
-
` review: ${bundle.reviewState}`,
|
|
348
|
-
`
|
|
349
|
-
` provenance: ${bundle.provenance}`,
|
|
348
|
+
` review: ${formatAgentRecordReviewState(bundle.reviewState)}`,
|
|
349
|
+
` origin: ${formatAgentRecordOrigin(bundle.source, bundle.provenance)}`,
|
|
350
350
|
` skills: ${bundle.skillIds.join(', ')}`,
|
|
351
351
|
` created: ${bundle.createdAt}`,
|
|
352
352
|
` updated: ${bundle.updatedAt}`,
|
|
@@ -398,17 +398,17 @@ export async function handlePersonasCommand(runtime: CliCommandRuntime): Promise
|
|
|
398
398
|
if (!name) return failure(runtime, 'invalid_persona_command', 'Usage: goodvibes-agent personas import-discovered <name> [--use] --yes', 2);
|
|
399
399
|
const discovered = findDiscoveredPersona(await discoverPersonas(shellPaths(runtime)), name);
|
|
400
400
|
if (!discovered) {
|
|
401
|
-
return failure(runtime, 'persona_discovery_not_found', `Unknown discovered Agent persona
|
|
401
|
+
return failure(runtime, 'persona_discovery_not_found', `Unknown discovered Agent persona ${name}\nRun goodvibes-agent personas discover to inspect available persona files.`, 1);
|
|
402
402
|
}
|
|
403
403
|
if (!hasFlag(options, 'yes')) {
|
|
404
404
|
return success(runtime, 'agent.personas.import_discovered.preview', { persona: discovered }, [
|
|
405
405
|
'Agent persona import preview',
|
|
406
|
-
` name
|
|
407
|
-
` origin
|
|
408
|
-
` path
|
|
409
|
-
` description
|
|
410
|
-
` body characters
|
|
411
|
-
' next
|
|
406
|
+
` name ${discovered.name}`,
|
|
407
|
+
` origin ${discovered.origin}`,
|
|
408
|
+
` path ${discovered.path}`,
|
|
409
|
+
` description ${discovered.description || '(none)'}`,
|
|
410
|
+
` body characters ${discovered.body.length}`,
|
|
411
|
+
' next rerun with --yes to import into the Agent-local persona registry',
|
|
412
412
|
].join('\n'));
|
|
413
413
|
}
|
|
414
414
|
const persona = registry.create({
|
|
@@ -421,7 +421,11 @@ export async function handlePersonasCommand(runtime: CliCommandRuntime): Promise
|
|
|
421
421
|
provenance: `discovered:${discovered.origin}:${discovered.path}`,
|
|
422
422
|
});
|
|
423
423
|
if (hasFlag(options, 'use')) registry.setActive(persona.id);
|
|
424
|
-
return success(runtime, 'agent.personas.import_discovered', persona,
|
|
424
|
+
return success(runtime, 'agent.personas.import_discovered', persona, [
|
|
425
|
+
`Imported Agent persona ${persona.id}: ${persona.name}${hasFlag(options, 'use') ? ' (active)' : ''}`,
|
|
426
|
+
` name ${persona.name}`,
|
|
427
|
+
` active ${hasFlag(options, 'use') ? 'yes' : 'no'}`,
|
|
428
|
+
].join('\n'));
|
|
425
429
|
}
|
|
426
430
|
if (normalized === 'search' || normalized === 'find') {
|
|
427
431
|
const query = rest.join(' ').trim();
|
|
@@ -432,7 +436,7 @@ export async function handlePersonasCommand(runtime: CliCommandRuntime): Promise
|
|
|
432
436
|
const id = rest[0];
|
|
433
437
|
if (!id) return failure(runtime, 'invalid_persona_command', 'Usage: goodvibes-agent personas show <id>', 2);
|
|
434
438
|
const persona = registry.get(id);
|
|
435
|
-
if (!persona) return failure(runtime, 'persona_not_found', `Unknown Agent persona
|
|
439
|
+
if (!persona) return failure(runtime, 'persona_not_found', `Unknown Agent persona ${id}`, 1);
|
|
436
440
|
return success(runtime, 'agent.personas.show', persona, renderPersona(persona, snapshot.activePersonaId));
|
|
437
441
|
}
|
|
438
442
|
if (normalized === 'create') {
|
|
@@ -443,10 +447,15 @@ export async function handlePersonasCommand(runtime: CliCommandRuntime): Promise
|
|
|
443
447
|
body: requiredOption(options, 'body', 'Usage: goodvibes-agent personas create --name <name> --description <summary> --body <instructions>'),
|
|
444
448
|
tags: csvOption(options, 'tags'),
|
|
445
449
|
triggers: csvOption(options, 'triggers'),
|
|
446
|
-
provenance: optionValue(options, 'provenance') ?? '
|
|
450
|
+
provenance: optionValue(options, 'provenance') ?? 'Command',
|
|
447
451
|
});
|
|
448
452
|
if (hasFlag(options, 'use')) registry.setActive(persona.id);
|
|
449
|
-
return success(runtime, 'agent.personas.create', persona,
|
|
453
|
+
return success(runtime, 'agent.personas.create', persona, [
|
|
454
|
+
'Agent persona created',
|
|
455
|
+
` id ${persona.id}`,
|
|
456
|
+
hasFlag(options, 'use') ? ' (active)' : '',
|
|
457
|
+
` active ${hasFlag(options, 'use') ? 'yes' : 'no'}`,
|
|
458
|
+
].filter(Boolean).join('\n'));
|
|
450
459
|
}
|
|
451
460
|
if (normalized === 'update') {
|
|
452
461
|
const id = rest[0];
|
|
@@ -460,13 +469,19 @@ export async function handlePersonasCommand(runtime: CliCommandRuntime): Promise
|
|
|
460
469
|
triggers: csvOption(options, 'triggers'),
|
|
461
470
|
provenance: optionValue(options, 'provenance'),
|
|
462
471
|
});
|
|
463
|
-
return success(runtime, 'agent.personas.update', persona,
|
|
472
|
+
return success(runtime, 'agent.personas.update', persona, [
|
|
473
|
+
'Agent persona updated',
|
|
474
|
+
` id ${persona.id}`,
|
|
475
|
+
].join('\n'));
|
|
464
476
|
}
|
|
465
477
|
if (normalized === 'use') {
|
|
466
478
|
const id = rest[0];
|
|
467
479
|
if (!id) return failure(runtime, 'invalid_persona_command', 'Usage: goodvibes-agent personas use <id>', 2);
|
|
468
480
|
const persona = registry.setActive(id);
|
|
469
|
-
return success(runtime, 'agent.personas.use', persona,
|
|
481
|
+
return success(runtime, 'agent.personas.use', persona, [
|
|
482
|
+
'Active Agent persona',
|
|
483
|
+
` id ${persona.id}`,
|
|
484
|
+
].join('\n'));
|
|
470
485
|
}
|
|
471
486
|
if (normalized === 'clear') {
|
|
472
487
|
registry.clearActive();
|
|
@@ -476,13 +491,19 @@ export async function handlePersonasCommand(runtime: CliCommandRuntime): Promise
|
|
|
476
491
|
const id = rest[0];
|
|
477
492
|
if (!id) return failure(runtime, 'invalid_persona_command', 'Usage: goodvibes-agent personas review <id>', 2);
|
|
478
493
|
const persona = registry.markReviewed(id);
|
|
479
|
-
return success(runtime, 'agent.personas.review', persona,
|
|
494
|
+
return success(runtime, 'agent.personas.review', persona, [
|
|
495
|
+
'Agent persona reviewed',
|
|
496
|
+
` id ${persona.id}`,
|
|
497
|
+
].join('\n'));
|
|
480
498
|
}
|
|
481
499
|
if (normalized === 'stale') {
|
|
482
500
|
const id = rest[0];
|
|
483
501
|
if (!id || rest.length < 2) return failure(runtime, 'invalid_persona_command', 'Usage: goodvibes-agent personas stale <id> <reason>', 2);
|
|
484
502
|
const persona = registry.markStale(id, rest.slice(1).join(' '));
|
|
485
|
-
return success(runtime, 'agent.personas.stale', persona,
|
|
503
|
+
return success(runtime, 'agent.personas.stale', persona, [
|
|
504
|
+
'Agent persona marked stale',
|
|
505
|
+
` id ${persona.id}`,
|
|
506
|
+
].join('\n'));
|
|
486
507
|
}
|
|
487
508
|
if (normalized === 'delete' || normalized === 'remove' || normalized === 'rm') {
|
|
488
509
|
const options = parseOptions(rest);
|
|
@@ -490,7 +511,10 @@ export async function handlePersonasCommand(runtime: CliCommandRuntime): Promise
|
|
|
490
511
|
if (!id) return failure(runtime, 'invalid_persona_command', 'Usage: goodvibes-agent personas delete <id> --yes', 2);
|
|
491
512
|
if (!hasFlag(options, 'yes')) return failure(runtime, 'confirmation_required', `Refusing to delete Agent persona ${id} without --yes.`, 2);
|
|
492
513
|
const persona = registry.deletePersona(id);
|
|
493
|
-
return success(runtime, 'agent.personas.delete', persona,
|
|
514
|
+
return success(runtime, 'agent.personas.delete', persona, [
|
|
515
|
+
`Agent persona deleted: ${id}`,
|
|
516
|
+
` id ${persona.id}`,
|
|
517
|
+
].join('\n'));
|
|
494
518
|
}
|
|
495
519
|
return failure(runtime, 'invalid_persona_command', usagePersonas(), 2);
|
|
496
520
|
} catch (error) {
|
|
@@ -520,7 +544,7 @@ function skillPayloadFromOptions(options: ParsedOptions): {
|
|
|
520
544
|
commands: csvOption(options, 'requires-command') ?? csvOption(options, 'requires-commands'),
|
|
521
545
|
}),
|
|
522
546
|
enabled: hasFlag(options, 'enabled') ? true : undefined,
|
|
523
|
-
provenance: optionValue(options, 'provenance') ?? '
|
|
547
|
+
provenance: optionValue(options, 'provenance') ?? 'Command',
|
|
524
548
|
};
|
|
525
549
|
}
|
|
526
550
|
|
|
@@ -538,7 +562,7 @@ async function handleSkillBundleCommand(runtime: CliCommandRuntime, args: readon
|
|
|
538
562
|
}
|
|
539
563
|
if (normalized === 'attention' || normalized === 'needs-setup') {
|
|
540
564
|
const bundles = snapshot.bundles.filter((bundle) => !evaluateAgentSkillBundleReadiness(bundle, snapshot.skills).ready);
|
|
541
|
-
return success(runtime, 'agent.skills.bundles.attention', { path: snapshot.path, bundles }, renderBundleList('Agent skill bundles needing setup', snapshot.path, bundles, snapshot.skills, 'No local
|
|
565
|
+
return success(runtime, 'agent.skills.bundles.attention', { path: snapshot.path, bundles }, renderBundleList('Agent skill bundles needing setup', snapshot.path, bundles, snapshot.skills, 'No Agent-local skill bundles need setup.'));
|
|
542
566
|
}
|
|
543
567
|
if (normalized === 'search' || normalized === 'find') {
|
|
544
568
|
const query = rest.join(' ').trim();
|
|
@@ -549,7 +573,7 @@ async function handleSkillBundleCommand(runtime: CliCommandRuntime, args: readon
|
|
|
549
573
|
const id = rest[0];
|
|
550
574
|
if (!id) return failure(runtime, 'invalid_skill_bundle_command', 'Usage: goodvibes-agent skills bundle show <id>', 2);
|
|
551
575
|
const bundle = registry.getBundle(id);
|
|
552
|
-
if (!bundle) return failure(runtime, 'skill_bundle_not_found', `Unknown Agent skill bundle
|
|
576
|
+
if (!bundle) return failure(runtime, 'skill_bundle_not_found', `Unknown Agent skill bundle ${id}`, 1);
|
|
553
577
|
return success(runtime, 'agent.skills.bundles.show', bundle, renderBundle(bundle, snapshot.skills));
|
|
554
578
|
}
|
|
555
579
|
if (normalized === 'create') {
|
|
@@ -560,9 +584,12 @@ async function handleSkillBundleCommand(runtime: CliCommandRuntime, args: readon
|
|
|
560
584
|
description: requiredOption(options, 'description', usage),
|
|
561
585
|
skillIds: requiredOption(options, 'skills', usage).split(',').map((entry) => entry.trim()).filter(Boolean),
|
|
562
586
|
enabled: hasFlag(options, 'enabled'),
|
|
563
|
-
provenance: optionValue(options, 'provenance') ?? '
|
|
587
|
+
provenance: optionValue(options, 'provenance') ?? 'Command',
|
|
564
588
|
});
|
|
565
|
-
return success(runtime, 'agent.skills.bundles.create', bundle,
|
|
589
|
+
return success(runtime, 'agent.skills.bundles.create', bundle, [
|
|
590
|
+
'Agent skill bundle created',
|
|
591
|
+
` id ${bundle.id}`,
|
|
592
|
+
].join('\n'));
|
|
566
593
|
}
|
|
567
594
|
if (normalized === 'update') {
|
|
568
595
|
const id = rest[0];
|
|
@@ -574,25 +601,37 @@ async function handleSkillBundleCommand(runtime: CliCommandRuntime, args: readon
|
|
|
574
601
|
skillIds: csvOption(options, 'skills'),
|
|
575
602
|
provenance: optionValue(options, 'provenance'),
|
|
576
603
|
});
|
|
577
|
-
return success(runtime, 'agent.skills.bundles.update', bundle,
|
|
604
|
+
return success(runtime, 'agent.skills.bundles.update', bundle, [
|
|
605
|
+
'Agent skill bundle updated',
|
|
606
|
+
` id ${bundle.id}`,
|
|
607
|
+
].join('\n'));
|
|
578
608
|
}
|
|
579
609
|
if (normalized === 'enable' || normalized === 'disable') {
|
|
580
610
|
const id = rest[0];
|
|
581
611
|
if (!id) return failure(runtime, 'invalid_skill_bundle_command', `Usage: goodvibes-agent skills bundle ${normalized} <id>`, 2);
|
|
582
612
|
const bundle = registry.setBundleEnabled(id, normalized === 'enable');
|
|
583
|
-
return success(runtime, `agent.skills.bundles.${normalized}`, bundle,
|
|
613
|
+
return success(runtime, `agent.skills.bundles.${normalized}`, bundle, [
|
|
614
|
+
`Agent skill bundle ${normalized === 'enable' ? 'enabled' : 'disabled'}`,
|
|
615
|
+
` id ${bundle.id}`,
|
|
616
|
+
].join('\n'));
|
|
584
617
|
}
|
|
585
618
|
if (normalized === 'review') {
|
|
586
619
|
const id = rest[0];
|
|
587
620
|
if (!id) return failure(runtime, 'invalid_skill_bundle_command', 'Usage: goodvibes-agent skills bundle review <id>', 2);
|
|
588
621
|
const bundle = registry.markBundleReviewed(id);
|
|
589
|
-
return success(runtime, 'agent.skills.bundles.review', bundle,
|
|
622
|
+
return success(runtime, 'agent.skills.bundles.review', bundle, [
|
|
623
|
+
'Agent skill bundle reviewed',
|
|
624
|
+
` id ${bundle.id}`,
|
|
625
|
+
].join('\n'));
|
|
590
626
|
}
|
|
591
627
|
if (normalized === 'stale') {
|
|
592
628
|
const id = rest[0];
|
|
593
629
|
if (!id || rest.length < 2) return failure(runtime, 'invalid_skill_bundle_command', 'Usage: goodvibes-agent skills bundle stale <id> <reason>', 2);
|
|
594
630
|
const bundle = registry.markBundleStale(id, rest.slice(1).join(' '));
|
|
595
|
-
return success(runtime, 'agent.skills.bundles.stale', bundle,
|
|
631
|
+
return success(runtime, 'agent.skills.bundles.stale', bundle, [
|
|
632
|
+
'Agent skill bundle marked stale',
|
|
633
|
+
` id ${bundle.id}`,
|
|
634
|
+
].join('\n'));
|
|
596
635
|
}
|
|
597
636
|
if (normalized === 'delete' || normalized === 'remove' || normalized === 'rm') {
|
|
598
637
|
const options = parseOptions(rest);
|
|
@@ -600,7 +639,10 @@ async function handleSkillBundleCommand(runtime: CliCommandRuntime, args: readon
|
|
|
600
639
|
if (!id) return failure(runtime, 'invalid_skill_bundle_command', 'Usage: goodvibes-agent skills bundle delete <id> --yes', 2);
|
|
601
640
|
if (!hasFlag(options, 'yes')) return failure(runtime, 'confirmation_required', `Refusing to delete Agent skill bundle ${id} without --yes.`, 2);
|
|
602
641
|
const bundle = registry.deleteBundle(id);
|
|
603
|
-
return success(runtime, 'agent.skills.bundles.delete', bundle,
|
|
642
|
+
return success(runtime, 'agent.skills.bundles.delete', bundle, [
|
|
643
|
+
'Agent skill bundle deleted',
|
|
644
|
+
` id ${bundle.id}`,
|
|
645
|
+
].join('\n'));
|
|
604
646
|
}
|
|
605
647
|
return failure(runtime, 'invalid_skill_bundle_command', usageBundles(), 2);
|
|
606
648
|
} catch (error) {
|
|
@@ -629,7 +671,7 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
629
671
|
}
|
|
630
672
|
if (normalized === 'attention' || normalized === 'needs-setup') {
|
|
631
673
|
const skills = snapshot.skills.filter((skill) => !evaluateAgentSkillReadiness(skill).ready);
|
|
632
|
-
return success(runtime, 'agent.skills.attention', { path: snapshot.path, skills }, renderSkillList('Agent skills needing setup', snapshot.path, skills, 'No local
|
|
674
|
+
return success(runtime, 'agent.skills.attention', { path: snapshot.path, skills }, renderSkillList('Agent skills needing setup', snapshot.path, skills, 'No Agent-local skills need setup.'));
|
|
633
675
|
}
|
|
634
676
|
if (normalized === 'discover') {
|
|
635
677
|
const discovered = await discoverSkills(shellPaths(runtime));
|
|
@@ -641,17 +683,17 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
641
683
|
if (!name) return failure(runtime, 'invalid_skill_command', 'Usage: goodvibes-agent skills import-discovered <name> [--enabled] --yes', 2);
|
|
642
684
|
const discovered = findDiscoveredSkill(await discoverSkills(shellPaths(runtime)), name);
|
|
643
685
|
if (!discovered) {
|
|
644
|
-
return failure(runtime, 'skill_discovery_not_found', `Unknown discovered Agent skill
|
|
686
|
+
return failure(runtime, 'skill_discovery_not_found', `Unknown discovered Agent skill ${name}\nRun goodvibes-agent skills discover to inspect available skill files.`, 1);
|
|
645
687
|
}
|
|
646
688
|
if (!hasFlag(options, 'yes')) {
|
|
647
689
|
return success(runtime, 'agent.skills.import_discovered.preview', { skill: discovered }, [
|
|
648
690
|
'Agent skill import preview',
|
|
649
|
-
` name
|
|
650
|
-
` origin
|
|
651
|
-
` path
|
|
652
|
-
` description
|
|
653
|
-
` procedure characters
|
|
654
|
-
' next
|
|
691
|
+
` name ${discovered.name}`,
|
|
692
|
+
` origin ${discovered.origin}`,
|
|
693
|
+
` path ${discovered.path}`,
|
|
694
|
+
` description ${discovered.description || '(none)'}`,
|
|
695
|
+
` procedure characters ${discovered.body.length}`,
|
|
696
|
+
' next rerun with --yes to import into the Agent-local skill registry',
|
|
655
697
|
].join('\n'));
|
|
656
698
|
}
|
|
657
699
|
const skill = registry.create({
|
|
@@ -668,7 +710,11 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
668
710
|
source: 'imported',
|
|
669
711
|
provenance: `discovered:${discovered.origin}:${discovered.path}`,
|
|
670
712
|
});
|
|
671
|
-
return success(runtime, 'agent.skills.import_discovered', skill,
|
|
713
|
+
return success(runtime, 'agent.skills.import_discovered', skill, [
|
|
714
|
+
`Imported Agent skill ${skill.id}: ${skill.name}${skill.enabled ? ' (enabled)' : ''}`,
|
|
715
|
+
` name ${skill.name}`,
|
|
716
|
+
` enabled ${skill.enabled ? 'yes' : 'no'}`,
|
|
717
|
+
].join('\n'));
|
|
672
718
|
}
|
|
673
719
|
if (normalized === 'search' || normalized === 'find') {
|
|
674
720
|
const query = rest.join(' ').trim();
|
|
@@ -679,12 +725,17 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
679
725
|
const id = rest[0];
|
|
680
726
|
if (!id) return failure(runtime, 'invalid_skill_command', 'Usage: goodvibes-agent skills show <id>', 2);
|
|
681
727
|
const skill = registry.get(id);
|
|
682
|
-
if (!skill) return failure(runtime, 'skill_not_found', `Unknown Agent skill
|
|
728
|
+
if (!skill) return failure(runtime, 'skill_not_found', `Unknown Agent skill ${id}`, 1);
|
|
683
729
|
return success(runtime, 'agent.skills.show', skill, renderSkill(skill));
|
|
684
730
|
}
|
|
685
731
|
if (normalized === 'create') {
|
|
686
732
|
const skill = registry.create(skillPayloadFromOptions(parseOptions(rest)));
|
|
687
|
-
return success(runtime, 'agent.skills.create', skill,
|
|
733
|
+
return success(runtime, 'agent.skills.create', skill, [
|
|
734
|
+
'Agent skill created',
|
|
735
|
+
` id ${skill.id}`,
|
|
736
|
+
skill.enabled ? ' (enabled)' : '',
|
|
737
|
+
` enabled ${skill.enabled ? 'yes' : 'no'}`,
|
|
738
|
+
].filter(Boolean).join('\n'));
|
|
688
739
|
}
|
|
689
740
|
if (normalized === 'update') {
|
|
690
741
|
const id = rest[0];
|
|
@@ -704,25 +755,37 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
704
755
|
: undefined,
|
|
705
756
|
provenance: optionValue(options, 'provenance'),
|
|
706
757
|
});
|
|
707
|
-
return success(runtime, 'agent.skills.update', skill,
|
|
758
|
+
return success(runtime, 'agent.skills.update', skill, [
|
|
759
|
+
'Agent skill updated',
|
|
760
|
+
` id ${skill.id}`,
|
|
761
|
+
].join('\n'));
|
|
708
762
|
}
|
|
709
763
|
if (normalized === 'enable' || normalized === 'disable') {
|
|
710
764
|
const id = rest[0];
|
|
711
765
|
if (!id) return failure(runtime, 'invalid_skill_command', `Usage: goodvibes-agent skills ${normalized} <id>`, 2);
|
|
712
766
|
const skill = registry.setEnabled(id, normalized === 'enable');
|
|
713
|
-
return success(runtime, `agent.skills.${normalized}`, skill,
|
|
767
|
+
return success(runtime, `agent.skills.${normalized}`, skill, [
|
|
768
|
+
`Agent skill ${normalized === 'enable' ? 'enabled' : 'disabled'}`,
|
|
769
|
+
` id ${skill.id}`,
|
|
770
|
+
].join('\n'));
|
|
714
771
|
}
|
|
715
772
|
if (normalized === 'review') {
|
|
716
773
|
const id = rest[0];
|
|
717
774
|
if (!id) return failure(runtime, 'invalid_skill_command', 'Usage: goodvibes-agent skills review <id>', 2);
|
|
718
775
|
const skill = registry.markReviewed(id);
|
|
719
|
-
return success(runtime, 'agent.skills.review', skill,
|
|
776
|
+
return success(runtime, 'agent.skills.review', skill, [
|
|
777
|
+
'Agent skill reviewed',
|
|
778
|
+
` id ${skill.id}`,
|
|
779
|
+
].join('\n'));
|
|
720
780
|
}
|
|
721
781
|
if (normalized === 'stale') {
|
|
722
782
|
const id = rest[0];
|
|
723
783
|
if (!id || rest.length < 2) return failure(runtime, 'invalid_skill_command', 'Usage: goodvibes-agent skills stale <id> <reason>', 2);
|
|
724
784
|
const skill = registry.markStale(id, rest.slice(1).join(' '));
|
|
725
|
-
return success(runtime, 'agent.skills.stale', skill,
|
|
785
|
+
return success(runtime, 'agent.skills.stale', skill, [
|
|
786
|
+
'Agent skill marked stale',
|
|
787
|
+
` id ${skill.id}`,
|
|
788
|
+
].join('\n'));
|
|
726
789
|
}
|
|
727
790
|
if (normalized === 'delete' || normalized === 'remove' || normalized === 'rm') {
|
|
728
791
|
const options = parseOptions(rest);
|
|
@@ -730,7 +793,10 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
730
793
|
if (!id) return failure(runtime, 'invalid_skill_command', 'Usage: goodvibes-agent skills delete <id> --yes', 2);
|
|
731
794
|
if (!hasFlag(options, 'yes')) return failure(runtime, 'confirmation_required', `Refusing to delete Agent skill ${id} without --yes.`, 2);
|
|
732
795
|
const skill = registry.deleteSkill(id);
|
|
733
|
-
return success(runtime, 'agent.skills.delete', skill,
|
|
796
|
+
return success(runtime, 'agent.skills.delete', skill, [
|
|
797
|
+
`Agent skill deleted: ${id}`,
|
|
798
|
+
` id ${skill.id}`,
|
|
799
|
+
].join('\n'));
|
|
734
800
|
}
|
|
735
801
|
return failure(runtime, 'invalid_skill_command', usageSkills(), 2);
|
|
736
802
|
} catch (error) {
|