@pellux/goodvibes-agent 0.1.92 → 0.1.94

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 CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to GoodVibes Agent will be recorded here.
4
4
 
5
+ ## 0.1.94 - 2026-06-01
6
+
7
+ - ae6fa3e Polish Agent runtime status labels
8
+
9
+ ## 0.1.93 - 2026-06-01
10
+
11
+ - 7f802e5 Add external runtime URL override
12
+
5
13
  ## 0.1.92 - 2026-06-01
6
14
 
7
15
  - f52b62e Fix copied CLI executable guidance
package/README.md CHANGED
@@ -89,6 +89,8 @@ Starting a routine records local usage and prints its steps; it does not spawn b
89
89
 
90
90
  Start or restart the GoodVibes runtime from GoodVibes TUI or the owning host before launching Agent. Agent status and companion/knowledge routes connect to that external runtime, normally on `http://127.0.0.1:3421`.
91
91
 
92
+ Use `--runtime-url http://host:port` for a one-off launch, or set `GOODVIBES_AGENT_RUNTIME_URL=http://host:port` when the runtime API is not on the default local port. The legacy `GOODVIBES_AGENT_BASE_URL` env var is also accepted as an alias. These only change the external runtime connection target; Agent still does not host or start the runtime.
93
+
92
94
  Agent reports unavailable, unauthenticated, or incompatible runtime state through `goodvibes-agent status`, `goodvibes-agent doctor`, and the TUI status views. It does not provide runtime hosting commands.
93
95
 
94
96
  ## Product Boundary
package/docs/README.md CHANGED
@@ -17,6 +17,7 @@ Important baseline constraints:
17
17
  - Agent does not start, stop, restart, install, uninstall, or own runtime hosting.
18
18
  - Agent Knowledge/Wiki uses only `/api/goodvibes-agent/knowledge/*`; there is no default Knowledge/Wiki or non-Agent product fallback.
19
19
  - Agent supports isolated runtime homes with `GOODVIBES_AGENT_HOME=<path>` and named profile homes with `goodvibes-agent profiles create <name> --template <starter> --yes` plus `--agent-profile <name>`.
20
+ - Agent supports external runtime URL overrides with `--runtime-url http://host:port` or `GOODVIBES_AGENT_RUNTIME_URL=http://host:port`; these do not make Agent own runtime hosting.
20
21
  - Agent ships starter profile templates for household, research, travel, operations, and personal productivity local state; `profiles templates export/import` and `/agent-profile guide` support local custom starters.
21
22
  - Local personas, routines, and Agent skills are stored under the Agent home and are injected only into the serial Agent conversation.
22
23
  - Normal assistant chat is not coding-session delegation.
@@ -97,6 +97,8 @@ Start the runtime from GoodVibes TUI or the owning host before using runtime-bac
97
97
  - `/api/goodvibes-agent/knowledge/search`
98
98
  - `/api/goodvibes-agent/knowledge/ingest/url`
99
99
 
100
+ If the runtime API is not on `http://127.0.0.1:3421`, use `goodvibes-agent --runtime-url http://host:port status` for a one-off check or set `GOODVIBES_AGENT_RUNTIME_URL=http://host:port` before launching the TUI.
101
+
100
102
  Agent Knowledge/Wiki is an Agent-owned product segment. Agent commands must not fall back to default Knowledge/Wiki or other product-specific knowledge spaces.
101
103
 
102
104
  Runtime-hosting commands are not part of GoodVibes Agent. Use `goodvibes-agent status`, `goodvibes-agent doctor`, and the Agent TUI status views for diagnostics.
@@ -24,6 +24,20 @@ http://127.0.0.1:3421
24
24
  /api/goodvibes-agent/knowledge/search
25
25
  ```
26
26
 
27
+ If the runtime API is on a different host or port, use a one-off override:
28
+
29
+ ```sh
30
+ goodvibes-agent --runtime-url http://127.0.0.1:3421 status
31
+ ```
32
+
33
+ For a persistent shell/session override, set:
34
+
35
+ ```sh
36
+ export GOODVIBES_AGENT_RUNTIME_URL=http://127.0.0.1:3421
37
+ ```
38
+
39
+ `GOODVIBES_AGENT_BASE_URL` is accepted as a legacy alias. These values only select the external runtime API root; they do not enable runtime hosting inside Agent.
40
+
27
41
  If the runtime is unavailable, unauthenticated, or on an incompatible SDK version, Agent commands report actionable diagnostics without printing token values.
28
42
 
29
43
  ## Product Boundary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "0.1.92",
3
+ "version": "0.1.94",
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",
@@ -19,12 +19,9 @@ const COMMANDS = [
19
19
  'subscription',
20
20
  'secrets',
21
21
  'sessions',
22
- 'tasks',
23
22
  'pair',
24
23
  'qrcode',
25
24
  'bundle',
26
- 'remote',
27
- 'bridge',
28
25
  'completion',
29
26
  'version',
30
27
  'help',
@@ -36,6 +33,7 @@ const OPTIONS = [
36
33
  '--model',
37
34
  '--provider',
38
35
  '--agent-profile',
36
+ '--runtime-url',
39
37
  '--cd',
40
38
  '--working-dir',
41
39
  '--config',
@@ -21,6 +21,38 @@ function parseConfigOverrideValue(value: string): unknown {
21
21
  }
22
22
  }
23
23
 
24
+ function parseRuntimeUrl(rawValue: string, source: string): { readonly host: string; readonly port: number } {
25
+ const trimmed = rawValue.trim();
26
+ if (trimmed.length === 0) {
27
+ throw new ConfigError(`${source} requires a non-empty http://host:port value.`);
28
+ }
29
+
30
+ const value = /^[a-z][a-z\d+.-]*:\/\//i.test(trimmed) ? trimmed : `http://${trimmed}`;
31
+ let url: URL;
32
+ try {
33
+ url = new URL(value);
34
+ } catch {
35
+ throw new ConfigError(`${source} must be a valid http://host:port URL.`);
36
+ }
37
+
38
+ if (url.protocol !== 'http:') {
39
+ throw new ConfigError(`${source} must use http:// because Agent connects to the local GoodVibes runtime API.`);
40
+ }
41
+ if (!url.hostname) {
42
+ throw new ConfigError(`${source} must include a hostname.`);
43
+ }
44
+ if ((url.pathname && url.pathname !== '/') || url.search || url.hash) {
45
+ throw new ConfigError(`${source} must point at the runtime root, not a path, query, or hash.`);
46
+ }
47
+
48
+ const port = url.port ? Number.parseInt(url.port, 10) : 3421;
49
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
50
+ throw new ConfigError(`${source} port must be from 1 to 65535.`);
51
+ }
52
+
53
+ return { host: url.hostname, port };
54
+ }
55
+
24
56
  function getRuntimeConfig(configManager: ConfigManager): GoodVibesConfig {
25
57
  const mutable = configManager as unknown as { config?: GoodVibesConfig };
26
58
  if (!mutable.config || typeof mutable.config !== 'object') {
@@ -93,6 +125,22 @@ export function applyRuntimeConfigOverrides(
93
125
  return errors;
94
126
  }
95
127
 
128
+ export function applyRuntimeUrlOverride(
129
+ configManager: ConfigManager,
130
+ rawValue: string,
131
+ source = '--runtime-url',
132
+ ): readonly string[] {
133
+ try {
134
+ const parsed = parseRuntimeUrl(rawValue, source);
135
+ applyRuntimeConfigValue(configManager, 'controlPlane.hostMode', hostModeForHostname(parsed.host));
136
+ applyRuntimeConfigValue(configManager, 'controlPlane.host', parsed.host);
137
+ applyRuntimeConfigValue(configManager, 'controlPlane.port', parsed.port);
138
+ return [];
139
+ } catch (error) {
140
+ return [error instanceof Error ? error.message : `Invalid ${source}`];
141
+ }
142
+ }
143
+
96
144
  export function applyRuntimeFeatureFlagOverrides(
97
145
  configManager: ConfigManager,
98
146
  options: {
@@ -11,6 +11,7 @@ import {
11
11
  applyRuntimeConfigOverrides,
12
12
  applyRuntimeConfigValue,
13
13
  applyRuntimeFeatureFlagOverrides,
14
+ applyRuntimeUrlOverride,
14
15
  buildCliStatusSnapshot,
15
16
  handleGoodVibesCliCommand,
16
17
  parseGoodVibesCli,
@@ -31,6 +32,14 @@ type ShellEntrypointOwnership = {
31
32
  readonly homeDirectory: string;
32
33
  };
33
34
 
35
+ function readEnvRuntimeUrl(): { readonly source: string; readonly value: string } | null {
36
+ const runtimeUrl = process.env['GOODVIBES_AGENT_RUNTIME_URL'];
37
+ if (runtimeUrl !== undefined) return { source: 'GOODVIBES_AGENT_RUNTIME_URL', value: runtimeUrl };
38
+ const legacyBaseUrl = process.env['GOODVIBES_AGENT_BASE_URL'];
39
+ if (legacyBaseUrl !== undefined) return { source: 'GOODVIBES_AGENT_BASE_URL', value: legacyBaseUrl };
40
+ return null;
41
+ }
42
+
34
43
  export type ShellEntrypointRoots = {
35
44
  readonly defaultWorkingDirectory: string;
36
45
  readonly homeDirectory: string;
@@ -112,6 +121,15 @@ export async function prepareShellCliRuntime(
112
121
  });
113
122
  new GlobalNetworkTransportInstaller().install(configManager);
114
123
 
124
+ const envRuntimeUrl = readEnvRuntimeUrl();
125
+ const envRuntimeUrlErrors = envRuntimeUrl
126
+ ? applyRuntimeUrlOverride(configManager, envRuntimeUrl.value, envRuntimeUrl.source)
127
+ : [];
128
+ if (envRuntimeUrlErrors.length > 0) {
129
+ console.error(envRuntimeUrlErrors.join('\n'));
130
+ process.exit(2);
131
+ }
132
+
115
133
  const overrideErrors = applyRuntimeConfigOverrides(configManager, cli.flags.configOverrides);
116
134
  if (overrideErrors.length > 0) {
117
135
  console.error(overrideErrors.join('\n'));
@@ -128,6 +146,13 @@ export async function prepareShellCliRuntime(
128
146
  const model = cli.flags.model ?? getModelIdFromProviderModel(currentModel);
129
147
  applyRuntimeConfigValue(configManager, 'provider.model', formatProviderModel(provider, model));
130
148
  }
149
+ if (cli.flags.runtimeUrl !== undefined) {
150
+ const runtimeUrlErrors = applyRuntimeUrlOverride(configManager, cli.flags.runtimeUrl);
151
+ if (runtimeUrlErrors.length > 0) {
152
+ console.error(runtimeUrlErrors.join('\n'));
153
+ process.exit(2);
154
+ }
155
+ }
131
156
  const endpointOverrideErrors = applyRuntimeCommandEndpointFlagOverrides(configManager, cli.command, cli.flags);
132
157
  if (endpointOverrideErrors.length > 0) {
133
158
  console.error(endpointOverrideErrors.join('\n'));
package/src/cli/help.ts CHANGED
@@ -57,6 +57,7 @@ export function renderGoodVibesHelp(binary = 'goodvibes-agent'): string {
57
57
  ' -m, --model <registryKey> Override model. provider:model infers --provider',
58
58
  ' --provider <id> Override provider',
59
59
  ' --agent-profile <name> Use an isolated Agent profile home',
60
+ ' --runtime-url <url> External GoodVibes runtime API root',
60
61
  ' -C, --cd <dir> Set working directory for this launch',
61
62
  ' --working-dir <dir> Alias for --cd',
62
63
  ' -c, --config <key=value> Override a config value for this launch',
@@ -82,6 +83,7 @@ export function renderGoodVibesHelp(binary = 'goodvibes-agent'): string {
82
83
  ` ${binary} onboarding`,
83
84
  ` ${binary} onboarding status`,
84
85
  ` ${binary} status`,
86
+ ` ${binary} --runtime-url http://127.0.0.1:3421 status`,
85
87
  ` ${binary} models current`,
86
88
  ` ${binary} models use openai:gpt-5.2`,
87
89
  ` ${binary} providers inspect openai`,
@@ -125,14 +127,14 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
125
127
  examples: ['onboarding', 'onboarding status'],
126
128
  },
127
129
  status: {
128
- usage: ['status', 'status --json'],
130
+ usage: ['status', 'status --json', '--runtime-url http://127.0.0.1:3421 status'],
129
131
  summary: 'Print Agent config, provider, auth, runtime connection, and onboarding posture.',
130
- examples: ['status', 'status --json'],
132
+ examples: ['status', 'status --json', '--runtime-url http://127.0.0.1:3421 status'],
131
133
  },
132
134
  doctor: {
133
- usage: ['doctor', 'doctor --json'],
135
+ usage: ['doctor', 'doctor --json', '--runtime-url http://127.0.0.1:3421 doctor'],
134
136
  summary: 'Print status plus actionable setup warnings with cause, impact, and next action.',
135
- examples: ['doctor', 'doctor --json'],
137
+ examples: ['doctor', 'doctor --json', '--runtime-url http://127.0.0.1:3421 doctor'],
136
138
  },
137
139
  providers: {
138
140
  usage: ['providers [list]', 'providers current', 'providers inspect <provider>', 'providers use <provider> [modelRegistryKey]'],
package/src/cli/parser.ts CHANGED
@@ -59,6 +59,7 @@ function createDefaultFlags(): GoodVibesCliFlags {
59
59
  model: undefined,
60
60
  agentProfile: undefined,
61
61
  daemonHome: undefined,
62
+ runtimeUrl: undefined,
62
63
  workingDir: undefined,
63
64
  help: false,
64
65
  version: false,
@@ -276,6 +277,12 @@ export function parseGoodVibesCli(
276
277
  if (consumed.value !== undefined) flags = withFlag(flags, 'daemonHome', consumed.value);
277
278
  continue;
278
279
  }
280
+ if (name === '--runtime-url' || name === '--runtime') {
281
+ const consumed = getValue(argv, index, inlineValue, name, errors);
282
+ index = consumed.nextIndex;
283
+ if (consumed.value !== undefined) flags = withFlag(flags, 'runtimeUrl', consumed.value);
284
+ continue;
285
+ }
279
286
  if (name === '--working-dir' || name === '--cd' || name === '-C') {
280
287
  const consumed = getValue(argv, index, inlineValue, name, errors);
281
288
  index = consumed.nextIndex;
package/src/cli/status.ts CHANGED
@@ -392,11 +392,12 @@ export function renderCliStatus(options: CliStatusOptions): string {
392
392
  ' live check: unavailable',
393
393
  ]),
394
394
  '',
395
- 'External Runtime Ownership:',
396
- ` owner: external GoodVibes runtime host`,
397
- ` hostConfigEnabled: ${yesNo(serviceEnabled)}`,
398
- ` hostAutostart: ${yesNo(serviceAutostart)}`,
399
- ` hostRestartOnFailure: ${yesNo(restartOnFailure)}`,
395
+ 'Runtime Ownership:',
396
+ ' Agent hosting: external only',
397
+ ` Agent starts runtime: no`,
398
+ ` legacy host config present: ${yesNo(serviceEnabled)}`,
399
+ ` legacy host autostart: ${yesNo(serviceAutostart)}`,
400
+ ` legacy host restart policy: ${yesNo(restartOnFailure)}`,
400
401
  ...(options.service ? [
401
402
  ` platform: ${options.service.managed.platform}`,
402
403
  ` installed: ${yesNo(options.service.managed.installed)}`,
@@ -405,7 +406,7 @@ export function renderCliStatus(options: CliStatusOptions): string {
405
406
  ` log: ${options.service.log.path ?? 'n/a'} (${options.service.log.exists ? 'present' : 'missing'})`,
406
407
  ] : []),
407
408
  '',
408
- 'Runtime Endpoints:',
409
+ 'Runtime Endpoint Diagnostics:',
409
410
  bindLine('runtimeApi', controlPlaneEnabled, controlPlaneBinding),
410
411
  bindLine('incomingWebhook', listenerEnabled, httpListenerBinding),
411
412
  bindLine('browserCompanion', webEnabled, webBinding),
@@ -438,7 +439,7 @@ export function renderCliStatus(options: CliStatusOptions): string {
438
439
  export function renderOnboardingCliStatus(options: CliStatusOptions): string {
439
440
  const marker = options.onboardingMarkers?.effective;
440
441
  return [
441
- 'GoodVibes onboarding status',
442
+ 'GoodVibes Agent onboarding status',
442
443
  ` checked: ${marker?.exists ? 'yes' : 'no'}`,
443
444
  ` scope: ${marker?.scope ?? 'none'}`,
444
445
  ` source: ${marker?.payload?.source ?? 'n/a'}`,
package/src/cli/types.ts CHANGED
@@ -37,6 +37,7 @@ export interface GoodVibesCliFlags {
37
37
  readonly model: string | undefined;
38
38
  readonly agentProfile: string | undefined;
39
39
  readonly daemonHome: string | undefined;
40
+ readonly runtimeUrl: string | undefined;
40
41
  readonly workingDir: string | undefined;
41
42
  readonly help: boolean;
42
43
  readonly version: boolean;
package/src/cli-flags.ts CHANGED
@@ -6,6 +6,7 @@ export {
6
6
  applyRuntimeCommandEndpointFlagOverrides,
7
7
  applyRuntimeEndpointFlagOverrides,
8
8
  applyRuntimeFeatureFlagOverrides,
9
+ applyRuntimeUrlOverride,
9
10
  handleGoodVibesCliCommand,
10
11
  parseGoodVibesCli,
11
12
  renderGoodVibesCommandHelp,
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.92';
9
+ let _version = '0.1.94';
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 {