@pellux/goodvibes-agent 0.1.9 → 0.1.11
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 -0
- package/README.md +1 -1
- package/docs/getting-started.md +1 -1
- package/docs/release-and-publishing.md +2 -2
- package/package.json +4 -1
- package/src/cli/agent-knowledge-command.ts +46 -20
- package/src/cli/help.ts +15 -2
- package/src/cli/management-commands.ts +3 -3
- package/src/cli/management.ts +7 -1
- package/src/cli/parser.ts +3 -0
- package/src/cli/service-posture.ts +6 -6
- package/src/cli/status.ts +9 -9
- package/src/cli/surface-command.ts +3 -3
- package/src/cli/types.ts +2 -0
- package/src/input/commands/cloudflare-runtime.ts +20 -5
- package/src/input/commands/confirmation.ts +24 -0
- package/src/input/commands/discovery-runtime.ts +16 -7
- package/src/input/commands/eval.ts +27 -14
- package/src/input/commands/experience-runtime.ts +66 -27
- package/src/input/commands/health-runtime.ts +1 -1
- package/src/input/commands/hooks-runtime.ts +79 -20
- package/src/input/commands/incident-runtime.ts +17 -6
- package/src/input/commands/integration-runtime.ts +93 -50
- package/src/input/commands/knowledge.ts +38 -12
- package/src/input/commands/local-auth-runtime.ts +36 -13
- package/src/input/commands/local-provider-runtime.ts +22 -11
- package/src/input/commands/local-runtime.ts +21 -11
- package/src/input/commands/local-setup.ts +35 -16
- package/src/input/commands/managed-runtime.ts +51 -20
- package/src/input/commands/marketplace-runtime.ts +31 -16
- package/src/input/commands/mcp-runtime.ts +65 -34
- package/src/input/commands/memory-product-runtime.ts +72 -35
- package/src/input/commands/memory.ts +9 -9
- package/src/input/commands/notify-runtime.ts +27 -8
- package/src/input/commands/operator-runtime.ts +85 -17
- package/src/input/commands/planning-runtime.ts +14 -2
- package/src/input/commands/platform-access-runtime.ts +88 -45
- package/src/input/commands/platform-services-runtime.ts +51 -25
- package/src/input/commands/product-runtime.ts +54 -27
- package/src/input/commands/profile-sync-runtime.ts +17 -6
- package/src/input/commands/recall-bundle.ts +38 -17
- package/src/input/commands/recall-query.ts +15 -4
- package/src/input/commands/recall-review.ts +9 -3
- package/src/input/commands/remote-runtime-setup.ts +45 -18
- package/src/input/commands/remote-runtime.ts +25 -9
- package/src/input/commands/replay-runtime.ts +9 -2
- package/src/input/commands/services-runtime.ts +21 -10
- package/src/input/commands/session-content.ts +53 -51
- package/src/input/commands/session-workflow.ts +10 -4
- package/src/input/commands/session.ts +1 -1
- package/src/input/commands/settings-sync-runtime.ts +40 -17
- package/src/input/commands/share-runtime.ts +12 -4
- package/src/input/commands/shell-core.ts +3 -3
- package/src/input/commands/subscription-runtime.ts +35 -20
- package/src/input/commands/teleport-runtime.ts +16 -5
- package/src/input/commands/work-plan-runtime.ts +23 -12
- package/src/input/handler-content-actions.ts +11 -62
- package/src/input/handler-interactions.ts +1 -1
- package/src/input/handler-onboarding-cloudflare.ts +48 -117
- package/src/input/handler.ts +1 -0
- package/src/input/keybindings.ts +1 -1
- package/src/input/mcp-workspace.ts +25 -49
- package/src/input/onboarding/onboarding-runtime-status.ts +8 -8
- package/src/input/onboarding/onboarding-wizard-apply.ts +13 -53
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +12 -12
- package/src/input/onboarding/onboarding-wizard-cloudflare.ts +2 -7
- package/src/input/onboarding/onboarding-wizard-constants.ts +7 -7
- package/src/input/onboarding/onboarding-wizard-external-surface-extra-specs.ts +4 -4
- package/src/input/onboarding/onboarding-wizard-steps.ts +13 -13
- package/src/input/profile-picker-modal.ts +13 -31
- package/src/input/session-picker-modal.ts +4 -30
- package/src/input/settings-modal-agent-policy.ts +18 -0
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal-types.ts +17 -0
- package/src/input/settings-modal.ts +30 -29
- package/src/main.ts +3 -26
- package/src/panels/incident-review-panel.ts +1 -1
- package/src/panels/local-auth-panel.ts +4 -4
- package/src/panels/provider-account-snapshot.ts +1 -1
- package/src/panels/provider-health-domains.ts +2 -2
- package/src/panels/settings-sync-panel.ts +2 -2
- package/src/panels/subscription-panel.ts +7 -7
- package/src/renderer/block-actions.ts +1 -1
- package/src/renderer/help-overlay.ts +2 -2
- package/src/renderer/mcp-workspace.ts +12 -12
- package/src/renderer/process-modal.ts +17 -8
- package/src/renderer/profile-picker-modal.ts +3 -11
- package/src/renderer/session-picker-modal.ts +2 -10
- package/src/renderer/settings-modal.ts +12 -8
- package/src/renderer/ui-factory.ts +4 -32
- package/src/runtime/bootstrap-shell.ts +0 -13
- package/src/runtime/bootstrap.ts +0 -10
- package/src/runtime/onboarding/derivation.ts +6 -6
- package/src/verification/live-verifier.ts +148 -13
- package/src/version.ts +10 -3
- package/src/input/commands/quit-shared.ts +0 -162
- package/src/renderer/git-status.ts +0 -89
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GoodVibes Agent will be recorded here.
|
|
4
4
|
|
|
5
|
+
## 0.1.11 - 2026-05-31
|
|
6
|
+
|
|
7
|
+
- d20a93e Allow explicit recall review without yes
|
|
8
|
+
- 601f41c Require confirmation for eval execution
|
|
9
|
+
- f41befb Block Cloudflare onboarding mutations
|
|
10
|
+
- 79071ec Block implicit block file saves
|
|
11
|
+
- 40aca02 Block inline diff file edits in Agent
|
|
12
|
+
- 854eda8 Block MCP workspace config mutations
|
|
13
|
+
- 665c423 Require confirmation for CLI Agent Knowledge ingest
|
|
14
|
+
- f07255a Require confirmation for recall review mutations
|
|
15
|
+
- 6e78ec3 Require confirmation for Agent Knowledge mutations
|
|
16
|
+
- c1e5ac1 Require confirmation for operator control mutations
|
|
17
|
+
- 5d6fc3c Require confirmation for local state mutations
|
|
18
|
+
- 3afd788 Require confirmation for remaining export paths
|
|
19
|
+
- d36ae96 Require confirmation for portable state bundles
|
|
20
|
+
- 1f0caab Require confirmation for setup and remote exports
|
|
21
|
+
- 2e149c9 Require confirmation for incident and handoff exports
|
|
22
|
+
- b439c55 Require confirmation for settings mutations
|
|
23
|
+
- f7c8fe6 Require confirmation for platform auth mutations
|
|
24
|
+
- 09064e0 Require confirmation for auth and service mutations
|
|
25
|
+
- 55e8b8d Require confirmation for marketplace mutations
|
|
26
|
+
- 88becca Require confirmation for plugin mutations
|
|
27
|
+
- 89c0584 Require confirmation for local provider mutations
|
|
28
|
+
- 7f3af1b Require confirmation for managed hook mutations
|
|
29
|
+
- 323426c Require confirmation for destructive workplan cleanup
|
|
30
|
+
- 191350e Require confirmation for side-effecting slash commands
|
|
31
|
+
|
|
32
|
+
## 0.1.10 - 2026-05-31
|
|
33
|
+
|
|
34
|
+
- 93aba19 Block agent-spawning hook authoring
|
|
35
|
+
- 735839a Prune git header renderer from Agent
|
|
36
|
+
- 95d22fd Remove unused git shell bootstrap wiring
|
|
37
|
+
- 1392ebc Remove Agent write-quit commit helper
|
|
38
|
+
- df6572f Remove coding header posture from Agent shell
|
|
39
|
+
- 2b8e679 Align live verification with Agent routes
|
|
40
|
+
- 70eb800 Add stable typecheck release scripts
|
|
41
|
+
- 6b57500 Hide local agent activity in Agent UI
|
|
42
|
+
- 7166188 Add Agent Knowledge CLI shortcuts
|
|
43
|
+
- 386c19d Align service diagnostics with Agent boundaries
|
|
44
|
+
- e8b19db Lock daemon-owned settings in Agent
|
|
45
|
+
|
|
5
46
|
## 0.1.9 - 2026-05-31
|
|
6
47
|
|
|
7
48
|
- 75e5d4a Align shell surface delegation test
|
package/README.md
CHANGED
package/docs/getting-started.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Getting Started
|
|
2
2
|
|
|
3
|
-
GoodVibes Agent `0.1.
|
|
3
|
+
GoodVibes Agent `0.1.9` is the current installable public alpha of the personal operator assistant built on the GoodVibes TUI foundation.
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Release And Publishing
|
|
2
2
|
|
|
3
|
-
GoodVibes Agent `0.1.
|
|
3
|
+
GoodVibes Agent `0.1.9` is the current installable public alpha release.
|
|
4
4
|
|
|
5
5
|
## Package Identity
|
|
6
6
|
|
|
@@ -17,7 +17,7 @@ Before any release candidate:
|
|
|
17
17
|
|
|
18
18
|
```sh
|
|
19
19
|
bun install
|
|
20
|
-
|
|
20
|
+
bun run typecheck
|
|
21
21
|
bun run build
|
|
22
22
|
bun run package:install-check
|
|
23
23
|
bun run publish:check
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Near-fork GoodVibes operator assistant with the GoodVibes TUI shell, renderer, input, fullscreen workspace, and daemon-connected Agent product brain.",
|
|
6
6
|
"type": "module",
|
|
@@ -40,6 +40,8 @@
|
|
|
40
40
|
"dev": "bun run src/main.ts",
|
|
41
41
|
"tui": "bun run src/main.ts",
|
|
42
42
|
"dev:watch": "bun --watch src/main.ts",
|
|
43
|
+
"typecheck": "bunx tsc --noEmit",
|
|
44
|
+
"check:types": "bun run typecheck",
|
|
43
45
|
"prebuild": "bun run scripts/prebuild.ts",
|
|
44
46
|
"build": "bun build src/main.ts --compile --outfile dist/goodvibes-agent",
|
|
45
47
|
"build:linux-x64": "bun build src/main.ts --compile --target=bun-linux-x64 --outfile dist/goodvibes-agent-linux-x64",
|
|
@@ -61,6 +63,7 @@
|
|
|
61
63
|
"build:all": "bun run scripts/build.ts --all",
|
|
62
64
|
"perf:check": "bun run scripts/perf-check.ts",
|
|
63
65
|
"architecture:check": "bun run scripts/check-architecture.ts",
|
|
66
|
+
"audit:home": "bun run scripts/audit-goodvibes-home.ts",
|
|
64
67
|
"foundation:artifacts": "bun run scripts/export-foundation-artifacts.ts",
|
|
65
68
|
"verification:ledger": "bun run scripts/verification-ledger.ts",
|
|
66
69
|
"verification:live": "bun run scripts/verify-live.ts",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
-
import {
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { join } from 'node:path';
|
|
4
3
|
import { createBrowserAgentSdk } from '@pellux/goodvibes-sdk/browser/agent';
|
|
5
4
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
5
|
+
import { SDK_VERSION, VERSION } from '../version.ts';
|
|
6
6
|
import type { CliCommandOutput } from './types.ts';
|
|
7
7
|
import type { CliCommandRuntime } from './management.ts';
|
|
8
8
|
import { formatJsonOrText, yesNo } from './management.ts';
|
|
@@ -149,24 +149,21 @@ function hasFlag(args: readonly string[], flag: string): boolean {
|
|
|
149
149
|
return args.includes(flag);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
function
|
|
153
|
-
|
|
152
|
+
function stripCommandFlag(args: readonly string[], flag: string): { readonly rest: readonly string[]; readonly present: boolean } {
|
|
153
|
+
const rest: string[] = [];
|
|
154
|
+
let present = false;
|
|
155
|
+
for (const arg of args) {
|
|
156
|
+
if (arg === flag) {
|
|
157
|
+
present = true;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
rest.push(arg);
|
|
161
|
+
}
|
|
162
|
+
return { rest, present };
|
|
154
163
|
}
|
|
155
164
|
|
|
156
165
|
function readPackageMetadata(): { readonly version: string; readonly sdkVersion: string } {
|
|
157
|
-
|
|
158
|
-
const parsed = JSON.parse(readFileSync(packageJsonPath(), 'utf-8')) as unknown;
|
|
159
|
-
if (!isRecord(parsed)) return { version: 'unknown', sdkVersion: 'unknown' };
|
|
160
|
-
const dependencies = isRecord(parsed.dependencies) ? parsed.dependencies : {};
|
|
161
|
-
return {
|
|
162
|
-
version: typeof parsed.version === 'string' ? parsed.version : 'unknown',
|
|
163
|
-
sdkVersion: typeof dependencies['@pellux/goodvibes-sdk'] === 'string'
|
|
164
|
-
? dependencies['@pellux/goodvibes-sdk']
|
|
165
|
-
: 'unknown',
|
|
166
|
-
};
|
|
167
|
-
} catch {
|
|
168
|
-
return { version: 'unknown', sdkVersion: 'unknown' };
|
|
169
|
-
}
|
|
166
|
+
return { version: VERSION, sdkVersion: SDK_VERSION };
|
|
170
167
|
}
|
|
171
168
|
|
|
172
169
|
function resolveDaemonConnection(runtime: CliCommandRuntime): AgentDaemonConnection {
|
|
@@ -460,7 +457,9 @@ async function runKnowledgeCall<TData>(
|
|
|
460
457
|
}
|
|
461
458
|
|
|
462
459
|
export async function handleAgentKnowledgeCommand(runtime: CliCommandRuntime): Promise<CliCommandOutput> {
|
|
463
|
-
const [sub = 'status', ...
|
|
460
|
+
const [sub = 'status', ...rawRest] = runtime.cli.commandArgs;
|
|
461
|
+
const confirmation = stripCommandFlag(rawRest, '--yes');
|
|
462
|
+
const rest = confirmation.rest;
|
|
464
463
|
const normalized = sub.toLowerCase();
|
|
465
464
|
const json = runtime.cli.flags.outputFormat === 'json';
|
|
466
465
|
const disallowedScopeFlag = findDisallowedKnowledgeScopeFlag(rest);
|
|
@@ -528,7 +527,19 @@ export async function handleAgentKnowledgeCommand(runtime: CliCommandRuntime): P
|
|
|
528
527
|
if (normalized === 'ingest-url') {
|
|
529
528
|
const values = commandValues(rest);
|
|
530
529
|
const url = values[0];
|
|
531
|
-
if (!url) return { output: 'Usage: goodvibes-agent knowledge ingest-url <url> [--title <title>] [--tags a,b]', exitCode: 2 };
|
|
530
|
+
if (!url) return { output: 'Usage: goodvibes-agent knowledge ingest-url <url> [--title <title>] [--tags a,b] --yes', exitCode: 2 };
|
|
531
|
+
if (!confirmation.present) {
|
|
532
|
+
const failure = {
|
|
533
|
+
ok: false,
|
|
534
|
+
kind: 'confirmation_required',
|
|
535
|
+
error: `Refusing to ingest URL into Agent Knowledge ${url} without --yes.`,
|
|
536
|
+
route: AGENT_KNOWLEDGE_METHODS.ingestUrl.route,
|
|
537
|
+
};
|
|
538
|
+
return {
|
|
539
|
+
output: json ? JSON.stringify(failure, null, 2) : `${failure.error}\nUsage: goodvibes-agent knowledge ingest-url <url> [--title <title>] [--tags a,b] --yes`,
|
|
540
|
+
exitCode: 2,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
532
543
|
const title = readOptionValue(rest, '--title');
|
|
533
544
|
const tags = readStringList(rest, '--tags');
|
|
534
545
|
const result = await runKnowledgeCall(runtime, AGENT_KNOWLEDGE_METHODS.ingestUrl, async (connection) => (
|
|
@@ -548,11 +559,26 @@ export async function handleAgentKnowledgeCommand(runtime: CliCommandRuntime): P
|
|
|
548
559
|
}
|
|
549
560
|
|
|
550
561
|
return {
|
|
551
|
-
output: 'Usage: goodvibes-agent knowledge [status|ask <question>|search <query>|ingest-url <url>]',
|
|
562
|
+
output: 'Usage: goodvibes-agent knowledge [status|ask <question>|search <query>|ingest-url <url> --yes]',
|
|
552
563
|
exitCode: 2,
|
|
553
564
|
};
|
|
554
565
|
}
|
|
555
566
|
|
|
567
|
+
export async function handleAgentKnowledgeShortcutCommand(
|
|
568
|
+
runtime: CliCommandRuntime,
|
|
569
|
+
subcommand: 'ask' | 'search',
|
|
570
|
+
): Promise<CliCommandOutput> {
|
|
571
|
+
return handleAgentKnowledgeCommand({
|
|
572
|
+
...runtime,
|
|
573
|
+
cli: {
|
|
574
|
+
...runtime.cli,
|
|
575
|
+
command: 'knowledge',
|
|
576
|
+
rawCommand: 'knowledge',
|
|
577
|
+
commandArgs: [subcommand, ...runtime.cli.commandArgs],
|
|
578
|
+
},
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
|
|
556
582
|
export async function handleCompatCommand(runtime: CliCommandRuntime): Promise<CliCommandOutput> {
|
|
557
583
|
const connection = resolveDaemonConnection(runtime);
|
|
558
584
|
const metadata = readPackageMetadata();
|
package/src/cli/help.ts
CHANGED
|
@@ -41,6 +41,7 @@ export function renderGoodVibesHelp(binary = 'goodvibes-agent'): string {
|
|
|
41
41
|
' auth Inspect and manage local users, sessions, and bootstrap auth',
|
|
42
42
|
' compat Inspect Agent SDK pin, daemon version, and Agent knowledge route readiness',
|
|
43
43
|
' knowledge Use isolated Agent Knowledge/Wiki routes',
|
|
44
|
+
' ask|search Shortcuts for isolated Agent Knowledge ask/search',
|
|
44
45
|
' delegate Explicitly delegate build/fix/review work to GoodVibes TUI',
|
|
45
46
|
' subscription Start/finish/logout provider subscription sessions',
|
|
46
47
|
' secrets List, set, link, delete, and test GoodVibes secret refs',
|
|
@@ -95,6 +96,8 @@ export function renderGoodVibesHelp(binary = 'goodvibes-agent'): string {
|
|
|
95
96
|
` ${binary} compat`,
|
|
96
97
|
` ${binary} knowledge status`,
|
|
97
98
|
` ${binary} knowledge ask "What is GoodVibes Agent?"`,
|
|
99
|
+
` ${binary} ask "What is GoodVibes Agent?"`,
|
|
100
|
+
` ${binary} search "release checklist"`,
|
|
98
101
|
` ${binary} delegate --wrfc "fix the failing tests in ~/work/project"`,
|
|
99
102
|
` ${binary} surfaces`,
|
|
100
103
|
` ${binary} surfaces check`,
|
|
@@ -164,16 +167,26 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
164
167
|
'knowledge status',
|
|
165
168
|
'knowledge ask <question> [--limit <n>] [--mode concise|standard|detailed]',
|
|
166
169
|
'knowledge search <query> [--limit <n>]',
|
|
167
|
-
'knowledge ingest-url <url> [--title <title>] [--tags a,b]',
|
|
170
|
+
'knowledge ingest-url <url> [--title <title>] [--tags a,b] --yes',
|
|
168
171
|
],
|
|
169
172
|
summary: 'Call isolated Agent Knowledge/Wiki routes under /api/goodvibes-agent/knowledge. No default wiki or HomeGraph fallback.',
|
|
170
173
|
examples: [
|
|
171
174
|
'knowledge status',
|
|
172
175
|
'knowledge ask "What is GoodVibes Agent?"',
|
|
173
176
|
'knowledge search "release checklist"',
|
|
174
|
-
'knowledge ingest-url https://example.com/page --title "Reference"',
|
|
177
|
+
'knowledge ingest-url https://example.com/page --title "Reference" --yes',
|
|
175
178
|
],
|
|
176
179
|
},
|
|
180
|
+
ask: {
|
|
181
|
+
usage: ['ask <question> [--limit <n>] [--mode concise|standard|detailed]'],
|
|
182
|
+
summary: 'Shortcut for isolated Agent Knowledge ask. This never queries default Knowledge/Wiki or HomeGraph.',
|
|
183
|
+
examples: ['ask "What is GoodVibes Agent?"', 'ask "release checklist" --mode concise'],
|
|
184
|
+
},
|
|
185
|
+
search: {
|
|
186
|
+
usage: ['search <query> [--limit <n>]'],
|
|
187
|
+
summary: 'Shortcut for isolated Agent Knowledge search. This never queries default Knowledge/Wiki or HomeGraph.',
|
|
188
|
+
examples: ['search "release checklist"', 'search "operator workspace" --limit 5'],
|
|
189
|
+
},
|
|
177
190
|
delegate: {
|
|
178
191
|
usage: ['delegate [--wrfc] <build/fix/review task>'],
|
|
179
192
|
summary: 'Create one shared-session task request for GoodVibes TUI. WRFC is requested only with --wrfc.',
|
|
@@ -329,9 +329,9 @@ export async function buildControlPlaneStatusResult(runtime: CliCommandRuntime):
|
|
|
329
329
|
};
|
|
330
330
|
const issues: string[] = [];
|
|
331
331
|
if (enabled === true && !reachable) issues.push(`Control plane is enabled but not reachable on ${binding.host}:${binding.port}.`);
|
|
332
|
-
if (enabled === true && service.enabled !== true) issues.push('Control plane is enabled but service
|
|
333
|
-
if (enabled === true && service.autostart !== true) issues.push('Control plane is enabled but
|
|
334
|
-
if (enabled === true && service.restartOnFailure !== true) issues.push('Control plane is enabled but
|
|
332
|
+
if (enabled === true && service.enabled !== true) issues.push('Control plane is enabled on the external daemon config, but Agent service ownership is disabled.');
|
|
333
|
+
if (enabled === true && service.autostart !== true) issues.push('Control plane is enabled on the external daemon config, but daemon autostart is off.');
|
|
334
|
+
if (enabled === true && service.restartOnFailure !== true) issues.push('Control plane is enabled on the external daemon config, but restart-on-failure is off.');
|
|
335
335
|
if (isNetworkFacing(enabled, binding) && !auth.userStorePresent) issues.push('Network-facing control plane has no local auth user store.');
|
|
336
336
|
if (isNetworkFacing(enabled, binding) && auth.bootstrapCredentialPresent) issues.push('Network-facing control plane still has a bootstrap credential file.');
|
|
337
337
|
return {
|
package/src/cli/management.ts
CHANGED
|
@@ -32,7 +32,7 @@ import { handleServiceCommand } from './service-command.ts';
|
|
|
32
32
|
import { handleBundleCommand } from './bundle-command.ts';
|
|
33
33
|
import { buildListenerTestResult, formatListenerTestResult, handleSurfacesCommand } from './surface-command.ts';
|
|
34
34
|
import { buildControlPlaneStatusResult, formatControlPlaneStatus, handleSecrets, handleSessions, handleTasks, renderPairing, renderRemote, renderSubscriptions, renderWeb } from './management-commands.ts';
|
|
35
|
-
import { handleAgentKnowledgeCommand, handleCompatCommand, handleDelegateCommand } from './agent-knowledge-command.ts';
|
|
35
|
+
import { handleAgentKnowledgeCommand, handleAgentKnowledgeShortcutCommand, handleCompatCommand, handleDelegateCommand } from './agent-knowledge-command.ts';
|
|
36
36
|
import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
|
|
37
37
|
|
|
38
38
|
export interface CliCommandRuntime {
|
|
@@ -703,6 +703,12 @@ export async function handleGoodVibesCliCommand(runtime: CliCommandRuntime): Pro
|
|
|
703
703
|
console.log(result.output);
|
|
704
704
|
return { handled: true, exitCode: result.exitCode };
|
|
705
705
|
}
|
|
706
|
+
case 'ask':
|
|
707
|
+
case 'search': {
|
|
708
|
+
const result = await handleAgentKnowledgeShortcutCommand(runtime, runtime.cli.command);
|
|
709
|
+
console.log(result.output);
|
|
710
|
+
return { handled: true, exitCode: result.exitCode };
|
|
711
|
+
}
|
|
706
712
|
case 'delegate': {
|
|
707
713
|
const result = await handleDelegateCommand(runtime);
|
|
708
714
|
console.log(result.output);
|
package/src/cli/parser.ts
CHANGED
|
@@ -31,6 +31,9 @@ const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
|
|
|
31
31
|
knowledge: 'knowledge',
|
|
32
32
|
know: 'knowledge',
|
|
33
33
|
kb: 'knowledge',
|
|
34
|
+
ask: 'ask',
|
|
35
|
+
search: 'search',
|
|
36
|
+
find: 'search',
|
|
34
37
|
delegate: 'delegate',
|
|
35
38
|
build: 'delegate',
|
|
36
39
|
subscription: 'subscription',
|
|
@@ -397,19 +397,19 @@ export async function buildCliServicePosture(
|
|
|
397
397
|
const issues: string[] = [];
|
|
398
398
|
|
|
399
399
|
if (serverBackedEnabled && !config.enabled) {
|
|
400
|
-
issues.push('
|
|
400
|
+
issues.push('Daemon-owned surfaces are configured, but Agent service ownership is disabled.');
|
|
401
401
|
}
|
|
402
402
|
if (config.enabled && !config.autostart) {
|
|
403
|
-
issues.push('
|
|
403
|
+
issues.push('External daemon service config has autostart off.');
|
|
404
404
|
}
|
|
405
405
|
if (config.enabled && !config.restartOnFailure) {
|
|
406
|
-
issues.push('
|
|
406
|
+
issues.push('External daemon service config has restart-on-failure off.');
|
|
407
407
|
}
|
|
408
408
|
if (config.enabled && !status.installed) {
|
|
409
|
-
issues.push('
|
|
409
|
+
issues.push('External daemon service config is enabled, but no platform service definition is installed.');
|
|
410
410
|
}
|
|
411
411
|
if (config.enabled && !status.running) {
|
|
412
|
-
issues.push('
|
|
412
|
+
issues.push('External daemon service config is enabled, but the managed service is not running.');
|
|
413
413
|
}
|
|
414
414
|
if (status.actionError) {
|
|
415
415
|
issues.push(`Service manager reported an error: ${status.actionError}`);
|
|
@@ -454,7 +454,7 @@ function yesNo(value: boolean): string {
|
|
|
454
454
|
export function formatCliServicePosture(posture: CliServicePosture, json = false): string {
|
|
455
455
|
if (json) return JSON.stringify(posture, null, 2);
|
|
456
456
|
return [
|
|
457
|
-
'GoodVibes service',
|
|
457
|
+
'GoodVibes external daemon service',
|
|
458
458
|
` enabled: ${yesNo(posture.config.enabled)}`,
|
|
459
459
|
` autostart: ${yesNo(posture.config.autostart)}`,
|
|
460
460
|
` restartOnFailure: ${yesNo(posture.config.restartOnFailure)}`,
|
package/src/cli/status.ts
CHANGED
|
@@ -122,10 +122,10 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
|
|
|
122
122
|
id: 'service-disabled-for-server-surfaces',
|
|
123
123
|
area: 'service',
|
|
124
124
|
severity: 'warning',
|
|
125
|
-
summary: '
|
|
125
|
+
summary: 'Daemon-owned surfaces are configured while Agent service ownership is disabled.',
|
|
126
126
|
cause: 'One or more daemon, control-plane, listener, or web settings are enabled while service.enabled is false.',
|
|
127
|
-
impact: 'The
|
|
128
|
-
action: '
|
|
127
|
+
impact: 'The external daemon host must own availability for those surfaces; Agent will not start or enable them.',
|
|
128
|
+
action: 'Manage surface/service posture from GoodVibes TUI or the daemon host, then use Agent for read-only diagnostics.',
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -134,10 +134,10 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
|
|
|
134
134
|
id: 'service-autostart-disabled',
|
|
135
135
|
area: 'service',
|
|
136
136
|
severity: 'warning',
|
|
137
|
-
summary: '
|
|
137
|
+
summary: 'External daemon service config has autostart off.',
|
|
138
138
|
cause: 'service.enabled is true and service.autostart is false.',
|
|
139
139
|
impact: 'The external GoodVibes daemon may not be available after login or reboot even though service mode is selected.',
|
|
140
|
-
action: '
|
|
140
|
+
action: 'Configure daemon autostart from GoodVibes TUI or the daemon host; Agent will not mutate this setting.',
|
|
141
141
|
});
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -146,10 +146,10 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
|
|
|
146
146
|
id: 'service-restart-disabled',
|
|
147
147
|
area: 'service',
|
|
148
148
|
severity: 'warning',
|
|
149
|
-
summary: '
|
|
149
|
+
summary: 'External daemon service config has restart-on-failure off.',
|
|
150
150
|
cause: 'service.enabled is true and service.restartOnFailure is false.',
|
|
151
151
|
impact: 'A crashed daemon or listener may stay down until manually restarted.',
|
|
152
|
-
action: '
|
|
152
|
+
action: 'Configure restart-on-failure from GoodVibes TUI or the daemon host; Agent will not mutate this setting.',
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
155
|
|
|
@@ -163,7 +163,7 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
|
|
|
163
163
|
summary: issue,
|
|
164
164
|
cause: 'The service lifecycle inspection found a mismatch between configured service/surface state and observed host state.',
|
|
165
165
|
impact: 'Daemon, control-plane, listener, or web availability may not match the configuration.',
|
|
166
|
-
action: '
|
|
166
|
+
action: 'Use goodvibes-agent service check for read-only detail, then manage the daemon from GoodVibes TUI or your daemon host tooling.',
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
169
|
}
|
|
@@ -326,7 +326,7 @@ export function renderCliStatus(options: CliStatusOptions): string {
|
|
|
326
326
|
? ` operatorTokens: ${options.auth.operatorTokenPresent ? 'present' : 'missing'} (${options.auth.operatorTokenPath})`
|
|
327
327
|
: ' operatorTokens: unknown',
|
|
328
328
|
'',
|
|
329
|
-
'Service:',
|
|
329
|
+
'External Daemon Service:',
|
|
330
330
|
` enabled: ${yesNo(serviceEnabled)}`,
|
|
331
331
|
` autostart: ${yesNo(serviceAutostart)}`,
|
|
332
332
|
` restartOnFailure: ${yesNo(restartOnFailure)}`,
|
|
@@ -217,9 +217,9 @@ export async function buildListenerTestResult(runtime: CliCommandRuntime): Promi
|
|
|
217
217
|
}).filter((surface) => surface.enabled === true);
|
|
218
218
|
const issues: string[] = [];
|
|
219
219
|
if (enabled !== true) issues.push('HTTP listener is disabled.');
|
|
220
|
-
if (enabled === true && service.enabled !== true) issues.push('HTTP listener is enabled but service
|
|
221
|
-
if (enabled === true && service.autostart !== true) issues.push('HTTP listener is enabled but
|
|
222
|
-
if (enabled === true && service.restartOnFailure !== true) issues.push('HTTP listener is enabled but
|
|
220
|
+
if (enabled === true && service.enabled !== true) issues.push('HTTP listener is enabled on the external daemon config, but Agent service ownership is disabled.');
|
|
221
|
+
if (enabled === true && service.autostart !== true) issues.push('HTTP listener is enabled on the external daemon config, but daemon autostart is off.');
|
|
222
|
+
if (enabled === true && service.restartOnFailure !== true) issues.push('HTTP listener is enabled on the external daemon config, but restart-on-failure is off.');
|
|
223
223
|
if (isNetworkFacing(enabled, binding) && !auth.userStorePresent) issues.push('Network-facing listener has no local auth user store.');
|
|
224
224
|
if (isNetworkFacing(enabled, binding) && auth.bootstrapCredentialPresent) issues.push('Network-facing listener still has a bootstrap credential file.');
|
|
225
225
|
for (const surface of surfaces) {
|
package/src/cli/types.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from '../../runtime/cloudflare-control-plane.ts';
|
|
12
12
|
import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
13
13
|
import { requireShellPaths } from './runtime-services.ts';
|
|
14
|
+
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
14
15
|
|
|
15
16
|
interface ParsedCloudflareArgs {
|
|
16
17
|
readonly positional: readonly string[];
|
|
@@ -22,10 +23,12 @@ export function registerCloudflareRuntimeCommands(registry: CommandRegistry): vo
|
|
|
22
23
|
name: 'cloudflare',
|
|
23
24
|
aliases: ['cf'],
|
|
24
25
|
description: 'Inspect and manage optional Cloudflare batch/control-plane integration through daemon SDK routes',
|
|
25
|
-
usage: '[status|setup|requirements|create-token|discover|validate|provision|verify|disable] [flags]',
|
|
26
|
+
usage: '[status|setup|requirements|create-token --yes|discover|validate|provision --yes|verify|disable --yes] [flags]',
|
|
26
27
|
async handler(args, ctx) {
|
|
27
|
-
const
|
|
28
|
-
const
|
|
28
|
+
const confirmation = stripYesFlag(args);
|
|
29
|
+
const commandArgs = [...confirmation.rest];
|
|
30
|
+
const subcommand = (commandArgs[0] ?? 'status').toLowerCase();
|
|
31
|
+
const parsed = parseCloudflareArgs(commandArgs.slice(1));
|
|
29
32
|
if (subcommand === 'setup' || subcommand === 'onboarding') {
|
|
30
33
|
ctx.openOnboardingWizard?.({ mode: 'edit', reset: true });
|
|
31
34
|
ctx.print('Opening onboarding wizard. Select the Cloudflare batch capability to configure Cloudflare.');
|
|
@@ -80,9 +83,13 @@ export function registerCloudflareRuntimeCommands(registry: CommandRegistry): vo
|
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
if (subcommand === 'create-token') {
|
|
86
|
+
if (!confirmation.yes) {
|
|
87
|
+
requireYesFlag(ctx, 'create and store a Cloudflare operational token', '/cloudflare create-token [flags] --yes');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
83
90
|
const bootstrapToken = getFlag(parsed, 'bootstrap-token') || readTokenEnv(parsed, 'bootstrap-env');
|
|
84
91
|
if (!bootstrapToken) {
|
|
85
|
-
ctx.print('Usage: /cloudflare create-token --account <account-id> --bootstrap-token <token>
|
|
92
|
+
ctx.print('Usage: /cloudflare create-token --account <account-id> (--bootstrap-token <token> | --bootstrap-env <env-name>) --yes');
|
|
86
93
|
return;
|
|
87
94
|
}
|
|
88
95
|
const result = await client.createOperationalToken({
|
|
@@ -141,6 +148,10 @@ export function registerCloudflareRuntimeCommands(registry: CommandRegistry): vo
|
|
|
141
148
|
}
|
|
142
149
|
|
|
143
150
|
if (subcommand === 'provision') {
|
|
151
|
+
if (!confirmation.yes) {
|
|
152
|
+
requireYesFlag(ctx, 'provision Cloudflare resources and persist config', '/cloudflare provision [flags] --yes');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
144
155
|
const result = await client.provision({
|
|
145
156
|
...cloudflareAuthInput(parsed),
|
|
146
157
|
components: componentsFromArgs(parsed),
|
|
@@ -212,6 +223,10 @@ export function registerCloudflareRuntimeCommands(registry: CommandRegistry): vo
|
|
|
212
223
|
}
|
|
213
224
|
|
|
214
225
|
if (subcommand === 'disable') {
|
|
226
|
+
if (!confirmation.yes) {
|
|
227
|
+
requireYesFlag(ctx, 'disable Cloudflare integration and persist config', '/cloudflare disable [flags] --yes');
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
215
230
|
const result = await client.disable({
|
|
216
231
|
...cloudflareAuthInput(parsed),
|
|
217
232
|
...optionalString('workerName', getFlag(parsed, 'worker-name')),
|
|
@@ -227,7 +242,7 @@ export function registerCloudflareRuntimeCommands(registry: CommandRegistry): vo
|
|
|
227
242
|
return;
|
|
228
243
|
}
|
|
229
244
|
|
|
230
|
-
ctx.print('Usage: /cloudflare [status|setup|requirements|create-token|discover|validate|provision|verify|disable] [flags]');
|
|
245
|
+
ctx.print('Usage: /cloudflare [status|setup|requirements|create-token --yes|discover|validate|provision --yes|verify|disable --yes] [flags]');
|
|
231
246
|
} catch (error) {
|
|
232
247
|
ctx.print(`Cloudflare ${subcommand} failed: ${formatCloudflareError(error)}`);
|
|
233
248
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CommandContext } from '../command-registry.ts';
|
|
2
|
+
|
|
3
|
+
export interface ConfirmationArgs {
|
|
4
|
+
readonly rest: readonly string[];
|
|
5
|
+
readonly yes: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function stripYesFlag(args: readonly string[]): ConfirmationArgs {
|
|
9
|
+
const rest: string[] = [];
|
|
10
|
+
let yes = false;
|
|
11
|
+
for (const token of args) {
|
|
12
|
+
if (token === '--yes') {
|
|
13
|
+
yes = true;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
rest.push(token);
|
|
17
|
+
}
|
|
18
|
+
return { rest, yes };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function requireYesFlag(ctx: CommandContext, action: string, usage: string): boolean {
|
|
22
|
+
ctx.print(`Refusing to ${action} without --yes.\nUsage: ${usage}`);
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
@@ -3,13 +3,16 @@ import { scan, persistProviders } from '@pellux/goodvibes-sdk/platform/discovery
|
|
|
3
3
|
import { requireProviderApi, requireShellPaths } from './runtime-services.ts';
|
|
4
4
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
5
5
|
import { GOODVIBES_AGENT_SURFACE_ROOT } from '../../config/surface.ts';
|
|
6
|
+
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
6
7
|
|
|
7
8
|
export function registerDiscoveryRuntimeCommands(registry: CommandRegistry): void {
|
|
8
9
|
registry.register({
|
|
9
10
|
name: 'scan',
|
|
10
11
|
aliases: [],
|
|
11
12
|
description: 'Scan localhost and LAN for local LLM servers',
|
|
12
|
-
|
|
13
|
+
usage: '[--yes]',
|
|
14
|
+
async handler(args, ctx) {
|
|
15
|
+
const { yes } = stripYesFlag(args);
|
|
13
16
|
ctx.print('Scanning for local LLM servers...');
|
|
14
17
|
ctx.renderRequest();
|
|
15
18
|
|
|
@@ -33,18 +36,24 @@ export function registerDiscoveryRuntimeCommands(registry: CommandRegistry): voi
|
|
|
33
36
|
ctx.print(lines.join('\n'));
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
try {
|
|
37
|
-
await requireProviderApi(ctx).registerDiscoveredProviders(result.servers);
|
|
38
|
-
} catch (err) {
|
|
39
|
-
ctx.print(`[Scan] Warning: failed to register some providers: ${summarizeError(err)}`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
39
|
if (result.servers.length > 0) {
|
|
40
|
+
if (!yes) {
|
|
41
|
+
requireYesFlag(ctx, 'persist discovered local provider configuration', '/scan --yes');
|
|
42
|
+
ctx.print('[Scan] Discovery results were not saved. Rerun /scan --yes to register and persist providers.');
|
|
43
|
+
ctx.renderRequest();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
await requireProviderApi(ctx).registerDiscoveredProviders(result.servers);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
ctx.print(`[Scan] Warning: failed to register some providers: ${summarizeError(err)}`);
|
|
50
|
+
}
|
|
43
51
|
const shellPaths = requireShellPaths(ctx);
|
|
44
52
|
persistProviders({
|
|
45
53
|
homeDirectory: shellPaths.homeDirectory,
|
|
46
54
|
surfaceRoot: GOODVIBES_AGENT_SURFACE_ROOT,
|
|
47
55
|
}, result.servers);
|
|
56
|
+
ctx.print('[Scan] Discovered providers registered and persisted.');
|
|
48
57
|
}
|
|
49
58
|
ctx.renderRequest();
|
|
50
59
|
},
|