@pellux/goodvibes-agent 0.1.73 → 0.1.75

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,18 @@
2
2
 
3
3
  All notable changes to GoodVibes Agent will be recorded here.
4
4
 
5
+ ## 0.1.75 - 2026-05-31
6
+
7
+ - Reworded Agent status, doctor, and external runtime diagnostics away from copied service/surface ownership language.
8
+ - Added `--delivery-channel` as the documented schedule promotion delivery flag while keeping prior delivery aliases as compatibility-only parser inputs.
9
+ - Cleaned Agent TUI help, workspace, and panel guidance so visible copy describes Agent workflows, channels, runtime endpoints, and external runtime connection boundaries.
10
+
11
+ ## 0.1.74 - 2026-05-31
12
+
13
+ - Filtered checked-in foundation operator artifacts to Agent-relevant routes so host-specific knowledge segments are not documented in Agent artifacts.
14
+ - Added a release regression that rejects excluded host-specific route IDs, paths, descriptions, and enum values from Agent operator artifacts.
15
+ - Updated foundation artifact wording to describe the Agent-filtered contract instead of a full host contract dump.
16
+
5
17
  ## 0.1.73 - 2026-05-31
6
18
 
7
19
  - Replaced copied first-run capability language with Agent-specific setup: operator TUI, provider access, isolated Agent Knowledge, local memory/skills, channels, automation review, and explicit TUI delegation.
package/README.md CHANGED
@@ -74,14 +74,14 @@ Local Agent behavior is editable from the TUI:
74
74
  /personas use research
75
75
  /routines create --name "Evening Review" --description "Review open work before shutdown" --steps "Check work plan, approvals, and Agent Knowledge status before summarizing." --enabled true
76
76
  /routines start evening-review
77
- /schedule promote-routine evening-review --cron "0 17 * * 1-5" --timezone America/Chicago --delivery-surface slack --yes
77
+ /schedule promote-routine evening-review --cron "0 17 * * 1-5" --timezone America/Chicago --delivery-channel slack --yes
78
78
  /schedule receipts
79
79
  /schedule reconcile
80
80
  /agent-skills create --name "Morning Brief" --description "Daily briefing flow" --procedure "Check tasks, approvals, calendar, and unread state before summarizing." --enabled true
81
81
  /skills local list
82
82
  ```
83
83
 
84
- Starting a routine records local usage and prints its steps; it does not spawn background agents or automation jobs. Promotion to an external schedule is separate and explicit: it calls the public `schedules.create` route only after `--yes`, can include explicit delivery targets such as `--delivery-surface slack`, records a redacted local receipt, and the generated scheduled prompt keeps Agent Knowledge isolated from default Knowledge/Wiki and non-Agent knowledge segments. Use `/schedule reconcile` to compare those local receipts against live external schedules through public `schedules.list`.
84
+ Starting a routine records local usage and prints its steps; it does not spawn background agents or automation jobs. Promotion to an external schedule is separate and explicit: it calls the public `schedules.create` route only after `--yes`, can include explicit delivery targets such as `--delivery-channel slack`, records a redacted local receipt, and the generated scheduled prompt keeps Agent Knowledge isolated from default Knowledge/Wiki and non-Agent knowledge segments. Use `/schedule reconcile` to compare those local receipts against live external schedules through public `schedules.list`.
85
85
 
86
86
  ## Runtime Prerequisite
87
87
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "0.1.73",
3
+ "version": "0.1.75",
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",
@@ -37,10 +37,10 @@ export function isRoutineScheduleDeliverySurfaceKind(value: string): value is Ro
37
37
  return DELIVERY_SURFACE_KINDS.includes(value as RoutineScheduleDeliverySurfaceKind);
38
38
  }
39
39
 
40
- function parseSurfaceDeliveryTarget(raw: string): RoutineScheduleDeliveryTargetSpec | string {
40
+ function parseChannelDeliveryTarget(raw: string): RoutineScheduleDeliveryTargetSpec | string {
41
41
  const [surfaceKind = '', routeId, label] = raw.split(':');
42
42
  if (!isRoutineScheduleDeliverySurfaceKind(surfaceKind)) {
43
- return `Unsupported delivery surface "${surfaceKind}".`;
43
+ return `Unsupported delivery channel "${surfaceKind}".`;
44
44
  }
45
45
  return {
46
46
  kind: 'surface',
@@ -148,7 +148,10 @@ export function parseRoutineSchedulePromotionArgs(args: readonly string[]): Pars
148
148
  };
149
149
  continue;
150
150
  }
151
- if (optionName === '--delivery-surface' || optionName === '--deliver-surface') {
151
+ if (
152
+ optionName === '--delivery-channel'
153
+ || optionName === '--deliver-channel'
154
+ ) {
152
155
  const consumed = optionValue(args, index, inlineValue);
153
156
  index = consumed.nextIndex;
154
157
  const value = consumed.value?.trim();
@@ -156,7 +159,7 @@ export function parseRoutineSchedulePromotionArgs(args: readonly string[]): Pars
156
159
  errors.push(`${optionName} requires a value.`);
157
160
  continue;
158
161
  }
159
- const target = parseSurfaceDeliveryTarget(value);
162
+ const target = parseChannelDeliveryTarget(value);
160
163
  if (typeof target === 'string') errors.push(target);
161
164
  else deliveryTargets.push(target);
162
165
  continue;
@@ -18,6 +18,11 @@ function readString(record: Record<string, unknown>, key: string): string | null
18
18
  return typeof value === 'string' ? value : null;
19
19
  }
20
20
 
21
+ function formatDeliveryTargetKind(target: { readonly kind?: string; readonly surfaceKind?: string }): string {
22
+ if (target.kind === 'surface') return `channel${target.surfaceKind ? `/${target.surfaceKind}` : ''}`;
23
+ return `${target.kind ?? 'unknown'}${target.surfaceKind ? `/${target.surfaceKind}` : ''}`;
24
+ }
25
+
21
26
  export function formatRoutineSchedulePreview(preview: RoutineSchedulePromotionPreview): string {
22
27
  const schedule = preview.payload.kind === 'cron'
23
28
  ? `${preview.payload.cron}${preview.payload.timezone ? ` [${preview.payload.timezone}]` : ''}`
@@ -90,9 +95,9 @@ export function formatRoutineScheduleReceipt(receipt: RoutineScheduleReceipt): s
90
95
  ` enabled: ${receipt.enabled ? 'yes' : 'no'}`,
91
96
  receipt.provider ? ` provider: ${receipt.provider}` : '',
92
97
  receipt.model ? ` model: ${receipt.model}` : '',
93
- ` target: ${receipt.target.kind ?? 'unknown'}${receipt.target.surfaceKind ? `/${receipt.target.surfaceKind}` : ''}`,
98
+ ` target: ${formatDeliveryTargetKind(receipt.target)}`,
94
99
  receipt.deliveryMode ? ` delivery: ${receipt.deliveryMode}` : '',
95
- ...(receipt.deliveryTargets ?? []).map((target) => ` delivery target: ${target.kind}${target.surfaceKind ? `/${target.surfaceKind}` : ''}${target.routeId ? ` route=${target.routeId}` : ''}${target.address ? ` address=${target.address}` : ''}${target.label ? ` label=${target.label}` : ''}`),
100
+ ...(receipt.deliveryTargets ?? []).map((target) => ` delivery target: ${formatDeliveryTargetKind(target)}${target.routeId ? ` route=${target.routeId}` : ''}${target.address ? ` address=${target.address}` : ''}${target.label ? ` label=${target.label}` : ''}`),
96
101
  receipt.failureKind ? ` failure: ${receipt.failureKind}` : '',
97
102
  receipt.failureError ? ` error: ${receipt.failureError}` : '',
98
103
  ].filter((line): line is string => Boolean(line)).join('\n');
package/src/cli/help.ts CHANGED
@@ -152,7 +152,7 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
152
152
  'routines receipts',
153
153
  'routines reconcile',
154
154
  'routines receipt <receipt-id>',
155
- 'routines promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--timezone <tz>] [--name <schedule-name>] [--provider <id>] [--model <model>] [--delivery-surface <surface[:route[:label]]>|--delivery-route <route[:label]>|--delivery-webhook <url>|--delivery-link <url>] [--disabled] --yes',
155
+ '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',
156
156
  ],
157
157
  summary: 'Inspect Agent-local routines, review local promotion receipts, reconcile receipts against live external schedules, and explicitly promote a reviewed routine into a GoodVibes schedule. Without --yes, promote only prints the schedules.create preview.',
158
158
  examples: [
@@ -160,7 +160,7 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
160
160
  'routines show daily-operations-sweep',
161
161
  'routines receipts',
162
162
  'routines reconcile',
163
- 'routines promote daily-operations-sweep --cron "0 9 * * *" --timezone America/Chicago --delivery-surface slack --yes',
163
+ 'routines promote daily-operations-sweep --cron "0 9 * * *" --timezone America/Chicago --delivery-channel slack --yes',
164
164
  'routines promote weekly-review --every 7d --disabled',
165
165
  ],
166
166
  },
@@ -277,7 +277,7 @@ export async function handleTasks(runtime: CliCommandRuntime): Promise<string> {
277
277
  const [sub = 'list', ...rest] = runtime.cli.commandArgs;
278
278
  if (sub === 'submit') {
279
279
  return [
280
- 'GoodVibes Agent blocks CLI task submission from the copied task surface.',
280
+ 'GoodVibes Agent blocks CLI task submission from the copied task workflow.',
281
281
  ' policy: do normal assistant work in the main Agent conversation or use `goodvibes-agent run <prompt>` for an explicit one-shot run.',
282
282
  ' build/fix/review: use `goodvibes-agent delegate <task>` for explicit GoodVibes TUI handoff.',
283
283
  ' result: no local task was started.',
@@ -104,7 +104,7 @@ async function handleRoutinePromotion(runtime: CliCommandRuntime, args: readonly
104
104
  };
105
105
  return {
106
106
  output: json ? JSON.stringify(failure, null, 2) : [
107
- 'Usage: goodvibes-agent routines promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--timezone <tz>] [--name <schedule-name>] [--provider <id>] [--model <model>] [--delivery-surface <surface[:route[:label]]>|--delivery-route <route[:label]>|--delivery-webhook <url>|--delivery-link <url>] [--disabled] --yes',
107
+ 'Usage: goodvibes-agent 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',
108
108
  ...parsed.errors.map((error) => ` ${error}`),
109
109
  ].join('\n'),
110
110
  exitCode: 2,
@@ -241,7 +241,7 @@ export async function handleRoutinesCommand(runtime: CliCommandRuntime): Promise
241
241
  return handleRoutinePromotion(runtime, rest);
242
242
  }
243
243
  return {
244
- output: 'Usage: goodvibes-agent routines [list|enabled|show <id>|receipts|reconcile|receipt <id>|promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-surface <surface>|--delivery-route <route>|--delivery-webhook <url>] --yes]',
244
+ output: 'Usage: goodvibes-agent routines [list|enabled|show <id>|receipts|reconcile|receipt <id>|promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes]',
245
245
  exitCode: 2,
246
246
  };
247
247
  }
@@ -62,8 +62,8 @@ export interface CliServicePosture {
62
62
 
63
63
  const ENDPOINTS: readonly { readonly id: RuntimeEndpointId; readonly label: string; readonly enabledKey: string }[] = [
64
64
  { id: 'controlPlane', label: 'runtime API', enabledKey: 'controlPlane.enabled' },
65
- { id: 'httpListener', label: 'HTTP listener', enabledKey: 'danger.httpListener' },
66
- { id: 'web', label: 'web surface', enabledKey: 'web.enabled' },
65
+ { id: 'httpListener', label: 'incoming webhook listener', enabledKey: 'danger.httpListener' },
66
+ { id: 'web', label: 'browser companion', enabledKey: 'web.enabled' },
67
67
  ];
68
68
 
69
69
  interface CliServicePostureOptions {
@@ -184,13 +184,13 @@ export async function buildCliServicePosture(
184
184
  const issues: string[] = [];
185
185
 
186
186
  if (serverBackedEnabled && !config.enabled) {
187
- issues.push('Host-owned surfaces are configured, but Agent service ownership is disabled.');
187
+ issues.push('External runtime endpoints are configured, but Agent runtime ownership is disabled by design.');
188
188
  }
189
189
  if (config.enabled && !config.autostart) {
190
- issues.push('External runtime service config has autostart off.');
190
+ issues.push('External runtime host config has autostart off.');
191
191
  }
192
192
  if (config.enabled && !config.restartOnFailure) {
193
- issues.push('External runtime service config has restart-on-failure off.');
193
+ issues.push('External runtime host config has restart-on-failure off.');
194
194
  }
195
195
  for (const endpoint of endpoints) {
196
196
  if (endpoint.enabled && options.probe && endpoint.reachable === false) {
@@ -230,15 +230,15 @@ export function formatCliServicePosture(posture: CliServicePosture, json = false
230
230
  if (json) return JSON.stringify(posture, null, 2);
231
231
  return [
232
232
  'GoodVibes external runtime diagnostics',
233
- ' lifecycle: managed outside goodvibes-agent',
234
- ` service config enabled: ${yesNo(posture.config.enabled)}`,
233
+ ' ownership: managed outside goodvibes-agent',
234
+ ` host 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
  '',
241
- 'Endpoints:',
241
+ 'Runtime endpoints:',
242
242
  ...posture.endpoints.map((endpoint) =>
243
243
  ` ${endpoint.label}: enabled=${yesNo(endpoint.enabled)} ${endpoint.binding.hostMode} ${endpoint.binding.host}:${endpoint.binding.port} posture=${endpoint.bindPosture.label}${endpoint.reachable === undefined ? '' : ` reachable=${yesNo(endpoint.reachable)}`}`,
244
244
  ),
package/src/cli/status.ts CHANGED
@@ -28,7 +28,7 @@ export interface CliAuthStatus {
28
28
 
29
29
  export interface CliDoctorFinding {
30
30
  readonly id: string;
31
- readonly area: 'auth' | 'network' | 'onboarding' | 'security' | 'service' | 'secrets';
31
+ readonly area: 'auth' | 'network' | 'onboarding' | 'runtime' | 'security' | 'secrets';
32
32
  readonly severity: 'warning' | 'risk';
33
33
  readonly summary: string;
34
34
  readonly cause: string;
@@ -52,13 +52,13 @@ export interface CliStatusSnapshot {
52
52
  readonly secretPolicyLabel: string;
53
53
  readonly localUsers: CliAuthStatus | null;
54
54
  };
55
- readonly service: {
55
+ readonly runtimeConnection: {
56
56
  readonly enabled: unknown;
57
57
  readonly autostart: unknown;
58
58
  readonly restartOnFailure: unknown;
59
59
  readonly lifecycle?: CliServicePosture;
60
60
  };
61
- readonly surfaces: {
61
+ readonly runtimeEndpoints: {
62
62
  readonly controlPlane: ReturnType<typeof resolveRuntimeEndpointBinding> & { readonly enabled: unknown };
63
63
  readonly httpListener: ReturnType<typeof resolveRuntimeEndpointBinding> & { readonly enabled: unknown };
64
64
  readonly web: ReturnType<typeof resolveRuntimeEndpointBinding> & { readonly enabled: unknown };
@@ -111,30 +111,30 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
111
111
  const serverBackedEnabled = daemonEnabled || controlPlaneEnabled || listenerEnabled || webEnabled;
112
112
  const networkFacingSurfaces = [
113
113
  ['runtime API', controlPlaneEnabled, controlPlaneBinding],
114
- ['HTTP listener', listenerEnabled, httpListenerBinding],
115
- ['web surface', webEnabled, webBinding],
114
+ ['incoming webhook listener', listenerEnabled, httpListenerBinding],
115
+ ['browser companion', webEnabled, webBinding],
116
116
  ].filter(([, enabled, binding]) => isNetworkFacing(enabled, binding as typeof controlPlaneBinding));
117
117
 
118
118
  const findings: CliDoctorFinding[] = [];
119
119
 
120
120
  if (serverBackedEnabled && !serviceEnabled) {
121
121
  findings.push({
122
- id: 'service-disabled-for-server-surfaces',
123
- area: 'service',
122
+ id: 'runtime-ownership-external',
123
+ area: 'runtime',
124
124
  severity: 'warning',
125
- summary: 'Host-owned surfaces are configured while Agent service ownership is disabled.',
125
+ summary: 'External runtime endpoints are configured while Agent runtime ownership is disabled by design.',
126
126
  cause: 'One or more runtime API, listener, or web settings are enabled while service.enabled is false.',
127
- impact: 'The external GoodVibes runtime must own availability for those surfaces; Agent will not start or enable them.',
128
- action: 'Manage surface/service posture from GoodVibes TUI or the owning host, then use Agent for read-only diagnostics.',
127
+ impact: 'The external GoodVibes runtime must own availability for those endpoints; Agent will not start or enable them.',
128
+ action: 'Manage runtime availability from GoodVibes TUI or the owning host, then use Agent for read-only diagnostics.',
129
129
  });
130
130
  }
131
131
 
132
132
  if (serviceEnabled && !serviceAutostart) {
133
133
  findings.push({
134
- id: 'service-autostart-disabled',
135
- area: 'service',
134
+ id: 'runtime-autostart-disabled',
135
+ area: 'runtime',
136
136
  severity: 'warning',
137
- summary: 'External runtime service config has autostart off.',
137
+ summary: 'External runtime host config has autostart off.',
138
138
  cause: 'service.enabled is true and service.autostart is false.',
139
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.',
@@ -143,10 +143,10 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
143
143
 
144
144
  if (serviceEnabled && !restartOnFailure) {
145
145
  findings.push({
146
- id: 'service-restart-disabled',
147
- area: 'service',
146
+ id: 'runtime-restart-disabled',
147
+ area: 'runtime',
148
148
  severity: 'warning',
149
- summary: 'External runtime service config has restart-on-failure off.',
149
+ summary: 'External runtime host config has restart-on-failure off.',
150
150
  cause: 'service.enabled is true and service.restartOnFailure is false.',
151
151
  impact: 'A crashed runtime or listener may stay down until manually restarted.',
152
152
  action: 'Configure restart-on-failure from GoodVibes TUI or the owning host; Agent will not mutate this setting.',
@@ -157,11 +157,11 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
157
157
  for (const issue of options.service.issues) {
158
158
  if (findings.some((finding) => finding.summary === issue)) continue;
159
159
  findings.push({
160
- id: `service-lifecycle-${findings.length}`,
161
- area: 'service',
160
+ id: `runtime-connection-${findings.length}`,
161
+ area: 'runtime',
162
162
  severity: 'warning',
163
163
  summary: issue,
164
- cause: 'The service lifecycle inspection found a mismatch between configured service/surface state and observed host state.',
164
+ cause: 'The runtime connection inspection found a mismatch between configured endpoint state and observed host state.',
165
165
  impact: 'Runtime API, listener, or web availability may not match the configuration.',
166
166
  action: 'Use Agent status and doctor diagnostics here, then manage the runtime from GoodVibes TUI or your host tooling.',
167
167
  });
@@ -175,17 +175,17 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
175
175
  severity: 'warning',
176
176
  summary: 'Onboarding has not been shown for this user.',
177
177
  cause: 'No global user onboarding check marker was found.',
178
- impact: 'Important service, network, provider, auth, or permission choices may still be implicit defaults.',
178
+ impact: 'Important runtime, network, provider, auth, or permission choices may still be implicit defaults.',
179
179
  action: 'Run /onboarding in GoodVibes Agent or goodvibes-agent onboarding status to review setup state.',
180
180
  });
181
181
  }
182
182
 
183
183
  if (networkFacingSurfaces.length > 0 && options.auth?.userStorePresent !== true) {
184
184
  findings.push({
185
- id: 'network-surface-without-local-users',
185
+ id: 'network-endpoint-without-local-users',
186
186
  area: 'auth',
187
187
  severity: 'risk',
188
- summary: 'Network-facing surfaces are enabled before local users are configured.',
188
+ summary: 'Network-facing runtime endpoints are enabled before local users are configured.',
189
189
  cause: `${networkFacingSurfaces.map(([name]) => name).join(', ')} are LAN/custom-bound, but no local auth user store was found.`,
190
190
  impact: 'Remote access paths may be unusable or unsafe until local admin auth is configured.',
191
191
  action: 'Create/verify a local admin user before exposing GoodVibes on the network.',
@@ -194,7 +194,7 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
194
194
 
195
195
  if (networkFacingSurfaces.length > 0 && options.auth?.bootstrapCredentialPresent === true) {
196
196
  findings.push({
197
- id: 'network-surface-with-bootstrap-credential',
197
+ id: 'network-endpoint-with-bootstrap-credential',
198
198
  area: 'auth',
199
199
  severity: 'risk',
200
200
  summary: 'A bootstrap credential is still present while network-facing surfaces are enabled.',
@@ -223,7 +223,7 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
223
223
  severity: 'risk',
224
224
  summary: 'Plaintext secret storage is allowed.',
225
225
  cause: 'storage.secretPolicy is plaintext_allowed.',
226
- impact: 'Provider keys and surface tokens may be stored without secure backend protection.',
226
+ impact: 'Provider keys and channel tokens may be stored without secure backend protection.',
227
227
  action: 'Use Require secure storage or Use secure storage when available for normal operation.',
228
228
  });
229
229
  }
@@ -233,10 +233,10 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
233
233
  id: 'network-http-listener-enabled',
234
234
  area: 'network',
235
235
  severity: 'warning',
236
- summary: 'The HTTP listener is reachable beyond loopback.',
237
- cause: `HTTP listener is enabled on ${httpListenerBinding.host}:${httpListenerBinding.port} with ${httpListenerBinding.hostMode} binding.`,
236
+ summary: 'The incoming webhook listener is reachable beyond loopback.',
237
+ cause: `Incoming webhook listener is enabled on ${httpListenerBinding.host}:${httpListenerBinding.port} with ${httpListenerBinding.hostMode} binding.`,
238
238
  impact: 'External tools and devices may be able to reach incoming event endpoints.',
239
- action: 'Keep listener secrets/signature checks configured for every enabled webhook surface.',
239
+ action: 'Keep listener secrets/signature checks configured for every enabled webhook endpoint.',
240
240
  });
241
241
  }
242
242
 
@@ -266,13 +266,13 @@ export function buildCliStatusSnapshot(options: CliStatusOptions): CliStatusSnap
266
266
  secretPolicyLabel: secretPolicyLabel(config.get('storage.secretPolicy')),
267
267
  localUsers: options.auth ?? null,
268
268
  },
269
- service: {
269
+ runtimeConnection: {
270
270
  enabled: config.get('service.enabled'),
271
271
  autostart: config.get('service.autostart'),
272
272
  restartOnFailure: config.get('service.restartOnFailure'),
273
273
  ...(options.service ? { lifecycle: options.service } : {}),
274
274
  },
275
- surfaces: {
275
+ runtimeEndpoints: {
276
276
  controlPlane: { enabled: config.get('controlPlane.enabled'), ...controlPlaneBinding },
277
277
  httpListener: { enabled: config.get('danger.httpListener'), ...httpListenerBinding },
278
278
  web: { enabled: config.get('web.enabled'), ...webBinding },
@@ -289,15 +289,15 @@ export function buildCliStatusSnapshot(options: CliStatusOptions): CliStatusSnap
289
289
  export function renderCliStatus(options: CliStatusOptions): string {
290
290
  const config = options.configManager;
291
291
  const snapshot = buildCliStatusSnapshot(options);
292
- const serviceEnabled = snapshot.service.enabled;
293
- const serviceAutostart = snapshot.service.autostart;
294
- const restartOnFailure = snapshot.service.restartOnFailure;
295
- const controlPlaneEnabled = snapshot.surfaces.controlPlane.enabled;
296
- const listenerEnabled = snapshot.surfaces.httpListener.enabled;
297
- const webEnabled = snapshot.surfaces.web.enabled;
298
- const controlPlaneBinding = snapshot.surfaces.controlPlane;
299
- const httpListenerBinding = snapshot.surfaces.httpListener;
300
- const webBinding = snapshot.surfaces.web;
292
+ const serviceEnabled = snapshot.runtimeConnection.enabled;
293
+ const serviceAutostart = snapshot.runtimeConnection.autostart;
294
+ const restartOnFailure = snapshot.runtimeConnection.restartOnFailure;
295
+ const controlPlaneEnabled = snapshot.runtimeEndpoints.controlPlane.enabled;
296
+ const listenerEnabled = snapshot.runtimeEndpoints.httpListener.enabled;
297
+ const webEnabled = snapshot.runtimeEndpoints.web.enabled;
298
+ const controlPlaneBinding = snapshot.runtimeEndpoints.controlPlane;
299
+ const httpListenerBinding = snapshot.runtimeEndpoints.httpListener;
300
+ const webBinding = snapshot.runtimeEndpoints.web;
301
301
  const marker = options.onboardingMarkers?.effective;
302
302
  const findings = snapshot.findings;
303
303
 
@@ -326,10 +326,10 @@ 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 Runtime Service:',
330
- ` enabled: ${yesNo(serviceEnabled)}`,
331
- ` autostart: ${yesNo(serviceAutostart)}`,
332
- ` restartOnFailure: ${yesNo(restartOnFailure)}`,
329
+ 'External Runtime Connection:',
330
+ ` hostConfigEnabled: ${yesNo(serviceEnabled)}`,
331
+ ` hostAutostart: ${yesNo(serviceAutostart)}`,
332
+ ` hostRestartOnFailure: ${yesNo(restartOnFailure)}`,
333
333
  ...(options.service ? [
334
334
  ` platform: ${options.service.managed.platform}`,
335
335
  ` installed: ${yesNo(options.service.managed.installed)}`,
@@ -339,9 +339,9 @@ export function renderCliStatus(options: CliStatusOptions): string {
339
339
  ] : []),
340
340
  '',
341
341
  'Runtime Endpoints:',
342
- bindLine('controlPlane', controlPlaneEnabled, controlPlaneBinding),
343
- bindLine('httpListener', listenerEnabled, httpListenerBinding),
344
- bindLine('web', webEnabled, webBinding),
342
+ bindLine('runtimeApi', controlPlaneEnabled, controlPlaneBinding),
343
+ bindLine('incomingWebhook', listenerEnabled, httpListenerBinding),
344
+ bindLine('browserCompanion', webEnabled, webBinding),
345
345
  '',
346
346
  'Onboarding:',
347
347
  ` checked: ${marker?.exists ? 'yes' : 'no'}`,
@@ -196,7 +196,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
196
196
  detail: 'Agent does not create local automation jobs or hidden scheduler spawns. Reviewed local routines can be promoted into external schedules only through an explicit schedules.create command with --yes, optional delivery targets, and a redacted local receipt.',
197
197
  actions: [
198
198
  { id: 'schedule-list', label: 'List schedules', detail: 'Inspect configured jobs and history without running or mutating them.', command: '/schedule list', kind: 'command', safety: 'read-only' },
199
- { id: 'schedule-promote-routine', label: 'Promote routine', detail: 'Create an external schedule from a local Agent routine. Requires a real routine id, schedule expression, optional delivery target, and explicit --yes.', command: '/schedule promote-routine <routine-id> --cron <expr> [--delivery-surface slack] --yes', kind: 'command', safety: 'safe' },
199
+ { id: 'schedule-promote-routine', label: 'Promote routine', detail: 'Create an external schedule from a local Agent routine. Requires a real routine id, schedule expression, optional delivery target, and explicit --yes.', command: '/schedule promote-routine <routine-id> --cron <expr> [--delivery-channel slack] --yes', kind: 'command', safety: 'safe' },
200
200
  { id: 'schedule-receipts', label: 'Promotion receipts', detail: 'Review local redacted receipt history for routine-to-schedule promotion attempts.', command: '/schedule receipts', kind: 'command', safety: 'read-only' },
201
201
  { id: 'schedule-reconcile', label: 'Reconcile schedules', detail: 'Compare local promotion receipts with live external schedules using schedules.list.', command: '/schedule reconcile', kind: 'command', safety: 'read-only' },
202
202
  { id: 'schedule-policy', label: 'Local scheduler blocked', detail: 'Local schedule add/run/remove/enable/disable remain blocked; only explicit external schedule promotion is allowed here.', kind: 'guidance', safety: 'blocked' },
@@ -64,7 +64,7 @@ export function registerExperienceRuntimeCommands(registry: CommandRegistry): vo
64
64
  ctx.print([
65
65
  `Approval Review: ${entry[0]}`,
66
66
  ` ${entry[1]}`,
67
- ' Related surfaces: /security, /policy preflight, /trust, /mcp',
67
+ ' Related workspaces: /security, /policy preflight, /trust, /mcp',
68
68
  ].join('\n'));
69
69
  return;
70
70
  }
@@ -74,7 +74,7 @@ export function registerExperienceRuntimeCommands(registry: CommandRegistry): vo
74
74
 
75
75
  registry.register({
76
76
  name: 'voice',
77
- description: 'Review voice posture and package portable voice-surface metadata',
77
+ description: 'Review voice posture and package portable voice interaction metadata',
78
78
  usage: '[review|enable --yes|disable --yes|bundle export <path> --yes|bundle inspect <path>]',
79
79
  handler(args, ctx) {
80
80
  const parsed = stripYesFlag(args);
@@ -86,19 +86,19 @@ export function registerExperienceRuntimeCommands(registry: CommandRegistry): vo
86
86
  ctx.print([
87
87
  'Voice Review',
88
88
  ` enabled: ${enabled ? 'yes' : 'no'}`,
89
- ' posture: optional local companion surface; disabled by default',
89
+ ' posture: optional local companion interaction; disabled by default',
90
90
  ' note: voice remains an optional operator convenience, not a required SaaS dependency',
91
91
  ].join('\n'));
92
92
  return;
93
93
  }
94
94
  if (sub === 'enable' || sub === 'disable') {
95
95
  if (!parsed.yes) {
96
- requireYesFlag(ctx, `${sub} voice surface`, `/voice ${sub} --yes`);
96
+ requireYesFlag(ctx, `${sub} voice interaction`, `/voice ${sub} --yes`);
97
97
  return;
98
98
  }
99
99
  const next = sub === 'enable';
100
100
  ctx.platform.configManager.setDynamic('ui.voiceEnabled', next);
101
- ctx.print(`Voice surface ${next ? 'enabled' : 'disabled'} for this runtime.`);
101
+ ctx.print(`Voice interaction ${next ? 'enabled' : 'disabled'} for this runtime.`);
102
102
  return;
103
103
  }
104
104
  if (sub === 'bundle') {
@@ -120,7 +120,7 @@ export function registerExperienceRuntimeCommands(registry: CommandRegistry): vo
120
120
  enabled: Boolean(ctx.platform.configManager.get('ui.voiceEnabled')),
121
121
  notes: [
122
122
  'Voice is optional and local-first.',
123
- 'Operator review remains the primary control surface for risky actions.',
123
+ 'Operator review remains the primary review path for risky actions.',
124
124
  ],
125
125
  };
126
126
  mkdirSync(dirname(targetPath), { recursive: true });
@@ -229,7 +229,7 @@ export function registerOperatorRuntimeCommands(registry: CommandRegistry): void
229
229
  + ' /mode — show current mode and settings\n'
230
230
  + ' /mode show — show current mode and settings\n'
231
231
  + ' /mode quiet --yes — suppress all non-critical notifications\n'
232
- + ' /mode balanced --yes — surface warnings, batch info noise (default)\n'
232
+ + ' /mode balanced --yes — show warnings, batch info noise (default)\n'
233
233
  + ' /mode operator --yes — full verbosity, no suppression\n'
234
234
  + ' /mode set-domain <d> <v> --yes — per-domain verbosity override (minimal|normal|verbose)'
235
235
  );
@@ -299,7 +299,7 @@ export function registerRoutinesRuntimeCommands(registry: CommandRegistry): void
299
299
  name: 'routines',
300
300
  aliases: ['routine'],
301
301
  description: 'Manage local GoodVibes Agent routines',
302
- usage: '[list|enabled|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps>|update <id> [--name ...] [--description ...] [--steps ...]|enable <id>|disable <id>|start <id>|review <id>|stale <id> <reason...>|promote <id> --cron <expr> [--delivery-surface slack] --yes|delete <id> --yes]',
302
+ usage: '[list|enabled|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps>|update <id> [--name ...] [--description ...] [--steps ...]|enable <id>|disable <id>|start <id>|review <id>|stale <id> <reason...>|promote <id> --cron <expr> [--delivery-channel slack] --yes|delete <id> --yes]',
303
303
  handler: runRoutinesRuntimeCommand,
304
304
  });
305
305
  }
@@ -64,7 +64,7 @@ async function promoteRoutineSchedule(args: readonly string[], ctx: CommandConte
64
64
  const parsed = parseRoutineSchedulePromotionArgs(args);
65
65
  if (parsed.errors.length > 0) {
66
66
  ctx.print([
67
- 'Usage: /schedule promote-routine <routine-id> (--cron <expr>|--every <interval>|--at <iso-time>) [--timezone <tz>] [--name <schedule-name>] [--provider <id>] [--model <model>] [--delivery-surface <surface[:route[:label]]>|--delivery-route <route[:label]>|--delivery-webhook <url>|--delivery-link <url>] [--disabled] --yes',
67
+ 'Usage: /schedule promote-routine <routine-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',
68
68
  ...parsed.errors.map((error) => ` ${error}`),
69
69
  ].join('\n'));
70
70
  return;
@@ -91,8 +91,8 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
91
91
  name: 'schedule',
92
92
  aliases: ['sched'],
93
93
  description: 'Inspect schedules and explicitly promote local Agent routines to external schedules',
94
- usage: 'list | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> [--delivery-surface slack] --yes',
95
- argsHint: 'list | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> [--delivery-surface slack] --yes',
94
+ usage: 'list | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> [--delivery-channel slack] --yes',
95
+ argsHint: 'list | receipts | reconcile | receipt <id> | promote-routine <routine-id> --cron <expr> [--delivery-channel slack] --yes',
96
96
  async handler(args, ctx) {
97
97
  const sub = args[0];
98
98
 
@@ -164,7 +164,7 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
164
164
  + ' /schedule receipts\n'
165
165
  + ' /schedule reconcile\n'
166
166
  + ' /schedule receipt <receipt-id>\n'
167
- + ' /schedule promote-routine <routine-id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-surface <surface>|--delivery-route <route>|--delivery-webhook <url>] --yes\n'
167
+ + ' /schedule promote-routine <routine-id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes\n'
168
168
  + ' Local schedule mutations and runs remain blocked.'
169
169
  );
170
170
  },
@@ -16,7 +16,7 @@ const BLOCKED_TASK_MUTATIONS: ReadonlySet<string> = new Set([
16
16
  function printTaskMutationBlocked(print: (text: string) => void, subcommand: string): void {
17
17
  print([
18
18
  `Task mutation "${subcommand}" is blocked in GoodVibes Agent.`,
19
- ' policy: runtime tasks are read-only from the Agent surface; normal work stays in the main conversation.',
19
+ ' policy: runtime tasks are read-only from the Agent TUI; normal work stays in the main conversation.',
20
20
  ' durable tasks: use /workplan for visible planning and task tracking.',
21
21
  ' build/fix/review: use /delegate <task> to hand explicit implementation work to GoodVibes TUI.',
22
22
  ' result: no local runtime task state was changed.',
@@ -125,7 +125,7 @@ export function buildToolsStep(): OnboardingWizardStepDefinition {
125
125
  kind: 'status',
126
126
  id: 'agent-tools.no-hidden-work',
127
127
  label: 'Hidden work policy',
128
- hint: 'Tool use stays visible in the main Agent conversation or explicit command surface; no hidden background work is started from onboarding.',
128
+ hint: 'Tool use stays visible in the main Agent conversation or explicit command workspace; no hidden background work is started from onboarding.',
129
129
  defaultValue: 'Visible',
130
130
  },
131
131
  ],
@@ -335,7 +335,7 @@ export class KnowledgePanel extends ScrollableListPanel<MemoryRecord> {
335
335
  [' project ', C.label], [String(byScope.get('project') ?? 0), C.value],
336
336
  [' team ', C.label], [String(byScope.get('team') ?? 0), C.good],
337
337
  ]),
338
- buildGuidanceLine(width, '/recall review', 'work the stale and contradicted queue from the command surface', C),
338
+ buildGuidanceLine(width, '/recall review', 'work the stale and contradicted queue from the command workspace', C),
339
339
  ];
340
340
 
341
341
  const recentSummaryLines: Line[] = [];
@@ -189,7 +189,7 @@ export class MemoryPanel extends SearchableListPanel<MemoryRecord> {
189
189
  { label: 'runbooks', value: String(byClass.get('runbook') ?? 0), valueColor: C.runbook },
190
190
  ], C),
191
191
  filterLine,
192
- buildGuidanceLine(width, '/recall review', 'review durable knowledge and queue posture from the command surface', C),
192
+ buildGuidanceLine(width, '/recall review', 'review durable knowledge and queue posture from the command workspace', C),
193
193
  ];
194
194
 
195
195
  const selected = records[this.selectedIndex];
@@ -79,7 +79,7 @@ export class SubscriptionPanel extends ScrollableListPanel<SubscriptionRow> {
79
79
  protected override getEmptyStateActions() {
80
80
  return [
81
81
  { command: '/subscription login openai start --yes', summary: 'start the first-class OpenAI subscription flow' },
82
- { command: '/login provider <name> start --yes', summary: 'use the front-door auth surface for supported providers' },
82
+ { command: '/login provider <name> start --yes', summary: 'use the front-door auth flow for supported providers' },
83
83
  { command: '/services auth-review', summary: 'inspect configured service auth posture and stored secrets' },
84
84
  ];
85
85
  }
@@ -205,7 +205,7 @@ export class SubscriptionPanel extends ScrollableListPanel<SubscriptionRow> {
205
205
  intro,
206
206
  sections: [{ lines: [...summaryLines, ...emptyLines] }],
207
207
  footerLines: [
208
- buildGuidanceLine(width, '/subscription login <provider> start --yes', 'start browser-based provider login from the packaged subscription surface', C),
208
+ buildGuidanceLine(width, '/subscription login <provider> start --yes', 'start browser-based provider login from the packaged subscription flow', C),
209
209
  buildPanelLine(width, [[' Up/Down move Enter/X sign out selected provider r refresh', C.dim]]),
210
210
  ],
211
211
  palette: C,
@@ -255,7 +255,7 @@ export class SubscriptionPanel extends ScrollableListPanel<SubscriptionRow> {
255
255
  header: headerLines,
256
256
  footer: [
257
257
  ...detailRows,
258
- buildGuidanceLine(width, '/subscription login <provider> start --yes', 'start browser-based provider login from the packaged subscription surface', C),
258
+ buildGuidanceLine(width, '/subscription login <provider> start --yes', 'start browser-based provider login from the packaged subscription flow', C),
259
259
  buildPanelLine(width, [[' Up/Down move Enter/X sign out selected provider r refresh', C.dim]]),
260
260
  ],
261
261
  });
@@ -144,7 +144,7 @@ export class SystemMessagesPanel extends ScrollableListPanel<SystemMessageEntry>
144
144
  this.getEmptyStateMessage(),
145
145
  'Model switches, scan notices, provider/system state, and other operational updates will appear here once the runtime starts emitting them.',
146
146
  [
147
- { command: '/help', summary: 'review command and workflow surfaces' },
147
+ { command: '/help', summary: 'review commands and operator workflows' },
148
148
  { command: '/cockpit', summary: 'open the unified runtime control room' },
149
149
  ],
150
150
  C,
@@ -185,7 +185,7 @@ export class TasksPanel extends ScrollableListPanel<RuntimeTask> {
185
185
  width,
186
186
  ' Runtime store not wired into this panel yet.',
187
187
  'Use the Tasks panel with a live runtime store to review active execution, cancellations, retries, and completion results.',
188
- [{ command: '/tasks', summary: 'open or operate the task surface from a shell-owned runtime' }],
188
+ [{ command: '/tasks', summary: 'inspect runtime tasks without starting background work' }],
189
189
  C,
190
190
  ),
191
191
  }],
@@ -192,10 +192,10 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
192
192
  } else if (category.id === 'voice-media') {
193
193
  base.push(
194
194
  { text: `Voice providers: ${snapshot.voiceProviderCount}; streaming TTS: ${snapshot.voiceStreamingProviderCount}; STT: ${snapshot.voiceSttProviderCount}; realtime: ${snapshot.voiceRealtimeProviderCount}.`, fg: PALETTE.info },
195
- { text: `Voice surface: ${snapshot.voiceSurfaceEnabled ? 'enabled' : 'disabled'}; use /voice review for portable voice posture.`, fg: snapshot.voiceSurfaceEnabled ? PALETTE.warn : PALETTE.muted },
195
+ { text: `Voice interaction: ${snapshot.voiceSurfaceEnabled ? 'enabled' : 'disabled'}; use /voice review for portable voice posture.`, fg: snapshot.voiceSurfaceEnabled ? PALETTE.warn : PALETTE.muted },
196
196
  { text: `TTS config: provider ${snapshot.ttsProvider}; voice ${snapshot.ttsVoice}; response model ${snapshot.ttsResponseModel}.`, fg: PALETTE.info },
197
197
  { text: `Media providers: ${snapshot.mediaProviderCount}; understanding: ${snapshot.mediaUnderstandingProviderCount}; generation: ${snapshot.mediaGenerationProviderCount}.`, fg: PALETTE.info },
198
- { text: `Browser tools: ${snapshot.browserSurfaceEnabled ? 'available' : 'not advertised'}; public base URL ${snapshot.browserSurfacePublicBaseUrl}.`, fg: snapshot.browserSurfaceEnabled ? PALETTE.warn : PALETTE.muted },
198
+ { text: `Browser companion: ${snapshot.browserSurfaceEnabled ? 'available' : 'not advertised'}; public base URL ${snapshot.browserSurfacePublicBaseUrl}.`, fg: snapshot.browserSurfaceEnabled ? PALETTE.warn : PALETTE.muted },
199
199
  { text: 'Build dispatch stays out of setup; explicit delegation is handled from the Build Delegation workspace.', fg: PALETTE.good },
200
200
  { text: 'Image input uses prompt attachments; media generation/provider setup stays behind explicit commands and configured providers.', fg: PALETTE.muted },
201
201
  );
@@ -83,7 +83,7 @@ export function renderHelpOverlay(
83
83
  ['hooks', '', 'Hook workbench and runtime activity'],
84
84
  ['orchestration','', 'Graph and recursive-agent control room'],
85
85
  ['communication','', 'Structured agent communication workspace'],
86
- ['tasks', '', 'Task surface for list/show/pause/resume/output'],
86
+ ['tasks', '', 'Read-only task view for list/show/pause/resume/output'],
87
87
  ];
88
88
 
89
89
  // Build command rows from featured list, filtering out unregistered commands.
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.73';
9
+ let _version = '0.1.75';
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 {