@pellux/goodvibes-agent 0.1.63 → 0.1.64
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 +6 -0
- package/package.json +1 -1
- package/src/cli/agent-knowledge-command.ts +1 -1
- package/src/cli/service-posture.ts +1 -1
- package/src/cli/status.ts +3 -3
- package/src/cli/surface-command.ts +1 -1
- package/src/input/agent-workspace-setup.ts +1 -1
- package/src/input/agent-workspace.ts +1 -1
- package/src/input/commands/agent-runtime-profile-runtime.ts +1 -1
- package/src/input/commands/local-auth-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +28 -15
- package/src/input/commands/remote-runtime-setup.ts +6 -6
- package/src/input/commands/routines-runtime.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-steps.ts +1 -1
- package/src/panels/automation-control-panel.ts +2 -2
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +3 -3
- package/src/panels/control-plane-panel.ts +2 -2
- package/src/panels/local-auth-panel.ts +1 -1
- package/src/panels/project-planning-panel.ts +2 -2
- package/src/panels/remote-panel.ts +2 -2
- package/src/panels/schedule-panel.ts +1 -1
- package/src/panels/watchers-panel.ts +1 -1
- package/src/renderer/settings-modal-helpers.ts +1 -1
- package/src/renderer/settings-modal.ts +2 -2
- package/src/runtime/bootstrap.ts +7 -7
- package/src/runtime/index.ts +2 -2
- package/src/runtime/onboarding/derivation.ts +15 -15
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GoodVibes Agent will be recorded here.
|
|
4
4
|
|
|
5
|
+
## 0.1.64 - 2026-05-31
|
|
6
|
+
|
|
7
|
+
- Cleaned remaining visible setup, workspace, panel, and auth wording that still exposed copied runtime-host terminology.
|
|
8
|
+
- Changed the advertised auth login target to runtime/listener while keeping legacy runtime-host aliases non-prominent.
|
|
9
|
+
- Added regression coverage so setup and workspace text stay Agent-specific and avoid copied platform/product wording.
|
|
10
|
+
|
|
5
11
|
## 0.1.63 - 2026-05-31
|
|
6
12
|
|
|
7
13
|
- Rewrote the remaining repo docs that still read like copied runtime/API notes into Agent-facing product docs.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.64",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
|
|
6
6
|
"type": "module",
|
|
@@ -443,7 +443,7 @@ async function runKnowledgeCall<TData>(
|
|
|
443
443
|
return {
|
|
444
444
|
ok: false,
|
|
445
445
|
kind: 'auth_required',
|
|
446
|
-
error: `No
|
|
446
|
+
error: `No runtime operator token found at ${connection.tokenPath}`,
|
|
447
447
|
baseUrl: connection.baseUrl,
|
|
448
448
|
route: method.route,
|
|
449
449
|
};
|
|
@@ -234,7 +234,7 @@ export function formatCliServicePosture(posture: CliServicePosture, json = false
|
|
|
234
234
|
` service config enabled: ${yesNo(posture.config.enabled)}`,
|
|
235
235
|
` autostart config: ${yesNo(posture.config.autostart)}`,
|
|
236
236
|
` restartOnFailure config: ${yesNo(posture.config.restartOnFailure)}`,
|
|
237
|
-
`
|
|
237
|
+
` runtime host flag: ${yesNo(posture.config.daemonEnabled)}`,
|
|
238
238
|
` log: ${posture.log.path ?? 'n/a'} (${posture.log.exists ? 'present' : 'missing'})`,
|
|
239
239
|
...(posture.log.readError ? [` log read error: ${posture.log.readError}`] : []),
|
|
240
240
|
'',
|
package/src/cli/status.ts
CHANGED
|
@@ -136,7 +136,7 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
|
|
|
136
136
|
severity: 'warning',
|
|
137
137
|
summary: 'External runtime service config has autostart off.',
|
|
138
138
|
cause: 'service.enabled is true and service.autostart is false.',
|
|
139
|
-
impact: 'The external GoodVibes runtime may not be available after login or reboot even though
|
|
139
|
+
impact: 'The external GoodVibes runtime may not be available after login or reboot even though host-managed startup is selected.',
|
|
140
140
|
action: 'Configure autostart from GoodVibes TUI or the owning host; Agent will not mutate this setting.',
|
|
141
141
|
});
|
|
142
142
|
}
|
|
@@ -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
|
-
'External
|
|
329
|
+
'External Runtime Service:',
|
|
330
330
|
` enabled: ${yesNo(serviceEnabled)}`,
|
|
331
331
|
` autostart: ${yesNo(serviceAutostart)}`,
|
|
332
332
|
` restartOnFailure: ${yesNo(restartOnFailure)}`,
|
|
@@ -338,7 +338,7 @@ export function renderCliStatus(options: CliStatusOptions): string {
|
|
|
338
338
|
` log: ${options.service.log.path ?? 'n/a'} (${options.service.log.exists ? 'present' : 'missing'})`,
|
|
339
339
|
] : []),
|
|
340
340
|
'',
|
|
341
|
-
'
|
|
341
|
+
'Runtime Endpoints:',
|
|
342
342
|
bindLine('controlPlane', controlPlaneEnabled, controlPlaneBinding),
|
|
343
343
|
bindLine('httpListener', listenerEnabled, httpListenerBinding),
|
|
344
344
|
bindLine('web', webEnabled, webBinding),
|
|
@@ -155,7 +155,7 @@ export async function handleSurfacesCommand(runtime: CliCommandRuntime): Promise
|
|
|
155
155
|
'ntfy inbound topics:',
|
|
156
156
|
` chat: ${ntfyTopics.chatTopic}`,
|
|
157
157
|
` agent: ${ntfyTopics.agentTopic}`,
|
|
158
|
-
`
|
|
158
|
+
` runtime-only remote: ${ntfyTopics.remoteTopic}`,
|
|
159
159
|
` default delivery topic: ${String(config.get('surfaces.ntfy.topic') || '(none)')}`,
|
|
160
160
|
] : []),
|
|
161
161
|
...(includeProbe ? [
|
|
@@ -37,7 +37,7 @@ export function buildAgentWorkspaceSetupChecklist(input: AgentWorkspaceSetupChec
|
|
|
37
37
|
id: 'runtime',
|
|
38
38
|
label: 'External runtime',
|
|
39
39
|
status: 'ready',
|
|
40
|
-
detail: `Agent will connect to ${input.daemonBaseUrl}; runtime
|
|
40
|
+
detail: `Agent will connect to ${input.daemonBaseUrl}; runtime ownership stays outside this TUI.`,
|
|
41
41
|
command: '/status',
|
|
42
42
|
},
|
|
43
43
|
{
|
|
@@ -154,7 +154,7 @@ export class AgentWorkspace {
|
|
|
154
154
|
this.lastActionResult = {
|
|
155
155
|
kind: 'refreshed',
|
|
156
156
|
title: 'Runtime context refreshed',
|
|
157
|
-
detail: 'Provider, model, session, local memory,
|
|
157
|
+
detail: 'Provider, model, session, local memory, runtime endpoint, and Agent knowledge route posture were re-read from the live command context.',
|
|
158
158
|
};
|
|
159
159
|
}
|
|
160
160
|
|
|
@@ -83,7 +83,7 @@ function renderGuide(homeDirectory: string): string {
|
|
|
83
83
|
'5. Create a runtime profile from the imported starter:',
|
|
84
84
|
' /agent-profile create <name> --template <imported-id> --yes',
|
|
85
85
|
'',
|
|
86
|
-
'This writes only Agent-local starter/profile state. It does not mutate the
|
|
86
|
+
'This writes only Agent-local starter/profile state. It does not mutate the runtime host, default wiki, or non-Agent knowledge segments.',
|
|
87
87
|
].join('\n');
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -119,7 +119,7 @@ export function registerLocalAuthRuntimeCommands(registry: CommandRegistry): voi
|
|
|
119
119
|
registry.register({
|
|
120
120
|
name: 'local-auth',
|
|
121
121
|
aliases: ['auth-local'],
|
|
122
|
-
description: 'Inspect and manage local
|
|
122
|
+
description: 'Inspect and manage local runtime auth users, sessions, and bootstrap credentials',
|
|
123
123
|
usage: '[review|panel|add-user <username> <password> [roles] --yes|delete-user <username> --yes|rotate-password <username> <password> --yes|revoke-session <token-or-fingerprint> --yes|clear-bootstrap-file --yes]',
|
|
124
124
|
handler(args, ctx) {
|
|
125
125
|
handleLocalAuthCommand(args, ctx);
|
|
@@ -31,13 +31,26 @@ interface UpdateBundle {
|
|
|
31
31
|
interface AuthReviewBundle {
|
|
32
32
|
readonly version: 1;
|
|
33
33
|
readonly exportedAt: number;
|
|
34
|
-
readonly
|
|
34
|
+
readonly runtimeLoginUrl: string;
|
|
35
35
|
readonly listenerLoginUrl: string;
|
|
36
36
|
readonly secretKeys: readonly string[];
|
|
37
37
|
readonly activeSubscriptions: readonly string[];
|
|
38
38
|
readonly pendingSubscriptions: readonly string[];
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
type AuthServiceLoginTarget = 'runtime' | 'listener';
|
|
42
|
+
|
|
43
|
+
function normalizeAuthServiceLoginTarget(value: string | undefined): AuthServiceLoginTarget | null {
|
|
44
|
+
const normalized = value?.trim().toLowerCase();
|
|
45
|
+
if (normalized === 'runtime' || normalized === 'daemon') return 'runtime';
|
|
46
|
+
if (normalized === 'listener' || normalized === 'inbound-listener') return 'listener';
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function authServiceSecretPrefix(target: AuthServiceLoginTarget): string {
|
|
51
|
+
return target === 'runtime' ? 'RUNTIME' : 'LISTENER';
|
|
52
|
+
}
|
|
53
|
+
|
|
41
54
|
function buildSetupLink(surface: string, target?: string): string {
|
|
42
55
|
const params = target ? `?target=${encodeURIComponent(target)}` : '';
|
|
43
56
|
return `goodvibes://open/${surface}${params}`;
|
|
@@ -68,7 +81,7 @@ function inspectAuthBundle(bundle: AuthReviewBundle): string {
|
|
|
68
81
|
return [
|
|
69
82
|
'Auth Review Bundle',
|
|
70
83
|
` exportedAt: ${new Date(bundle.exportedAt).toISOString()}`,
|
|
71
|
-
`
|
|
84
|
+
` runtimeLoginUrl: ${bundle.runtimeLoginUrl}`,
|
|
72
85
|
` listenerLoginUrl: ${bundle.listenerLoginUrl}`,
|
|
73
86
|
` stored secrets: ${bundle.secretKeys.length}`,
|
|
74
87
|
` active subscriptions: ${bundle.activeSubscriptions.length}`,
|
|
@@ -80,7 +93,7 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
80
93
|
registry.register({
|
|
81
94
|
name: 'login',
|
|
82
95
|
description: 'Front-door login flow for provider subscriptions and local service sessions',
|
|
83
|
-
usage: '[provider <name> start|finish <code> --yes|service <
|
|
96
|
+
usage: '[provider <name> start|finish <code> --yes|service <runtime|listener> <baseUrl> <username> <password> [secretKey] --yes]',
|
|
84
97
|
async handler(args, ctx) {
|
|
85
98
|
const parsed = stripYesFlag(args);
|
|
86
99
|
const commandArgs = [...parsed.rest];
|
|
@@ -106,17 +119,17 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
106
119
|
}
|
|
107
120
|
if (target === 'service') {
|
|
108
121
|
if (!parsed.yes) {
|
|
109
|
-
requireYesFlag(ctx, 'store a local service session token', '/login service <
|
|
122
|
+
requireYesFlag(ctx, 'store a local service session token', '/login service <runtime|listener> <baseUrl> <username> <password> [secretKey] --yes');
|
|
110
123
|
return;
|
|
111
124
|
}
|
|
112
125
|
if (ctx.executeCommand) {
|
|
113
126
|
await ctx.executeCommand('auth', ['login', ...commandArgs.slice(1), '--yes']);
|
|
114
127
|
return;
|
|
115
128
|
}
|
|
116
|
-
ctx.print('Use /auth login <
|
|
129
|
+
ctx.print('Use /auth login <runtime|listener> <baseUrl> <username> <password> [secretKey] --yes');
|
|
117
130
|
return;
|
|
118
131
|
}
|
|
119
|
-
ctx.print('Usage: /login [provider <name> start|finish <code> --yes|service <
|
|
132
|
+
ctx.print('Usage: /login [provider <name> start|finish <code> --yes|service <runtime|listener> <baseUrl> <username> <password> [secretKey] --yes]');
|
|
120
133
|
},
|
|
121
134
|
});
|
|
122
135
|
|
|
@@ -293,7 +306,7 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
293
306
|
registry.register({
|
|
294
307
|
name: 'auth',
|
|
295
308
|
description: 'Review auth posture and exchange session login tokens with local services',
|
|
296
|
-
usage: '[review|show <provider>|repair <provider>|bundle export <path> --yes|bundle inspect <path>|login <
|
|
309
|
+
usage: '[review|show <provider>|repair <provider>|bundle export <path> --yes|bundle inspect <path>|login <runtime|listener> <baseUrl> <username> <password> [secretKey] --yes|local <review|panel|add-user --yes|delete-user --yes|rotate-password --yes|revoke-session --yes|clear-bootstrap-file --yes>]',
|
|
297
310
|
async handler(args, ctx) {
|
|
298
311
|
const parsed = stripYesFlag(args);
|
|
299
312
|
const commandArgs = [...parsed.rest];
|
|
@@ -315,7 +328,7 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
315
328
|
const builtinProviders = listBuiltinSubscriptionProviders().map((entry) => entry.provider);
|
|
316
329
|
ctx.print([
|
|
317
330
|
'Auth Review',
|
|
318
|
-
'
|
|
331
|
+
' runtime login route: /login',
|
|
319
332
|
' listener login route: /login',
|
|
320
333
|
` stored secrets: ${snapshot.secretKeyCount}`,
|
|
321
334
|
` built-in providers: ${builtinProviders.length}${builtinProviders.length > 0 ? ` (${builtinProviders.join(', ')})` : ''}`,
|
|
@@ -397,7 +410,7 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
397
410
|
const bundle: AuthReviewBundle = {
|
|
398
411
|
version: 1,
|
|
399
412
|
exportedAt: Date.now(),
|
|
400
|
-
|
|
413
|
+
runtimeLoginUrl: 'http://127.0.0.1:3421/login',
|
|
401
414
|
listenerLoginUrl: 'http://127.0.0.1:3422/login',
|
|
402
415
|
secretKeys,
|
|
403
416
|
activeSubscriptions: subscriptions.list().map((entry) => entry.provider),
|
|
@@ -416,17 +429,17 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
416
429
|
}
|
|
417
430
|
|
|
418
431
|
if (sub === 'login') {
|
|
419
|
-
const target = commandArgs[1];
|
|
432
|
+
const target = normalizeAuthServiceLoginTarget(commandArgs[1]);
|
|
420
433
|
const baseUrl = commandArgs[2];
|
|
421
434
|
const username = commandArgs[3];
|
|
422
435
|
const password = commandArgs[4];
|
|
423
|
-
const secretKey = commandArgs[5] ?? `${target
|
|
424
|
-
if (
|
|
425
|
-
ctx.print('Usage: /auth login <
|
|
436
|
+
const secretKey = commandArgs[5] ?? `${target ? authServiceSecretPrefix(target) : 'SERVICE'}_SESSION_TOKEN`;
|
|
437
|
+
if (!target || !baseUrl || !username || !password) {
|
|
438
|
+
ctx.print('Usage: /auth login <runtime|listener> <baseUrl> <username> <password> [secretKey] --yes');
|
|
426
439
|
return;
|
|
427
440
|
}
|
|
428
441
|
if (!parsed.yes) {
|
|
429
|
-
requireYesFlag(ctx, `store ${target} session token`, '/auth login <
|
|
442
|
+
requireYesFlag(ctx, `store ${target} session token`, '/auth login <runtime|listener> <baseUrl> <username> <password> [secretKey] --yes');
|
|
430
443
|
return;
|
|
431
444
|
}
|
|
432
445
|
const url = new URL('/login', baseUrl).toString();
|
|
@@ -450,7 +463,7 @@ export function registerPlatformAccessRuntimeCommands(registry: CommandRegistry)
|
|
|
450
463
|
return;
|
|
451
464
|
}
|
|
452
465
|
|
|
453
|
-
ctx.print('Usage: /auth [review|show <provider>|bundle export <path> --yes|bundle inspect <path>|login <
|
|
466
|
+
ctx.print('Usage: /auth [review|show <provider>|bundle export <path> --yes|bundle inspect <path>|login <runtime|listener> <baseUrl> <username> <password> [secretKey] --yes|local <review|panel|add-user --yes|delete-user --yes|rotate-password --yes|revoke-session --yes|clear-bootstrap-file --yes>]');
|
|
454
467
|
},
|
|
455
468
|
});
|
|
456
469
|
}
|
|
@@ -43,15 +43,15 @@ export async function handleRemoteSetupCommand(
|
|
|
43
43
|
const lines = [
|
|
44
44
|
'Remote Setup Review',
|
|
45
45
|
` acp agent command: ${command.join(' ')}`,
|
|
46
|
-
`
|
|
47
|
-
`
|
|
46
|
+
` runtime host enabled: ${danger.daemon ? 'yes' : 'no'}`,
|
|
47
|
+
` inbound listener enabled: ${danger.httpListener ? 'yes' : 'no'}`,
|
|
48
48
|
` remote runner contracts: ${remoteRegistry.listContracts().length}`,
|
|
49
49
|
` active acp connections: ${activeConnections.length}`,
|
|
50
50
|
'',
|
|
51
51
|
' guidance:',
|
|
52
52
|
' - set ACP_AGENT_CMD to override the spawned remote agent command',
|
|
53
53
|
' - use /remote env to export a reusable shell snippet',
|
|
54
|
-
' -
|
|
54
|
+
' - runtime-host and inbound-listener posture belongs to the runtime owner, not Agent onboarding',
|
|
55
55
|
];
|
|
56
56
|
if (commandArgs[1]?.toLowerCase() === 'export') {
|
|
57
57
|
const pathArg = commandArgs[2];
|
|
@@ -69,8 +69,8 @@ export async function handleRemoteSetupCommand(
|
|
|
69
69
|
writeFileSync(targetPath, `${JSON.stringify({
|
|
70
70
|
exportedAt: Date.now(),
|
|
71
71
|
acpAgentCommand: command,
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
runtimeHostEnabled: Boolean(danger.daemon),
|
|
73
|
+
inboundListenerEnabled: Boolean(danger.httpListener),
|
|
74
74
|
remoteRunnerContracts: remoteRegistry.listContracts().length,
|
|
75
75
|
}, null, 2)}\n`, 'utf-8');
|
|
76
76
|
ctx.print(`Exported remote setup bundle to ${targetPath}`);
|
|
@@ -111,7 +111,7 @@ export async function handleRemoteSetupCommand(
|
|
|
111
111
|
const mode = commandArgs[1]?.toLowerCase() ?? 'review';
|
|
112
112
|
const lines = [
|
|
113
113
|
'Remote Tunnel Review',
|
|
114
|
-
' transport: self-hosted ACP /
|
|
114
|
+
' transport: self-hosted ACP / runtime relay',
|
|
115
115
|
` session: ${ctx.session.runtime.sessionId}`,
|
|
116
116
|
` active remote connections: ${activeConnections.length}`,
|
|
117
117
|
' guidance: forward ACP agent traffic through your chosen self-hosted tunnel or SSH transport',
|
|
@@ -243,7 +243,7 @@ export async function runRoutinesRuntimeCommand(args: readonly string[], ctx: Co
|
|
|
243
243
|
const routine = routineRegistry.markStarted(id);
|
|
244
244
|
ctx.print([
|
|
245
245
|
`Started Agent routine ${routine.id}: ${routine.name}`,
|
|
246
|
-
' policy: same main conversation; no hidden
|
|
246
|
+
' policy: same main conversation; no hidden job, runtime mutation, or external side effect was started',
|
|
247
247
|
'',
|
|
248
248
|
routine.steps,
|
|
249
249
|
].join('\n'));
|
|
@@ -501,7 +501,7 @@ export function buildVoiceMediaStep(): OnboardingWizardStepDefinition {
|
|
|
501
501
|
kind: 'status',
|
|
502
502
|
id: 'agent-voice-media.nodes',
|
|
503
503
|
label: 'Node and device posture',
|
|
504
|
-
hint: 'Remote devices and nodes are inspected
|
|
504
|
+
hint: 'Remote devices and nodes are inspected only when useful. Agent onboarding does not launch runners or background service processes.',
|
|
505
505
|
defaultValue: 'External',
|
|
506
506
|
},
|
|
507
507
|
],
|
|
@@ -88,12 +88,12 @@ export class AutomationControlPanel extends ScrollableListPanel<AutomationRun> {
|
|
|
88
88
|
protected override getEmptyStateActions(): Array<{ command: string; summary: string }> {
|
|
89
89
|
return [
|
|
90
90
|
{ command: '/schedule list', summary: 'inspect jobs and run history without mutating schedules' },
|
|
91
|
-
{ command: '/automation jobs', summary: 'review
|
|
91
|
+
{ command: '/automation jobs', summary: 'review runtime-owned automation jobs from Agent' },
|
|
92
92
|
];
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
public render(width: number, height: number): Line[] {
|
|
96
|
-
const intro = 'Automation jobs, active runs, deliveries, and failure posture across the shared
|
|
96
|
+
const intro = 'Automation jobs, active runs, deliveries, and failure posture across the shared runtime.';
|
|
97
97
|
|
|
98
98
|
if (!this.readModel) {
|
|
99
99
|
const workspace = buildPanelWorkspace(width, height, {
|
|
@@ -97,7 +97,7 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
|
|
|
97
97
|
name: 'Schedule',
|
|
98
98
|
icon: 'Z',
|
|
99
99
|
category: 'agent',
|
|
100
|
-
description: 'Read-only schedule posture from the external
|
|
100
|
+
description: 'Read-only schedule posture from the external runtime; local Agent schedule mutation is blocked',
|
|
101
101
|
factory: () => new SchedulePanel(requireAutomationManager(deps)),
|
|
102
102
|
});
|
|
103
103
|
}
|
|
@@ -129,7 +129,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
129
129
|
name: 'Control Plane',
|
|
130
130
|
icon: 'C',
|
|
131
131
|
category: 'monitoring',
|
|
132
|
-
description: '
|
|
132
|
+
description: 'Runtime state, clients, approvals, and recent operator activity',
|
|
133
133
|
factory: () => {
|
|
134
134
|
requireControlPlanePanelDeps(deps);
|
|
135
135
|
return new ControlPlanePanel(ui.readModels.controlPlane);
|
|
@@ -150,7 +150,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
150
150
|
name: 'Local Auth',
|
|
151
151
|
icon: 'U',
|
|
152
152
|
category: 'monitoring',
|
|
153
|
-
description: 'Local
|
|
153
|
+
description: 'Local runtime auth users, bootstrap posture, and active sessions',
|
|
154
154
|
factory: () => new LocalAuthPanel(deps.localUserAuthManager),
|
|
155
155
|
});
|
|
156
156
|
|
|
@@ -251,7 +251,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
251
251
|
name: 'Remote',
|
|
252
252
|
icon: 'R',
|
|
253
253
|
category: 'monitoring',
|
|
254
|
-
description: '
|
|
254
|
+
description: 'Runtime transport state with active remote connections',
|
|
255
255
|
factory: () => new RemotePanel(ui.readModels.remote),
|
|
256
256
|
});
|
|
257
257
|
|
|
@@ -83,7 +83,7 @@ export class ControlPlanePanel extends ScrollableListPanel<ControlPlaneClient> {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
public render(width: number, height: number): Line[] {
|
|
86
|
-
const intro = 'Shared
|
|
86
|
+
const intro = 'Shared runtime state, live clients, approval pressure, and recent omnichannel session posture.';
|
|
87
87
|
|
|
88
88
|
if (!this.readModel) {
|
|
89
89
|
const workspace = buildPanelWorkspace(width, height, {
|
|
@@ -123,7 +123,7 @@ export class ControlPlanePanel extends ScrollableListPanel<ControlPlaneClient> {
|
|
|
123
123
|
{ label: 'sessions', value: String(sessions.length), valueColor: sessions.length > 0 ? C.info : C.dim },
|
|
124
124
|
{ label: 'events', value: String(recentEvents.length), valueColor: recentEvents.length > 0 ? C.info : C.dim },
|
|
125
125
|
], C),
|
|
126
|
-
buildGuidanceLine(width, '/cockpit', 'use
|
|
126
|
+
buildGuidanceLine(width, '/cockpit', 'use confirmed runtime actions for interventions while this panel tracks overall posture', C),
|
|
127
127
|
];
|
|
128
128
|
|
|
129
129
|
if (clients.length === 0 && approvals.length === 0 && sessions.length === 0) {
|
|
@@ -57,7 +57,7 @@ export class LocalAuthPanel extends ScrollableListPanel<LocalAuthUser> {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
public render(width: number, height: number): Line[] {
|
|
60
|
-
const intro = '
|
|
60
|
+
const intro = 'Review local runtime auth users, bootstrap state, and active sessions.';
|
|
61
61
|
const snapshot = this.authManager.inspect();
|
|
62
62
|
const users = this.getItems();
|
|
63
63
|
|
|
@@ -545,13 +545,13 @@ export class ProjectPlanningPanel extends BasePanel {
|
|
|
545
545
|
id: 'scope-end-to-end',
|
|
546
546
|
label: 'End-to-end required scope',
|
|
547
547
|
detail: 'Let the plan include every component needed to make this work, but avoid unrelated cleanup.',
|
|
548
|
-
answer: 'Scope is everything required to make the requested outcome work end-to-end. Include TUI,
|
|
548
|
+
answer: 'Scope is everything required to make the requested outcome work end-to-end. Include TUI, runtime composition, configuration, docs, and tests if they are required. Do not include unrelated cleanup or broad refactors unless they are necessary for this task.',
|
|
549
549
|
});
|
|
550
550
|
actions.push({
|
|
551
551
|
id: 'scope-agent-first',
|
|
552
552
|
label: 'Agent-first scope',
|
|
553
553
|
detail: 'Fix Agent behavior here; report SDK blockers instead of patching around SDK-owned bugs.',
|
|
554
|
-
answer: 'Scope is Agent-owned behavior first. If a blocker is SDK-owned, report the exact SDK contract/runtime issue instead of patching around it locally. Include
|
|
554
|
+
answer: 'Scope is Agent-owned behavior first. If a blocker is SDK-owned, report the exact SDK contract/runtime issue instead of patching around it locally. Include runtime contracts only where Agent consumes public runtime routes.',
|
|
555
555
|
});
|
|
556
556
|
}
|
|
557
557
|
actions.push({
|
|
@@ -158,7 +158,7 @@ export class RemotePanel extends BasePanel {
|
|
|
158
158
|
|
|
159
159
|
const postureLines: Line[] = [
|
|
160
160
|
buildPanelLine(width, [
|
|
161
|
-
['
|
|
161
|
+
[' runtime ', C.label],
|
|
162
162
|
[daemon.transportState.toUpperCase(), stateColor(daemon.transportState)],
|
|
163
163
|
[' running ', C.label],
|
|
164
164
|
[daemon.isRunning ? 'yes' : 'no', daemon.isRunning ? C.ok : C.dim],
|
|
@@ -199,7 +199,7 @@ export class RemotePanel extends BasePanel {
|
|
|
199
199
|
|
|
200
200
|
if (daemon.lastError) {
|
|
201
201
|
postureLines.push(buildPanelLine(width, [
|
|
202
|
-
['
|
|
202
|
+
[' runtime error ', C.label],
|
|
203
203
|
[daemon.lastError.slice(0, Math.max(0, width - 14)), C.error],
|
|
204
204
|
]));
|
|
205
205
|
}
|
|
@@ -171,7 +171,7 @@ export class SchedulePanel extends BasePanel {
|
|
|
171
171
|
}
|
|
172
172
|
case 'return':
|
|
173
173
|
case ' ': {
|
|
174
|
-
this.setError('Schedule mutation is read-only in GoodVibes Agent; use
|
|
174
|
+
this.setError('Schedule mutation is read-only in GoodVibes Agent; use explicit runtime approval routes later.');
|
|
175
175
|
return true;
|
|
176
176
|
}
|
|
177
177
|
case 'r': {
|
|
@@ -130,7 +130,7 @@ export class WatchersPanel extends ScrollableListPanel<WatcherEntry> {
|
|
|
130
130
|
{ label: 'degraded', value: String(snapshot.totalDegraded), valueColor: snapshot.totalDegraded > 0 ? C.warn : C.dim },
|
|
131
131
|
{ label: 'lagged', value: String(snapshot.totalLagged), valueColor: snapshot.totalLagged > 0 ? C.warn : C.dim },
|
|
132
132
|
], C),
|
|
133
|
-
buildGuidanceLine(width, '/schedule list', 'verify jobs consuming these sources
|
|
133
|
+
buildGuidanceLine(width, '/schedule list', 'verify jobs consuming these sources; Agent keeps watcher lifecycle read-only here', C),
|
|
134
134
|
];
|
|
135
135
|
|
|
136
136
|
if (watchers.length === 0) {
|
|
@@ -154,7 +154,7 @@ export const SETTING_LABELS: Partial<Record<string, string>> = {
|
|
|
154
154
|
'surfaces.ntfy.topic': 'ntfy Default Delivery Topic',
|
|
155
155
|
'surfaces.ntfy.chatTopic': 'ntfy Chat Topic',
|
|
156
156
|
'surfaces.ntfy.agentTopic': 'ntfy Agent Topic',
|
|
157
|
-
'surfaces.ntfy.remoteTopic': 'ntfy
|
|
157
|
+
'surfaces.ntfy.remoteTopic': 'ntfy Runtime-Only Remote Topic',
|
|
158
158
|
'surfaces.ntfy.token': 'ntfy Token',
|
|
159
159
|
'surfaces.ntfy.defaultPriority': 'ntfy Default Priority',
|
|
160
160
|
};
|
|
@@ -75,9 +75,9 @@ const ENUM_VALUE_DESCRIPTIONS: Record<string, Record<string, string>> = {
|
|
|
75
75
|
plaintext_allowed: 'Allow plaintext fallback when secure storage is unavailable.',
|
|
76
76
|
},
|
|
77
77
|
'batch.mode': {
|
|
78
|
-
off: 'Keep
|
|
78
|
+
off: 'Keep runtime work on the immediate local path.',
|
|
79
79
|
explicit: 'Use batch only when callers explicitly request batch execution.',
|
|
80
|
-
'eligible-by-default': 'Allow eligible
|
|
80
|
+
'eligible-by-default': 'Allow eligible runtime work to use the batch path unless callers opt out.',
|
|
81
81
|
},
|
|
82
82
|
'controlPlane.hostMode': {
|
|
83
83
|
localhost: 'Bind only to this computer.',
|
package/src/runtime/bootstrap.ts
CHANGED
|
@@ -46,8 +46,8 @@ import { buildEnabledRoutinesPrompt } from '../agent/routine-registry.ts';
|
|
|
46
46
|
|
|
47
47
|
const GOODVIBES_AGENT_OPERATOR_POLICY = [
|
|
48
48
|
'## GoodVibes Agent Operator Policy',
|
|
49
|
-
'- Default to serial, proactive assistant work in the main conversation. Answer, inspect, summarize, remember useful non-secret facts, configure local Agent state, use read-only
|
|
50
|
-
'- GoodVibes Agent connects to an externally managed GoodVibes
|
|
49
|
+
'- Default to serial, proactive assistant work in the main conversation. Answer, inspect, summarize, remember useful non-secret facts, configure local Agent state, use read-only runtime/operator routes, and take safe non-destructive actions without spawning local agents or WRFC.',
|
|
50
|
+
'- GoodVibes Agent connects to an externally managed GoodVibes runtime host. Do not start, stop, restart, install, expose, or mutate runtime-host network/listener posture from Agent runtime.',
|
|
51
51
|
'- Use the `agent_local_registry` tool when a reusable persona, skill, or routine would improve future work. Keep those records local, non-secret, source/provenance tagged, and reviewable. Starting a routine means applying its steps in this same serial conversation, not creating a background job.',
|
|
52
52
|
'- WRFC is never the default Agent reasoning path. Do not create local WRFC chains for planning, research, operations, knowledge, memory, configuration, approvals, automation observability, or ordinary assistant work.',
|
|
53
53
|
'- GoodVibes Agent is not the coding TUI. Do not use the `agent` tool to spawn local Engineer, Reviewer, Tester, Verifier, or batch-spawn roots from Agent.',
|
|
@@ -332,8 +332,8 @@ export async function bootstrapRuntime(
|
|
|
332
332
|
port,
|
|
333
333
|
baseUrl: formatHostServiceBaseUrl(host, port),
|
|
334
334
|
reason: service === 'daemon'
|
|
335
|
-
? 'GoodVibes Agent connects to an externally managed GoodVibes
|
|
336
|
-
: 'GoodVibes Agent does not own
|
|
335
|
+
? 'GoodVibes Agent connects to an externally managed GoodVibes runtime host and does not start or restart it.'
|
|
336
|
+
: 'GoodVibes Agent does not own external listener lifecycle.',
|
|
337
337
|
};
|
|
338
338
|
};
|
|
339
339
|
|
|
@@ -373,7 +373,7 @@ export async function bootstrapRuntime(
|
|
|
373
373
|
daemonStatus: createExternalAgentServiceStatus('daemon'),
|
|
374
374
|
httpListenerStatus: createExternalAgentServiceStatus('httpListener'),
|
|
375
375
|
};
|
|
376
|
-
systemMessageRouter.high('[Startup] GoodVibes Agent does not start or restart
|
|
376
|
+
systemMessageRouter.high('[Startup] GoodVibes Agent does not start or restart runtime-host services. Start the GoodVibes runtime from its owner, then refresh status.');
|
|
377
377
|
requestRender();
|
|
378
378
|
return inspectExternalServices();
|
|
379
379
|
},
|
|
@@ -450,8 +450,8 @@ export async function bootstrapRuntime(
|
|
|
450
450
|
});
|
|
451
451
|
bootstrapUnsubs.push(() => mcpAutoReload.stop());
|
|
452
452
|
if (configManager.get('automation.enabled')) {
|
|
453
|
-
logger.warn('Local automation startup is disabled in GoodVibes Agent; use external
|
|
454
|
-
systemMessageRouter.low('[Startup] Local automation runners are disabled in GoodVibes Agent; use read-only automation observability or explicit external-
|
|
453
|
+
logger.warn('Local automation startup is disabled in GoodVibes Agent; use external runtime observability instead.');
|
|
454
|
+
systemMessageRouter.low('[Startup] Local automation runners are disabled in GoodVibes Agent; use read-only automation observability or explicit external-runtime actions.');
|
|
455
455
|
}
|
|
456
456
|
|
|
457
457
|
// ── Phase 12: Session:start lifecycle hook ─────────────────────────────
|
package/src/runtime/index.ts
CHANGED
|
@@ -113,8 +113,8 @@ function agentExternalHostStatus(
|
|
|
113
113
|
port,
|
|
114
114
|
baseUrl: `http://${host}:${port}`,
|
|
115
115
|
reason: service === 'daemon'
|
|
116
|
-
? 'GoodVibes Agent connects to an externally managed GoodVibes
|
|
117
|
-
: 'GoodVibes Agent does not own
|
|
116
|
+
? 'GoodVibes Agent connects to an externally managed GoodVibes runtime host and does not start or restart it.'
|
|
117
|
+
: 'GoodVibes Agent does not own external listener lifecycle.',
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
|
|
@@ -253,28 +253,28 @@ function hasExternalIntegrations(snapshot: OnboardingSnapshotState): boolean {
|
|
|
253
253
|
|
|
254
254
|
function describeLocalTuiOnly(snapshot: OnboardingSnapshotState): string {
|
|
255
255
|
if (!hasAnyServerEnabled(snapshot)) {
|
|
256
|
-
return 'Use GoodVibes Agent in this terminal while connecting
|
|
256
|
+
return 'Use GoodVibes Agent in this terminal while connecting to the existing GoodVibes runtime. Agent setup does not enable network services or extra entrypoints.';
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
return 'Keep Agent local-
|
|
259
|
+
return 'Keep Agent local-first by reviewing runtime connectivity separately from Agent-owned assistant setup.';
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
function describeBrowserAccess(snapshot: OnboardingSnapshotState): string {
|
|
263
263
|
return snapshot.bindSettings.web.enabled
|
|
264
|
-
? 'Review
|
|
265
|
-
: '
|
|
264
|
+
? 'Review browser access already exposed by the runtime owner. Agent records visibility but does not change network posture.'
|
|
265
|
+
: 'Browser access is optional. Agent can stay terminal-first while the runtime owner controls any browser entrypoint.';
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
function describeRemoteDeviceAccess(snapshot: OnboardingSnapshotState): string {
|
|
269
269
|
return hasRemoteDeviceAccess(snapshot)
|
|
270
|
-
? 'Review
|
|
271
|
-
: '
|
|
270
|
+
? 'Review runtime access reachable from other devices on your LAN. Local authentication is required.'
|
|
271
|
+
: 'Other-device access is optional and remains controlled by the runtime owner.';
|
|
272
272
|
}
|
|
273
273
|
|
|
274
274
|
function describeWebhookIngress(snapshot: OnboardingSnapshotState): string {
|
|
275
275
|
return hasWebhookOrEventIngress(snapshot)
|
|
276
|
-
? 'Review
|
|
277
|
-
: '
|
|
276
|
+
? 'Review incoming webhook, callback, and automation-event routes exposed by the runtime owner.'
|
|
277
|
+
: 'Incoming webhook and callback routes are optional; Agent onboarding does not create them.';
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
function describeExternalIntegrations(snapshot: OnboardingSnapshotState): string {
|
|
@@ -284,10 +284,10 @@ function describeExternalIntegrations(snapshot: OnboardingSnapshotState): string
|
|
|
284
284
|
]).size;
|
|
285
285
|
|
|
286
286
|
if (integrationCount === 0) {
|
|
287
|
-
return '
|
|
287
|
+
return 'Connect only the channels you want the assistant to use, then review delivery safety before sending externally.';
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
return `Review
|
|
290
|
+
return `Review ${integrationCount} detected channel or integration signal(s) before allowing external delivery.`;
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
function getAcknowledgementAccepted(
|
|
@@ -330,31 +330,31 @@ export function deriveStep1Capabilities(
|
|
|
330
330
|
return [
|
|
331
331
|
{
|
|
332
332
|
id: 'local-tui-only',
|
|
333
|
-
label: 'Agent
|
|
333
|
+
label: 'Agent Terminal First',
|
|
334
334
|
selected: !hasAnyServerEnabled(snapshot),
|
|
335
335
|
detail: describeLocalTuiOnly(snapshot),
|
|
336
336
|
},
|
|
337
337
|
{
|
|
338
338
|
id: 'browser-access',
|
|
339
|
-
label: '
|
|
339
|
+
label: 'Optional Browser Access',
|
|
340
340
|
selected: hasBrowserAccess(snapshot),
|
|
341
341
|
detail: describeBrowserAccess(snapshot),
|
|
342
342
|
},
|
|
343
343
|
{
|
|
344
344
|
id: 'network-access',
|
|
345
|
-
label: '
|
|
345
|
+
label: 'Optional Other-Device Access',
|
|
346
346
|
selected: hasRemoteDeviceAccess(snapshot),
|
|
347
347
|
detail: describeRemoteDeviceAccess(snapshot),
|
|
348
348
|
},
|
|
349
349
|
{
|
|
350
350
|
id: 'webhook-events',
|
|
351
|
-
label: '
|
|
351
|
+
label: 'Optional Incoming Events',
|
|
352
352
|
selected: hasWebhookOrEventIngress(snapshot),
|
|
353
353
|
detail: describeWebhookIngress(snapshot),
|
|
354
354
|
},
|
|
355
355
|
{
|
|
356
356
|
id: 'external-integrations',
|
|
357
|
-
label: '
|
|
357
|
+
label: 'Channels and Integrations',
|
|
358
358
|
selected: hasExternalIntegrations(snapshot),
|
|
359
359
|
detail: describeExternalIntegrations(snapshot),
|
|
360
360
|
},
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '0.1.
|
|
9
|
+
let _version = '0.1.64';
|
|
10
10
|
let _sdkVersion = '0.33.35';
|
|
11
11
|
try {
|
|
12
12
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|