@pellux/goodvibes-agent 0.1.116 → 0.1.117
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 +41 -663
- package/README.md +38 -52
- package/dist/package/main.js +37826 -35924
- package/docs/README.md +5 -4
- package/docs/{connected-services.md → connected-host.md} +18 -10
- package/docs/getting-started.md +41 -44
- package/docs/release-and-publishing.md +6 -4
- package/package.json +3 -3
- package/src/agent/behavior-discovery-summary.ts +1 -3
- package/src/agent/persona-discovery.ts +1 -3
- package/src/agent/persona-registry.ts +5 -3
- package/src/agent/reminder-schedule-format.ts +6 -6
- package/src/agent/reminder-schedule.ts +1 -1
- package/src/agent/routine-registry.ts +43 -4
- package/src/agent/routine-schedule-format.ts +6 -6
- package/src/agent/routine-schedule-promotion.ts +1 -1
- package/src/agent/routine-schedule-receipts.ts +1 -1
- package/src/agent/runtime-profile-starters.ts +3 -3
- package/src/agent/runtime-profile.ts +78 -0
- package/src/agent/skill-registry.ts +190 -13
- package/src/cli/agent-knowledge-command.ts +2 -2
- package/src/cli/agent-knowledge-format.ts +2 -2
- package/src/cli/agent-knowledge-runtime.ts +1 -1
- package/src/cli/bundle-command.ts +1 -1
- package/src/cli/entrypoint.ts +16 -7
- package/src/cli/help.ts +26 -19
- package/src/cli/local-library-command.ts +75 -21
- package/src/cli/management-commands.ts +7 -6
- package/src/cli/management.ts +6 -51
- package/src/cli/parser.ts +23 -2
- package/src/cli/profiles-command.ts +119 -1
- package/src/cli/routines-command.ts +139 -11
- package/src/cli/service-posture.ts +11 -11
- package/src/cli/status.ts +21 -25
- 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 +2 -1
- package/src/input/agent-workspace-basic-command-editor-submission.ts +345 -92
- package/src/input/agent-workspace-basic-command-editors.ts +480 -7
- package/src/input/agent-workspace-categories.ts +175 -15
- package/src/input/agent-workspace-channel-command-editor-submission.ts +49 -0
- package/src/input/agent-workspace-channel-command-editors.ts +47 -0
- package/src/input/agent-workspace-command-editor.ts +23 -1
- package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
- package/src/input/agent-workspace-editors.ts +27 -0
- 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-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-mcp-command-editor-submission.ts +95 -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-navigation.ts +45 -0
- package/src/input/agent-workspace-notify-editor-submission.ts +107 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +146 -0
- package/src/input/agent-workspace-operations-command-editors.ts +119 -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-requirements.ts +11 -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 +24 -14
- 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 +50 -8
- 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-types.ts +120 -0
- package/src/input/agent-workspace-voice-media.ts +1 -1
- package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
- package/src/input/agent-workspace.ts +47 -37
- package/src/input/command-registry.ts +1 -1
- package/src/input/commands/agent-runtime-profile-runtime.ts +89 -4
- package/src/input/commands/agent-skills-runtime.ts +76 -12
- package/src/input/commands/agent-workspace-runtime.ts +4 -3
- package/src/input/commands/brief-runtime.ts +38 -9
- package/src/input/commands/channels-runtime.ts +3 -3
- package/src/input/commands/compat-runtime.ts +32 -0
- package/src/input/commands/health-runtime.ts +22 -24
- package/src/input/commands/knowledge.ts +26 -5
- package/src/input/commands/local-provider-runtime.ts +7 -3
- package/src/input/commands/local-setup-review.ts +4 -14
- package/src/input/commands/mcp-runtime.ts +8 -12
- package/src/input/commands/operator-runtime.ts +8 -67
- package/src/input/commands/personas-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +7 -70
- package/src/input/commands/policy-dispatch.ts +1 -1
- package/src/input/commands/policy.ts +1 -5
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/qrcode-runtime.ts +6 -4
- package/src/input/commands/routines-runtime.ts +44 -6
- package/src/input/commands/runtime-services.ts +1 -14
- package/src/input/commands/security-runtime.ts +3 -8
- package/src/input/commands/session-content.ts +1 -1
- package/src/input/commands/session-workflow.ts +5 -14
- package/src/input/commands/shell-core.ts +8 -2
- package/src/input/commands/subscription-runtime.ts +1 -6
- package/src/input/commands/support-bundle-runtime.ts +53 -0
- package/src/input/commands/tasks-runtime.ts +2 -2
- package/src/input/commands.ts +4 -0
- package/src/input/feed-context-factory.ts +0 -1
- package/src/input/handler-content-actions.ts +0 -25
- package/src/input/handler-feed.ts +0 -2
- package/src/input/handler-interactions.ts +2 -31
- package/src/input/handler-onboarding.ts +29 -12
- package/src/input/handler-shortcuts.ts +1 -3
- package/src/input/handler.ts +4 -7
- package/src/input/keybindings.ts +9 -9
- 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 +49 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +81 -3
- package/src/input/onboarding/onboarding-wizard-steps.ts +14 -7
- package/src/input/onboarding/onboarding-wizard-types.ts +1 -0
- package/src/input/onboarding/onboarding-wizard.ts +19 -2
- package/src/input/profile-picker-modal.ts +2 -2
- package/src/input/settings-modal-agent-policy.ts +6 -6
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal.ts +14 -14
- package/src/main.ts +0 -2
- package/src/panels/automation-control-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +2 -2
- package/src/panels/builtin/session.ts +26 -18
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/project-planning-panel.ts +1 -1
- package/src/panels/provider-health-domains.ts +3 -3
- package/src/panels/qr-panel.ts +44 -20
- package/src/panels/subscription-panel.ts +3 -3
- package/src/panels/system-messages-panel.ts +2 -2
- package/src/panels/tasks-panel.ts +4 -4
- package/src/planning/project-planning-coordinator.ts +2 -2
- package/src/renderer/agent-workspace.ts +26 -5
- package/src/renderer/block-actions.ts +1 -3
- package/src/renderer/help-overlay.ts +13 -8
- package/src/renderer/mcp-workspace.ts +32 -13
- package/src/renderer/model-picker-overlay.ts +0 -1
- package/src/renderer/model-workspace.ts +0 -2
- package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
- package/src/renderer/panel-picker-overlay.ts +1 -1
- package/src/renderer/profile-picker-modal.ts +2 -2
- package/src/renderer/settings-modal-helpers.ts +23 -23
- package/src/renderer/settings-modal.ts +18 -18
- package/src/renderer/system-message.ts +1 -1
- package/src/runtime/agent-runtime-events.ts +129 -0
- package/src/runtime/bootstrap-command-parts.ts +3 -2
- package/src/runtime/bootstrap-core.ts +4 -64
- package/src/runtime/bootstrap-shell.ts +42 -4
- package/src/runtime/bootstrap.ts +8 -27
- package/src/runtime/connected-host-auth.ts +42 -0
- package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
- package/src/runtime/index.ts +1 -5
- package/src/runtime/onboarding/apply.ts +213 -0
- package/src/runtime/onboarding/derivation.ts +5 -5
- package/src/runtime/onboarding/snapshot.ts +2 -2
- package/src/runtime/onboarding/types.ts +26 -1
- package/src/runtime/onboarding/verify.ts +81 -2
- package/src/runtime/operator-token-cleanup.ts +2 -2
- package/src/runtime/services.ts +27 -12
- package/src/shell/service-settings-sync.ts +7 -7
- package/src/shell/ui-openers.ts +27 -38
- package/src/tools/agent-local-registry-tool.ts +10 -4
- package/src/tools/agent-tool-policy-guard.ts +5 -7
- package/src/version.ts +1 -1
- package/src/cli/package-verification.ts +0 -274
package/src/cli/help.ts
CHANGED
|
@@ -37,12 +37,12 @@ export function renderGoodVibesHelp(binary = 'goodvibes-agent'): string {
|
|
|
37
37
|
' /setup Open setup/config flows',
|
|
38
38
|
' /model Choose provider and model',
|
|
39
39
|
' /knowledge Use isolated Agent Knowledge',
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
' /personas, /skills Tune local Agent behavior',
|
|
41
|
+
' /routines Run local routines in the main conversation',
|
|
42
|
+
' /schedule remind Create confirmed reminders or inspect schedules',
|
|
43
|
+
' /delegate Explicitly hand build/fix/review work to GoodVibes TUI',
|
|
44
44
|
'',
|
|
45
|
-
'
|
|
45
|
+
'Scriptable mirrors:',
|
|
46
46
|
' run|exec [prompt] Run non-interactively with text/json/stream-json output',
|
|
47
47
|
' status Print config, provider, auth, and setup posture',
|
|
48
48
|
' doctor Print status plus setup warnings',
|
|
@@ -55,7 +55,7 @@ export function renderGoodVibesHelp(binary = 'goodvibes-agent'): string {
|
|
|
55
55
|
' memory Manage Agent-owned durable memory records',
|
|
56
56
|
' routines Inspect local routines and explicitly promote one to a connected schedule',
|
|
57
57
|
' auth Inspect Agent auth posture and connection token state',
|
|
58
|
-
' compat Inspect Agent SDK pin, connected
|
|
58
|
+
' compat Inspect Agent SDK pin, connected host version, and Agent Knowledge route readiness',
|
|
59
59
|
' knowledge Use isolated Agent Knowledge/Wiki routes',
|
|
60
60
|
' ask|search Shortcuts for isolated Agent Knowledge ask/search',
|
|
61
61
|
' delegate Explicitly delegate build/fix/review work to GoodVibes TUI',
|
|
@@ -106,7 +106,7 @@ export function renderGoodVibesHelp(binary = 'goodvibes-agent'): string {
|
|
|
106
106
|
` ${binary} profiles create household --template household --yes`,
|
|
107
107
|
` ${binary} --agent-profile household`,
|
|
108
108
|
` ${binary} personas create --name "Travel Planner" --description "Plan trips" --body "Compare options before booking"`,
|
|
109
|
-
` ${binary} skills create --name "Daily Brief" --description "Summarize operator state" --procedure "Review Agent Knowledge, work plans, approvals, and routines" --enabled`,
|
|
109
|
+
` ${binary} skills create --name "Daily Brief" --description "Summarize operator state" --procedure "Review Agent Knowledge, work plans, approvals, and routines" --requires-env GOODVIBES_AGENT_TOKEN --requires-command gh --enabled`,
|
|
110
110
|
` ${binary} memory add fact "Prefers concise morning briefings" --scope project --tags preference`,
|
|
111
111
|
` ${binary} memory search "morning briefings"`,
|
|
112
112
|
` ${binary} routines promote daily-operations-sweep --cron "0 9 * * *" --timezone America/Chicago --yes`,
|
|
@@ -138,12 +138,12 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
138
138
|
},
|
|
139
139
|
setup: {
|
|
140
140
|
usage: ['setup', 'setup status', 'onboarding', 'onboarding status'],
|
|
141
|
-
summary: 'Open Agent setup, or inspect whether setup has already been
|
|
141
|
+
summary: 'Open Agent setup, or inspect whether setup has already been applied for this user.',
|
|
142
142
|
examples: ['setup', 'setup status', 'onboarding status'],
|
|
143
143
|
},
|
|
144
144
|
status: {
|
|
145
145
|
usage: ['status', 'status --json', '--runtime-url http://127.0.0.1:3421 status'],
|
|
146
|
-
summary: 'Print Agent config, provider, auth, connected-
|
|
146
|
+
summary: 'Print Agent config, provider, auth, connected-host state, and setup posture.',
|
|
147
147
|
examples: ['status', 'status --json', '--runtime-url http://127.0.0.1:3421 status'],
|
|
148
148
|
},
|
|
149
149
|
doctor: {
|
|
@@ -157,9 +157,9 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
157
157
|
examples: ['providers', 'providers inspect openai-subscriber', 'providers use openai openai:gpt-5.4'],
|
|
158
158
|
},
|
|
159
159
|
profiles: {
|
|
160
|
-
usage: ['profiles list', 'profiles templates', 'profiles templates from-discovered <id> --yes', 'profiles create-from-discovered <name> --yes', 'profiles templates export <id> <path> --yes', 'profiles templates import <path> --yes', 'profiles show <name>', 'profiles create <name> [--template <id>] --yes', 'profiles delete <name> --yes', '--agent-profile <name>'],
|
|
161
|
-
summary: 'Create and inspect isolated Agent profile homes, with starter templates for household, research, travel, operations, personal productivity, and local imported starters. A profile changes Agent-local config, sessions, memory, personas, skills, routines, and setup paths without changing connected GoodVibes
|
|
162
|
-
examples: ['profiles templates', 'profiles create-from-discovered research-desk --yes', 'profiles templates from-discovered research-desk --yes', 'profiles templates export research ./research-starter.json --yes', 'profiles templates import ./research-starter.json --yes', '
|
|
160
|
+
usage: ['profiles list', 'profiles default', 'profiles use <name> --yes', 'profiles default clear --yes', 'profiles templates', 'profiles templates from-discovered <id> --yes', 'profiles create-from-discovered <name> --yes', 'profiles templates export <id> <path> --yes', 'profiles templates import <path> --yes', 'profiles show <name>', 'profiles create <name> [--template <id>] --yes', 'profiles delete <name> --yes', '--agent-profile <name>'],
|
|
161
|
+
summary: 'Create and inspect isolated Agent profile homes, with starter templates for household, research, travel, operations, personal productivity, and local imported starters. A profile changes Agent-local config, sessions, memory, personas, skills, routines, and setup paths without changing the connected GoodVibes host.',
|
|
162
|
+
examples: ['profiles templates', 'profiles create household --template household --yes', 'profiles use household --yes', 'profiles default', 'profiles create-from-discovered research-desk --yes', 'profiles templates from-discovered research-desk --yes', 'profiles templates export research ./research-starter.json --yes', 'profiles templates import ./research-starter.json --yes', '--agent-profile household status'],
|
|
163
163
|
},
|
|
164
164
|
personas: {
|
|
165
165
|
usage: [
|
|
@@ -192,25 +192,28 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
192
192
|
'skills list',
|
|
193
193
|
'skills enabled',
|
|
194
194
|
'skills active',
|
|
195
|
+
'skills attention',
|
|
195
196
|
'skills discover',
|
|
196
197
|
'skills import-discovered <name> [--enabled] --yes',
|
|
197
198
|
'skills search <query>',
|
|
198
199
|
'skills show <id>',
|
|
199
|
-
'skills create --name <name> --description <summary> --procedure <steps> [--tags a,b] [--triggers a,b] [--enabled]',
|
|
200
|
-
'skills update <id> [--name <name>] [--description <summary>] [--procedure <steps>] [--tags a,b] [--triggers a,b]',
|
|
200
|
+
'skills create --name <name> --description <summary> --procedure <steps> [--tags a,b] [--triggers a,b] [--requires-env A,B] [--requires-command gh,jq] [--enabled]',
|
|
201
|
+
'skills update <id> [--name <name>] [--description <summary>] [--procedure <steps>] [--tags a,b] [--triggers a,b] [--requires-env A,B] [--requires-command gh,jq]',
|
|
201
202
|
'skills enable <id>',
|
|
202
203
|
'skills disable <id>',
|
|
203
204
|
'skills review <id>',
|
|
204
205
|
'skills stale <id> <reason>',
|
|
205
206
|
'skills delete <id> --yes',
|
|
206
|
-
'skills bundle [list|enabled|show|create|update|enable|disable|review|stale|delete]',
|
|
207
|
+
'skills bundle [list|enabled|attention|show|create|update|enable|disable|review|stale|delete]',
|
|
207
208
|
],
|
|
208
209
|
summary: 'Manage reusable Agent-local procedures and skill bundles for the main conversation.',
|
|
209
210
|
examples: [
|
|
210
211
|
'skills list',
|
|
212
|
+
'skills attention',
|
|
213
|
+
'skills bundle attention',
|
|
211
214
|
'skills discover',
|
|
212
215
|
'skills import-discovered "Daily Brief" --enabled --yes',
|
|
213
|
-
'skills create --name "Daily Brief" --description "Summarize operator state" --procedure "Review Agent Knowledge, work plans, approvals, and routines" --enabled',
|
|
216
|
+
'skills create --name "Daily Brief" --description "Summarize operator state" --procedure "Review Agent Knowledge, work plans, approvals, and routines" --requires-env GOODVIBES_AGENT_TOKEN --requires-command gh --enabled',
|
|
214
217
|
'skills bundle create --name "Ops Pack" --description "Daily operations bundle" --skills daily-brief --enabled',
|
|
215
218
|
'skills delete daily-brief --yes',
|
|
216
219
|
],
|
|
@@ -247,20 +250,24 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
247
250
|
usage: [
|
|
248
251
|
'routines list',
|
|
249
252
|
'routines enabled',
|
|
253
|
+
'routines attention',
|
|
250
254
|
'routines discover',
|
|
251
255
|
'routines import-discovered <name> [--enabled] --yes',
|
|
252
256
|
'routines show <id>',
|
|
257
|
+
'routines create --name <name> --description <summary> --steps <steps> [--tags a,b] [--triggers a,b] [--requires-env A,B] [--requires-command gh,jq] [--enabled]',
|
|
253
258
|
'routines receipts',
|
|
254
259
|
'routines reconcile',
|
|
255
260
|
'routines receipt <receipt-id>',
|
|
256
261
|
'routines promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--timezone <tz>] [--name <schedule-name>] [--provider <id>] [--model <model>] [--delivery-channel <channel[:route[:label]]>|--delivery-route <route[:label]>|--delivery-webhook <url>|--delivery-link <url>] [--disabled] --yes',
|
|
257
262
|
],
|
|
258
|
-
summary: 'Inspect and import Agent-local routines
|
|
263
|
+
summary: 'Inspect, create, and import Agent-local routines with setup readiness. The same routine workflow is available in the TUI through /routines and the Agent workspace. GoodVibes schedule promotion is explicit. Without --yes, promotion only prints the preview.',
|
|
259
264
|
examples: [
|
|
260
265
|
'routines list',
|
|
266
|
+
'routines attention',
|
|
261
267
|
'routines discover',
|
|
262
268
|
'routines import-discovered "Daily Brief" --enabled --yes',
|
|
263
269
|
'routines show daily-operations-sweep',
|
|
270
|
+
'routines create --name "Daily Sweep" --description "Review operator state" --steps "Check tasks, approvals, channels, and Agent Knowledge" --requires-env GOODVIBES_AGENT_TOKEN',
|
|
264
271
|
'routines receipts',
|
|
265
272
|
'routines reconcile',
|
|
266
273
|
'routines promote daily-operations-sweep --cron "0 9 * * *" --timezone America/Chicago --delivery-channel slack --yes',
|
|
@@ -348,7 +355,7 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
348
355
|
},
|
|
349
356
|
tasks: {
|
|
350
357
|
usage: ['tasks list', 'tasks show <taskId>'],
|
|
351
|
-
summary: 'Inspect connected-
|
|
358
|
+
summary: 'Inspect connected-host task summaries. Agent blocks host-owned task submission; use run for one-shot work or delegate for explicit build/fix/review handoff.',
|
|
352
359
|
examples: ['tasks list', 'tasks show task-123', 'run "check provider readiness"', 'delegate "fix the failing tests"'],
|
|
353
360
|
},
|
|
354
361
|
bundle: {
|
|
@@ -402,7 +409,7 @@ export function renderGoodVibesCommandHelp(topic: string, binary = 'goodvibes-ag
|
|
|
402
409
|
].join('\n');
|
|
403
410
|
}
|
|
404
411
|
return [
|
|
405
|
-
`GoodVibes ${normalized}`,
|
|
412
|
+
`GoodVibes Agent ${normalized}`,
|
|
406
413
|
'',
|
|
407
414
|
help.summary,
|
|
408
415
|
'',
|
|
@@ -4,6 +4,10 @@ import { AgentPersonaRegistry, type AgentPersonaRecord } from '../agent/persona-
|
|
|
4
4
|
import { discoverSkills, type SkillRecord } from '../agent/skill-discovery.ts';
|
|
5
5
|
import {
|
|
6
6
|
AgentSkillRegistry,
|
|
7
|
+
buildAgentSkillRequirements,
|
|
8
|
+
evaluateAgentSkillBundleReadiness,
|
|
9
|
+
evaluateAgentSkillReadiness,
|
|
10
|
+
formatAgentSkillRequirement,
|
|
7
11
|
type AgentSkillBundleRecord,
|
|
8
12
|
type AgentSkillRecord,
|
|
9
13
|
} from '../agent/skill-registry.ts';
|
|
@@ -170,7 +174,7 @@ function renderDiscoveredPersonaList(personas: readonly DiscoveredPersonaRecord[
|
|
|
170
174
|
return [
|
|
171
175
|
'Discovered Agent persona files',
|
|
172
176
|
' No persona markdown files found in Agent persona folders.',
|
|
173
|
-
' Search roots: .goodvibes/personas, .goodvibes/agent/personas,
|
|
177
|
+
' Search roots: .goodvibes/personas, .goodvibes/agent/personas, ~/.goodvibes/personas, ~/.goodvibes/agent/personas',
|
|
174
178
|
].join('\n');
|
|
175
179
|
}
|
|
176
180
|
return [
|
|
@@ -204,21 +208,29 @@ function discoveredPersonaFrontmatterList(persona: DiscoveredPersonaRecord, key:
|
|
|
204
208
|
function summarizeSkill(skill: AgentSkillRecord): string {
|
|
205
209
|
const enabled = skill.enabled ? 'enabled' : 'disabled';
|
|
206
210
|
const tags = skill.tags.length > 0 ? ` tags=${skill.tags.join(',')}` : '';
|
|
207
|
-
|
|
211
|
+
const readiness = evaluateAgentSkillReadiness(skill);
|
|
212
|
+
const ready = readiness.ready ? 'ready' : `needs ${readiness.missing.map(formatAgentSkillRequirement).join(',')}`;
|
|
213
|
+
return ` ${skill.id} ${enabled} ${skill.reviewState} ${ready} ${skill.name} - ${skill.description}${tags}`;
|
|
208
214
|
}
|
|
209
215
|
|
|
210
|
-
function summarizeBundle(bundle: AgentSkillBundleRecord): string {
|
|
216
|
+
function summarizeBundle(bundle: AgentSkillBundleRecord, skills: readonly AgentSkillRecord[]): string {
|
|
211
217
|
const enabled = bundle.enabled ? 'enabled' : 'disabled';
|
|
212
|
-
|
|
218
|
+
const readiness = evaluateAgentSkillBundleReadiness(bundle, skills);
|
|
219
|
+
const missing = [
|
|
220
|
+
...readiness.missingRequirements.map(formatAgentSkillRequirement),
|
|
221
|
+
...readiness.missingSkillIds.map((skillId) => `skill:${skillId}`),
|
|
222
|
+
];
|
|
223
|
+
const ready = readiness.ready ? 'ready' : `needs ${missing.join(',')}`;
|
|
224
|
+
return ` ${bundle.id} ${enabled} ${bundle.reviewState} ${ready} ${bundle.name} - ${bundle.description} skills=${bundle.skillIds.join(',')}`;
|
|
213
225
|
}
|
|
214
226
|
|
|
215
|
-
function renderSkillList(title: string, path: string, skills: readonly AgentSkillRecord[]): string {
|
|
227
|
+
function renderSkillList(title: string, path: string, skills: readonly AgentSkillRecord[], emptyMessage?: string): string {
|
|
216
228
|
if (skills.length === 0) {
|
|
217
229
|
return [
|
|
218
230
|
title,
|
|
219
|
-
'
|
|
220
|
-
' Create one with: goodvibes-agent skills create --name <name> --description <summary> --procedure <steps>',
|
|
221
|
-
].join('\n');
|
|
231
|
+
` ${emptyMessage ?? 'No local Agent skills yet.'}`,
|
|
232
|
+
emptyMessage ? '' : ' Create one with: goodvibes-agent skills create --name <name> --description <summary> --procedure <steps>',
|
|
233
|
+
].filter(Boolean).join('\n');
|
|
222
234
|
}
|
|
223
235
|
return [
|
|
224
236
|
`${title} (${skills.length})`,
|
|
@@ -273,26 +285,38 @@ function discoveredFrontmatterList(skill: SkillRecord, key: string): readonly st
|
|
|
273
285
|
return value.split(',').map((entry) => entry.trim()).filter(Boolean);
|
|
274
286
|
}
|
|
275
287
|
|
|
276
|
-
function
|
|
288
|
+
function discoveredFrontmatterAnyList(skill: SkillRecord, keys: readonly string[]): readonly string[] {
|
|
289
|
+
for (const key of keys) {
|
|
290
|
+
const values = discoveredFrontmatterList(skill, key);
|
|
291
|
+
if (values.length > 0) return values;
|
|
292
|
+
}
|
|
293
|
+
return [];
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function renderBundleList(title: string, path: string, bundles: readonly AgentSkillBundleRecord[], skills: readonly AgentSkillRecord[], emptyMessage?: string): string {
|
|
277
297
|
if (bundles.length === 0) {
|
|
278
298
|
return [
|
|
279
299
|
title,
|
|
280
|
-
'
|
|
281
|
-
' Create one with: goodvibes-agent skills bundle create --name <name> --description <summary> --skills <id,id>',
|
|
282
|
-
].join('\n');
|
|
300
|
+
` ${emptyMessage ?? 'No local Agent skill bundles yet.'}`,
|
|
301
|
+
emptyMessage ? '' : ' Create one with: goodvibes-agent skills bundle create --name <name> --description <summary> --skills <id,id>',
|
|
302
|
+
].filter(Boolean).join('\n');
|
|
283
303
|
}
|
|
284
304
|
return [
|
|
285
305
|
`${title} (${bundles.length})`,
|
|
286
306
|
` store: ${path}`,
|
|
287
|
-
...bundles.map(summarizeBundle),
|
|
307
|
+
...bundles.map((bundle) => summarizeBundle(bundle, skills)),
|
|
288
308
|
].join('\n');
|
|
289
309
|
}
|
|
290
310
|
|
|
291
311
|
function renderSkill(skill: AgentSkillRecord): string {
|
|
312
|
+
const readiness = evaluateAgentSkillReadiness(skill);
|
|
292
313
|
return [
|
|
293
314
|
`Skill ${skill.name}`,
|
|
294
315
|
` id: ${skill.id}`,
|
|
295
316
|
` enabled: ${skill.enabled ? 'yes' : 'no'}`,
|
|
317
|
+
` readiness: ${readiness.ready ? 'ready' : 'needs setup'}`,
|
|
318
|
+
` requirements: ${skill.requirements.map(formatAgentSkillRequirement).join(', ') || '(none)'}`,
|
|
319
|
+
readiness.missing.length > 0 ? ` missing: ${readiness.missing.map(formatAgentSkillRequirement).join(', ')}` : '',
|
|
296
320
|
` review: ${skill.reviewState}`,
|
|
297
321
|
` source: ${skill.source}`,
|
|
298
322
|
` provenance: ${skill.provenance}`,
|
|
@@ -308,11 +332,18 @@ function renderSkill(skill: AgentSkillRecord): string {
|
|
|
308
332
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
309
333
|
}
|
|
310
334
|
|
|
311
|
-
function renderBundle(bundle: AgentSkillBundleRecord): string {
|
|
335
|
+
function renderBundle(bundle: AgentSkillBundleRecord, skills: readonly AgentSkillRecord[]): string {
|
|
336
|
+
const readiness = evaluateAgentSkillBundleReadiness(bundle, skills);
|
|
337
|
+
const missing = [
|
|
338
|
+
...readiness.missingRequirements.map(formatAgentSkillRequirement),
|
|
339
|
+
...readiness.missingSkillIds.map((skillId) => `skill:${skillId}`),
|
|
340
|
+
];
|
|
312
341
|
return [
|
|
313
342
|
`Skill bundle ${bundle.name}`,
|
|
314
343
|
` id: ${bundle.id}`,
|
|
315
344
|
` enabled: ${bundle.enabled ? 'yes' : 'no'}`,
|
|
345
|
+
` readiness: ${readiness.ready ? 'ready' : 'needs setup'}`,
|
|
346
|
+
missing.length > 0 ? ` missing: ${missing.join(', ')}` : '',
|
|
316
347
|
` review: ${bundle.reviewState}`,
|
|
317
348
|
` source: ${bundle.source}`,
|
|
318
349
|
` provenance: ${bundle.provenance}`,
|
|
@@ -330,11 +361,11 @@ function usagePersonas(): string {
|
|
|
330
361
|
}
|
|
331
362
|
|
|
332
363
|
function usageSkills(): string {
|
|
333
|
-
return 'Usage: goodvibes-agent skills [list|enabled|active|discover|import-discovered <name> --yes|search <query>|show <id>|create|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes|bundle ...]';
|
|
364
|
+
return 'Usage: goodvibes-agent skills [list|enabled|active|attention|discover|import-discovered <name> --yes|search <query>|show <id>|create [--requires-env A,B] [--requires-command gh,jq]|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes|bundle ...]';
|
|
334
365
|
}
|
|
335
366
|
|
|
336
367
|
function usageBundles(): string {
|
|
337
|
-
return 'Usage: goodvibes-agent skills bundle [list|enabled|search <query>|show <id>|create|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes]';
|
|
368
|
+
return 'Usage: goodvibes-agent skills bundle [list|enabled|attention|search <query>|show <id>|create|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes]';
|
|
338
369
|
}
|
|
339
370
|
|
|
340
371
|
function errorOutput(runtime: CliCommandRuntime, error: unknown, kind: string): CliCommandOutput {
|
|
@@ -473,6 +504,7 @@ function skillPayloadFromOptions(options: ParsedOptions): {
|
|
|
473
504
|
readonly procedure: string;
|
|
474
505
|
readonly tags: readonly string[] | undefined;
|
|
475
506
|
readonly triggers: readonly string[] | undefined;
|
|
507
|
+
readonly requirements: ReturnType<typeof buildAgentSkillRequirements>;
|
|
476
508
|
readonly enabled: boolean | undefined;
|
|
477
509
|
readonly provenance: string;
|
|
478
510
|
} {
|
|
@@ -483,6 +515,10 @@ function skillPayloadFromOptions(options: ParsedOptions): {
|
|
|
483
515
|
procedure: requiredOption(options, 'procedure', usage),
|
|
484
516
|
tags: csvOption(options, 'tags'),
|
|
485
517
|
triggers: csvOption(options, 'triggers'),
|
|
518
|
+
requirements: buildAgentSkillRequirements({
|
|
519
|
+
env: csvOption(options, 'requires-env'),
|
|
520
|
+
commands: csvOption(options, 'requires-command') ?? csvOption(options, 'requires-commands'),
|
|
521
|
+
}),
|
|
486
522
|
enabled: hasFlag(options, 'enabled') ? true : undefined,
|
|
487
523
|
provenance: optionValue(options, 'provenance') ?? 'cli',
|
|
488
524
|
};
|
|
@@ -495,22 +531,26 @@ async function handleSkillBundleCommand(runtime: CliCommandRuntime, args: readon
|
|
|
495
531
|
const registry = skillRegistry(runtime);
|
|
496
532
|
const snapshot = registry.snapshot();
|
|
497
533
|
if (normalized === 'list' || normalized === 'ls') {
|
|
498
|
-
return success(runtime, 'agent.skills.bundles.list', { path: snapshot.path, bundles: snapshot.bundles }, renderBundleList('Agent skill bundles', snapshot.path, snapshot.bundles));
|
|
534
|
+
return success(runtime, 'agent.skills.bundles.list', { path: snapshot.path, bundles: snapshot.bundles }, renderBundleList('Agent skill bundles', snapshot.path, snapshot.bundles, snapshot.skills));
|
|
499
535
|
}
|
|
500
536
|
if (normalized === 'enabled') {
|
|
501
|
-
return success(runtime, 'agent.skills.bundles.enabled', { path: snapshot.path, bundles: snapshot.enabledBundles }, renderBundleList('Enabled Agent skill bundles', snapshot.path, snapshot.enabledBundles));
|
|
537
|
+
return success(runtime, 'agent.skills.bundles.enabled', { path: snapshot.path, bundles: snapshot.enabledBundles }, renderBundleList('Enabled Agent skill bundles', snapshot.path, snapshot.enabledBundles, snapshot.skills));
|
|
538
|
+
}
|
|
539
|
+
if (normalized === 'attention' || normalized === 'needs-setup') {
|
|
540
|
+
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 Agent skill bundles need setup.'));
|
|
502
542
|
}
|
|
503
543
|
if (normalized === 'search' || normalized === 'find') {
|
|
504
544
|
const query = rest.join(' ').trim();
|
|
505
545
|
const results = registry.searchBundles(query);
|
|
506
|
-
return success(runtime, 'agent.skills.bundles.search', { query, results }, renderBundleList(`Agent skill bundles matching "${query}"`, snapshot.path, results));
|
|
546
|
+
return success(runtime, 'agent.skills.bundles.search', { query, results }, renderBundleList(`Agent skill bundles matching "${query}"`, snapshot.path, results, snapshot.skills));
|
|
507
547
|
}
|
|
508
548
|
if (normalized === 'show' || normalized === 'get') {
|
|
509
549
|
const id = rest[0];
|
|
510
550
|
if (!id) return failure(runtime, 'invalid_skill_bundle_command', 'Usage: goodvibes-agent skills bundle show <id>', 2);
|
|
511
551
|
const bundle = registry.getBundle(id);
|
|
512
552
|
if (!bundle) return failure(runtime, 'skill_bundle_not_found', `Unknown Agent skill bundle: ${id}`, 1);
|
|
513
|
-
return success(runtime, 'agent.skills.bundles.show', bundle, renderBundle(bundle));
|
|
553
|
+
return success(runtime, 'agent.skills.bundles.show', bundle, renderBundle(bundle, snapshot.skills));
|
|
514
554
|
}
|
|
515
555
|
if (normalized === 'create') {
|
|
516
556
|
const options = parseOptions(rest);
|
|
@@ -584,9 +624,13 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
584
624
|
if (normalized === 'active') {
|
|
585
625
|
return success(runtime, 'agent.skills.active', { path: snapshot.path, skills: snapshot.activeSkills, bundles: snapshot.enabledBundles }, [
|
|
586
626
|
renderSkillList('Active Agent skills', snapshot.path, snapshot.activeSkills),
|
|
587
|
-
snapshot.enabledBundles.length > 0 ? renderBundleList('Enabled Agent skill bundles', snapshot.path, snapshot.enabledBundles) : '',
|
|
627
|
+
snapshot.enabledBundles.length > 0 ? renderBundleList('Enabled Agent skill bundles', snapshot.path, snapshot.enabledBundles, snapshot.skills) : '',
|
|
588
628
|
].filter(Boolean).join('\n\n'));
|
|
589
629
|
}
|
|
630
|
+
if (normalized === 'attention' || normalized === 'needs-setup') {
|
|
631
|
+
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 Agent skills need setup.'));
|
|
633
|
+
}
|
|
590
634
|
if (normalized === 'discover') {
|
|
591
635
|
const discovered = await discoverSkills(shellPaths(runtime));
|
|
592
636
|
return success(runtime, 'agent.skills.discover', { skills: discovered }, renderDiscoveredSkillList(discovered));
|
|
@@ -616,6 +660,10 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
616
660
|
procedure: discovered.body,
|
|
617
661
|
tags: discoveredFrontmatterList(discovered, 'tags'),
|
|
618
662
|
triggers: discoveredFrontmatterList(discovered, 'triggers'),
|
|
663
|
+
requirements: buildAgentSkillRequirements({
|
|
664
|
+
env: discoveredFrontmatterAnyList(discovered, ['requiresEnv', 'requires-env', 'requires_env']),
|
|
665
|
+
commands: discoveredFrontmatterAnyList(discovered, ['requiresCommands', 'requires-commands', 'requires_commands', 'commands']),
|
|
666
|
+
}),
|
|
619
667
|
enabled: hasFlag(options, 'enabled'),
|
|
620
668
|
source: 'imported',
|
|
621
669
|
provenance: `discovered:${discovered.origin}:${discovered.path}`,
|
|
@@ -648,6 +696,12 @@ export async function handleSkillsCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
648
696
|
procedure: optionValue(options, 'procedure'),
|
|
649
697
|
tags: csvOption(options, 'tags'),
|
|
650
698
|
triggers: csvOption(options, 'triggers'),
|
|
699
|
+
requirements: options.values.has('requires-env') || options.values.has('requires-command') || options.values.has('requires-commands')
|
|
700
|
+
? buildAgentSkillRequirements({
|
|
701
|
+
env: csvOption(options, 'requires-env'),
|
|
702
|
+
commands: csvOption(options, 'requires-command') ?? csvOption(options, 'requires-commands'),
|
|
703
|
+
})
|
|
704
|
+
: undefined,
|
|
651
705
|
provenance: optionValue(options, 'provenance'),
|
|
652
706
|
});
|
|
653
707
|
return success(runtime, 'agent.skills.update', skill, `Agent skill updated: ${skill.id}`);
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { dirname
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
3
|
import { SecretsManager } from '../config/secrets.ts';
|
|
4
4
|
import { BUILTIN_SECRET_PROVIDER_SOURCES, describeSecretRef, isSecretRefInput, resolveSecretRef } from '@pellux/goodvibes-sdk/platform/config';
|
|
5
5
|
import { getSubscriptionProviderConfig, listAvailableSubscriptionProviders } from '@pellux/goodvibes-sdk/platform/config';
|
|
6
6
|
import { beginOpenAICodexLogin, exchangeOpenAICodexCode } from '@pellux/goodvibes-sdk/platform/config';
|
|
7
7
|
import { inspectProviderAuth } from '@/runtime/index.ts';
|
|
8
|
-
import {
|
|
8
|
+
import { buildCompanionConnectionInfo, encodeConnectionPayload, formatConnectionBlock } from '@pellux/goodvibes-sdk/platform/pairing';
|
|
9
9
|
import { generateQrMatrix, renderQrToString } from '@pellux/goodvibes-sdk/platform/pairing';
|
|
10
10
|
import { resolveRuntimeEndpointBinding } from './endpoints.ts';
|
|
11
11
|
import type { CliCommandRuntime } from './management.ts';
|
|
12
12
|
import { extractAuthorizationCode, formatJsonOrText, hasCommandFlag, openBrowser, urlHostForBindHost, withRuntimeServices, yesNo } from './management.ts';
|
|
13
13
|
import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../config/surface.ts';
|
|
14
|
+
import { connectedHostTokenRequiredMessage, readConnectedHostOperatorToken } from '../runtime/connected-host-auth.ts';
|
|
14
15
|
|
|
15
16
|
export async function renderSubscriptions(runtime: CliCommandRuntime): Promise<string> {
|
|
16
17
|
return await withRuntimeServices(runtime, async (services) => {
|
|
@@ -279,7 +280,7 @@ export async function handleTasks(runtime: CliCommandRuntime): Promise<string> {
|
|
|
279
280
|
const [sub = 'list', ...rest] = runtime.cli.commandArgs;
|
|
280
281
|
if (sub === 'submit') {
|
|
281
282
|
return [
|
|
282
|
-
'GoodVibes Agent blocks CLI task submission from the
|
|
283
|
+
'GoodVibes Agent blocks CLI task submission from the host-owned task workflow.',
|
|
283
284
|
' policy: do normal assistant work in the main Agent conversation or use `goodvibes-agent run <prompt>` for an explicit one-shot run.',
|
|
284
285
|
' build/fix/review: use `goodvibes-agent delegate <task>` for explicit GoodVibes TUI handoff.',
|
|
285
286
|
' result: no local task was started.',
|
|
@@ -289,7 +290,7 @@ export async function handleTasks(runtime: CliCommandRuntime): Promise<string> {
|
|
|
289
290
|
const tasks = [...services.runtimeStore.getState().tasks.tasks.values()];
|
|
290
291
|
if (sub === 'list') {
|
|
291
292
|
return tasks.length === 0
|
|
292
|
-
? 'GoodVibes tasks\n No connected-
|
|
293
|
+
? 'GoodVibes tasks\n No connected-host tasks are currently recorded.'
|
|
293
294
|
: ['GoodVibes tasks', ...tasks.map((task) => ` ${task.id} ${task.status} ${task.kind} ${task.title}`)].join('\n');
|
|
294
295
|
}
|
|
295
296
|
if (sub === 'show') {
|
|
@@ -302,8 +303,8 @@ export async function handleTasks(runtime: CliCommandRuntime): Promise<string> {
|
|
|
302
303
|
}
|
|
303
304
|
|
|
304
305
|
export async function renderPairing(runtime: CliCommandRuntime): Promise<string> {
|
|
305
|
-
const
|
|
306
|
-
|
|
306
|
+
const tokenRecord = readConnectedHostOperatorToken(runtime.homeDirectory);
|
|
307
|
+
if (!tokenRecord.token) return connectedHostTokenRequiredMessage(tokenRecord.path);
|
|
307
308
|
const binding = resolveRuntimeEndpointBinding(runtime.configManager, 'controlPlane');
|
|
308
309
|
const daemonUrl = `http://${urlHostForBindHost(binding.host)}:${binding.port}`;
|
|
309
310
|
const info = buildCompanionConnectionInfo({
|
package/src/cli/management.ts
CHANGED
|
@@ -19,14 +19,9 @@ import { BUILTIN_SECRET_PROVIDER_SOURCES, describeSecretRef, isSecretRefInput, r
|
|
|
19
19
|
import { getSubscriptionProviderConfig, listAvailableSubscriptionProviders } from '@pellux/goodvibes-sdk/platform/config';
|
|
20
20
|
import { beginOpenAICodexLogin, exchangeOpenAICodexCode } from '@pellux/goodvibes-sdk/platform/config';
|
|
21
21
|
import { inspectProviderAuth } from '@/runtime/index.ts';
|
|
22
|
-
import { getOrCreateCompanionToken, buildCompanionConnectionInfo, encodeConnectionPayload, formatConnectionBlock } from '@pellux/goodvibes-sdk/platform/pairing';
|
|
23
|
-
import { generateQrMatrix, renderQrToString } from '@pellux/goodvibes-sdk/platform/pairing';
|
|
24
22
|
import type { GoodVibesCliParseResult } from './types.ts';
|
|
25
23
|
import { formatProviderAuthRoute, summarizeProviderAuthRoutes } from './provider-auth-routes.ts';
|
|
26
24
|
import { classifyProviderSetup } from './provider-classification.ts';
|
|
27
|
-
import { resolveRuntimeEndpointBinding } from './endpoints.ts';
|
|
28
|
-
import { applyRuntimeEndpointFlagOverrides } from './config-overrides.ts';
|
|
29
|
-
import type { RuntimeEndpointId } from './endpoints.ts';
|
|
30
25
|
import { handleBundleCommand } from './bundle-command.ts';
|
|
31
26
|
import { handleSecrets, handleSessions, handleTasks, renderPairing, renderSubscriptions } from './management-commands.ts';
|
|
32
27
|
import { handleAgentKnowledgeCommand, handleAgentKnowledgeShortcutCommand, handleCompatCommand, handleDelegateCommand } from './agent-knowledge-command.ts';
|
|
@@ -132,46 +127,6 @@ export function urlHostForBindHost(host: string): string {
|
|
|
132
127
|
return host || '127.0.0.1';
|
|
133
128
|
}
|
|
134
129
|
|
|
135
|
-
export function enableServicePosture(config: ConfigManager): void {
|
|
136
|
-
config.setDynamic('service.enabled', true);
|
|
137
|
-
config.setDynamic('service.autostart', true);
|
|
138
|
-
config.setDynamic('service.restartOnFailure', true);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export function enableEndpointLanDefault(config: ConfigManager, endpoint: RuntimeEndpointId): void {
|
|
142
|
-
const binding = resolveRuntimeEndpointBinding(config, endpoint);
|
|
143
|
-
if (binding.hostMode === 'custom') return;
|
|
144
|
-
if (endpoint === 'controlPlane') {
|
|
145
|
-
config.setDynamic('controlPlane.hostMode', 'network');
|
|
146
|
-
config.setDynamic('controlPlane.host', '0.0.0.0');
|
|
147
|
-
config.setDynamic('controlPlane.allowRemote', true);
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
if (endpoint === 'httpListener') {
|
|
151
|
-
config.setDynamic('httpListener.hostMode', 'network');
|
|
152
|
-
config.setDynamic('httpListener.host', '0.0.0.0');
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
config.setDynamic('web.hostMode', 'network');
|
|
156
|
-
config.setDynamic('web.host', '0.0.0.0');
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export function applyTargetEndpointFlagsOrDefault(
|
|
160
|
-
runtime: CliCommandRuntime,
|
|
161
|
-
endpoint: RuntimeEndpointId,
|
|
162
|
-
): string | null {
|
|
163
|
-
const errors = applyRuntimeEndpointFlagOverrides(runtime.configManager, endpoint, runtime.cli.flags);
|
|
164
|
-
if (errors.length > 0) return errors.join('\n');
|
|
165
|
-
if (runtime.cli.flags.hostname === undefined) {
|
|
166
|
-
enableEndpointLanDefault(runtime.configManager, endpoint);
|
|
167
|
-
}
|
|
168
|
-
if (endpoint === 'controlPlane') {
|
|
169
|
-
const binding = resolveRuntimeEndpointBinding(runtime.configManager, endpoint);
|
|
170
|
-
runtime.configManager.setDynamic('controlPlane.allowRemote', binding.hostMode !== 'local');
|
|
171
|
-
}
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
130
|
export function openBrowser(url: string): string {
|
|
176
131
|
const platform = process.platform;
|
|
177
132
|
const command = platform === 'darwin' ? 'open' : platform === 'win32' ? 'cmd' : 'xdg-open';
|
|
@@ -544,8 +499,8 @@ async function renderAuth(runtime: CliCommandRuntime): Promise<string> {
|
|
|
544
499
|
]);
|
|
545
500
|
if (blocked.has(sub)) {
|
|
546
501
|
return [
|
|
547
|
-
'Unsupported: connected-
|
|
548
|
-
'GoodVibes Agent does not create, delete, rotate, revoke, or clear connected-
|
|
502
|
+
'Unsupported: connected-host auth user/session administration is outside GoodVibes Agent.',
|
|
503
|
+
'GoodVibes Agent does not create, delete, rotate, revoke, or clear connected-host users, sessions, or bootstrap credentials.',
|
|
549
504
|
'Use the owning GoodVibes host for auth administration.',
|
|
550
505
|
].join('\n');
|
|
551
506
|
}
|
|
@@ -566,21 +521,21 @@ async function renderAuth(runtime: CliCommandRuntime): Promise<string> {
|
|
|
566
521
|
if (sub === 'users' || sub === 'sessions') {
|
|
567
522
|
return formatJsonOrText(runtime.cli)(value, [
|
|
568
523
|
`GoodVibes Agent auth ${sub}`,
|
|
569
|
-
' owner: connected GoodVibes
|
|
524
|
+
' owner: connected GoodVibes host',
|
|
570
525
|
` operator token: ${paths.operatorTokenPresent ? 'present' : 'missing'}`,
|
|
571
526
|
` operator token path: ${paths.operatorTokenPath}`,
|
|
572
527
|
` ${sub}: managed outside Agent`,
|
|
573
|
-
' Agent does not enumerate or mutate connected-
|
|
528
|
+
' Agent does not enumerate or mutate connected-host users/sessions from the local CLI.',
|
|
574
529
|
].join('\n'));
|
|
575
530
|
}
|
|
576
531
|
return formatJsonOrText(runtime.cli)(value, [
|
|
577
532
|
'GoodVibes Agent auth',
|
|
578
|
-
' owner: connected GoodVibes
|
|
533
|
+
' owner: connected GoodVibes host',
|
|
579
534
|
` permission mode: ${String(value.permissionMode)}`,
|
|
580
535
|
` operator token: ${paths.operatorTokenPresent ? 'present' : 'missing'} (${paths.operatorTokenPath})`,
|
|
581
536
|
` compatibility user store: ${paths.userStorePresent ? 'present' : 'missing'} (${paths.userStorePath})`,
|
|
582
537
|
` compatibility bootstrap credential: ${paths.bootstrapCredentialPresent ? 'present' : 'missing'} (${paths.bootstrapCredentialPath})`,
|
|
583
|
-
' connected-
|
|
538
|
+
' connected-host user/session administration: outside Agent',
|
|
584
539
|
' next: goodvibes-agent providers',
|
|
585
540
|
' next: goodvibes-agent subscription providers',
|
|
586
541
|
].join('\n'));
|
package/src/cli/parser.ts
CHANGED
|
@@ -58,7 +58,28 @@ const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
|
|
|
58
58
|
version: 'version',
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
const
|
|
61
|
+
const BLOCKED_PRODUCT_COMMANDS = new Set([
|
|
62
|
+
'app',
|
|
63
|
+
'bridge',
|
|
64
|
+
'control-plane',
|
|
65
|
+
'controlplane',
|
|
66
|
+
'cp',
|
|
67
|
+
'daemon',
|
|
68
|
+
'http-listener',
|
|
69
|
+
'launch',
|
|
70
|
+
'listener',
|
|
71
|
+
'remote',
|
|
72
|
+
'serve',
|
|
73
|
+
'server',
|
|
74
|
+
'service',
|
|
75
|
+
'services',
|
|
76
|
+
'start',
|
|
77
|
+
'surface',
|
|
78
|
+
'surfaces',
|
|
79
|
+
'tui',
|
|
80
|
+
'web',
|
|
81
|
+
'webhook',
|
|
82
|
+
]);
|
|
62
83
|
|
|
63
84
|
function createDefaultFlags(): GoodVibesCliFlags {
|
|
64
85
|
return {
|
|
@@ -200,7 +221,7 @@ export function parseGoodVibesCli(
|
|
|
200
221
|
if (!token.startsWith('-') || token === '-') {
|
|
201
222
|
if (!sawCommand) {
|
|
202
223
|
const commandToken = token.toLowerCase();
|
|
203
|
-
if (
|
|
224
|
+
if (BLOCKED_PRODUCT_COMMANDS.has(commandToken)) {
|
|
204
225
|
command = 'unknown';
|
|
205
226
|
rawCommand = token;
|
|
206
227
|
sawCommand = true;
|