@pellux/goodvibes-agent 0.1.88 → 0.1.90

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.90 - 2026-06-01
6
+
7
+ - 19f67ea Polish Agent command guidance
8
+
9
+ ## 0.1.89 - 2026-06-01
10
+
11
+ - 6be201c Fix Agent workspace command targets
12
+
5
13
  ## 0.1.88 - 2026-06-01
6
14
 
7
15
  - e97d2a2 Fix release test daemon port allocation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "0.1.88",
3
+ "version": "0.1.90",
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",
@@ -1,6 +1,8 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import { existsSync, readFileSync, statSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
+ import { CommandRegistry } from '../input/command-registry.ts';
5
+ import { registerBuiltinCommands } from '../input/commands.ts';
4
6
 
5
7
  export interface PackageCliBinVerification {
6
8
  readonly command: 'goodvibes-agent';
@@ -108,11 +110,40 @@ const PACKAGE_FACING_REQUIRED_TEXT: readonly {
108
110
  { path: 'docs/runtime-connection.md', required: ['/api/goodvibes-agent/knowledge'] },
109
111
  { path: 'docs/release-and-publishing.md', required: ['/api/goodvibes-agent/knowledge'] },
110
112
  ];
113
+ const NON_COMMAND_ROUTE_ROOTS = new Set(['api', 'status']);
111
114
 
112
115
  function readPackageJson(root: string): Record<string, unknown> {
113
116
  return JSON.parse(readFileSync(join(root, 'package.json'), 'utf-8')) as Record<string, unknown>;
114
117
  }
115
118
 
119
+ function buildRegisteredSlashCommandNames(): ReadonlySet<string> {
120
+ const registry = new CommandRegistry();
121
+ registerBuiltinCommands(registry);
122
+ const names = new Set<string>();
123
+ for (const command of registry.list()) {
124
+ names.add(command.name);
125
+ for (const alias of command.aliases ?? []) names.add(alias);
126
+ }
127
+ return names;
128
+ }
129
+
130
+ function verifyPackageFacingSlashCommands(path: string, content: string, registeredCommands: ReadonlySet<string>): readonly string[] {
131
+ const failures: string[] = [];
132
+ const commandPattern = /(^|[\s`([])\/([a-z][a-z0-9_-]*)(?=$|[\s`.,;:)\]])/g;
133
+ const lines = content.split(/\r?\n/);
134
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
135
+ const line = lines[lineIndex] ?? '';
136
+ commandPattern.lastIndex = 0;
137
+ for (let match = commandPattern.exec(line); match !== null; match = commandPattern.exec(line)) {
138
+ const root = match[2] ?? '';
139
+ if (NON_COMMAND_ROUTE_ROOTS.has(root)) continue;
140
+ if (registeredCommands.has(root)) continue;
141
+ failures.push(`package-facing text ${path}:${lineIndex + 1} references unknown Agent slash command: /${root}`);
142
+ }
143
+ }
144
+ return failures;
145
+ }
146
+
116
147
  function hasExecutableBit(path: string): boolean {
117
148
  return existsSync(path) && (statSync(path).mode & 0o111) !== 0;
118
149
  }
@@ -146,6 +177,7 @@ function registryPackDryRun(root: string): { readonly files: readonly string[];
146
177
 
147
178
  export function verifyPackageFacingText(root: string): { readonly checkedPaths: readonly string[]; readonly failures: readonly string[] } {
148
179
  const failures: string[] = [];
180
+ const registeredCommands = buildRegisteredSlashCommandNames();
149
181
  for (const path of PACKAGE_FACING_TEXT_PATHS) {
150
182
  const absolutePath = join(root, path);
151
183
  if (!existsSync(absolutePath)) {
@@ -153,6 +185,9 @@ export function verifyPackageFacingText(root: string): { readonly checkedPaths:
153
185
  continue;
154
186
  }
155
187
  const content = readFileSync(absolutePath, 'utf-8');
188
+ if (path !== 'CHANGELOG.md') {
189
+ failures.push(...verifyPackageFacingSlashCommands(path, content, registeredCommands));
190
+ }
156
191
  for (const forbidden of PACKAGE_FACING_FORBIDDEN_TEXT) {
157
192
  if (content.includes(forbidden)) {
158
193
  failures.push(`package-facing text ${path} contains forbidden default/TUI route or policy: ${forbidden}`);
@@ -49,8 +49,8 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
49
49
  detail: 'Agent uses externally managed channels. Pairing, account inspection, and readiness checks are visible here; inbound delivery and public channel exposure stay policy-gated.',
50
50
  actions: [
51
51
  { id: 'pair', label: 'Pair companion', detail: 'Open the QR pairing view for companion app setup.', command: '/pair', kind: 'command', safety: 'safe' },
52
- { id: 'communication', label: 'Communication routes', detail: 'Inspect structured communication routes and recent activity.', command: '/communication', kind: 'command', safety: 'read-only' },
53
- { id: 'setup-review', label: 'Channel setup review', detail: 'Review setup posture without starting inbound endpoints or mutating channel state.', command: '/setup review', kind: 'command', safety: 'read-only' },
52
+ { id: 'notification-routes', label: 'Notification routes', detail: 'Inspect configured webhook notification URLs without sending a test message.', command: '/notify list', kind: 'command', safety: 'read-only' },
53
+ { id: 'setup-review', label: 'Health review', detail: 'Review setup posture without starting inbound endpoints or mutating channel state.', command: '/health review', kind: 'command', safety: 'read-only' },
54
54
  { id: 'channel-safety', label: 'Delivery safety', detail: 'External messages, channel DMs, and public delivery targets require explicit user action and runtime policy. Agent will not silently send or expose channels from this workspace.', kind: 'guidance', safety: 'blocked' },
55
55
  ],
56
56
  },
@@ -90,14 +90,14 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
90
90
  group: 'SETUP',
91
91
  label: 'Profiles',
92
92
  summary: 'Isolated Agent homes, config profiles, and setup bundles.',
93
- detail: 'Profiles isolate Agent state. GoodVibes Agent exposes named homes, config profile pickers, profile-sync bundles, setup transfer bundles, and support bundles while keeping the shared runtime external.',
93
+ detail: 'Profiles isolate Agent state. GoodVibes Agent exposes named homes, starter templates, and config profile pickers while keeping the shared runtime external.',
94
94
  actions: [
95
95
  { id: 'profiles-open', label: 'Open config profiles', detail: 'Open the config profile picker for display/provider/behavior profile files.', command: '/profiles', kind: 'command', safety: 'safe' },
96
96
  { id: 'runtime-profile-guide', label: 'Starter authoring guide', detail: 'Open the Agent-local starter authoring flow inside the Agent TUI.', command: '/agent-profile guide', kind: 'command', safety: 'safe' },
97
97
  { id: 'runtime-profile-templates', label: 'Browse starter templates', detail: 'List built-in and local Agent starter templates with persona, skill, routine, and source details.', command: '/agent-profile templates', kind: 'command', safety: 'read-only' },
98
- { id: 'profile-sync-list', label: 'Profile sync list', detail: 'Inspect saved config profiles available for export/import.', command: '/profilesync list', kind: 'command', safety: 'read-only' },
99
- { id: 'profile-sync-export', label: 'Export profile sync', detail: 'Export config profiles to a portable bundle. Requires a real path and explicit --yes.', command: '/profilesync export <path> --yes', kind: 'command', safety: 'safe' },
100
- { id: 'setup-transfer-export', label: 'Export setup transfer', detail: 'Export Agent setup transfer data from the current home. Requires a real path and explicit --yes.', command: '/setup transfer export <path> --yes', kind: 'command', safety: 'safe' },
98
+ { id: 'runtime-profile-list', label: 'List Agent profiles', detail: 'List isolated Agent profile homes under this Agent home.', command: '/agent-profile list', kind: 'command', safety: 'read-only' },
99
+ { id: 'runtime-profile-template-export', label: 'Export starter template', detail: 'Export a starter template JSON file. Requires a real starter id, path, and explicit --yes.', command: '/agent-profile template export <id> <path> --yes', kind: 'command', safety: 'safe' },
100
+ { id: 'runtime-profile-template-import', label: 'Import starter template', detail: 'Import a reviewed starter template JSON file into this Agent home. Requires a real path and explicit --yes.', command: '/agent-profile template import <path> --yes', kind: 'command', safety: 'safe' },
101
101
  { id: 'runtime-profile-create', label: 'Create Agent profile', detail: 'Open an in-workspace form that creates an isolated Agent home from a built-in or local starter.', editorKind: 'profile', kind: 'editor', safety: 'safe' },
102
102
  { id: 'runtime-profile-template-edit', label: 'Customize starter', detail: 'Export a starter JSON file, edit it, import it as a local starter, then create a profile from it.', command: '/agent-profile template export <id> <path> --yes', kind: 'command', safety: 'safe' },
103
103
  { id: 'runtime-profile-switch', label: 'Switch Agent profile', detail: 'Launch goodvibes-agent --agent-profile <name> to use that isolated Agent home. This workspace cannot switch the current process home after startup.', kind: 'guidance', safety: 'safe' },
@@ -40,7 +40,7 @@ export function buildAgentWorkspaceSetupChecklist(input: AgentWorkspaceSetupChec
40
40
  label: 'GoodVibes runtime',
41
41
  status: 'ready',
42
42
  detail: `Agent will connect to ${input.daemonBaseUrl}; runtime ownership stays outside this product.`,
43
- command: '/status',
43
+ command: '/health',
44
44
  },
45
45
  {
46
46
  id: 'provider-model',
@@ -238,6 +238,10 @@ function runBundleCommand(args: readonly string[], ctx: CommandContext, skillReg
238
238
 
239
239
  export async function runAgentSkillsRuntimeCommand(args: readonly string[], ctx: CommandContext): Promise<void> {
240
240
  const sub = (args[0] ?? 'list').toLowerCase();
241
+ if (sub === 'local' || sub === 'agent') {
242
+ await runAgentSkillsRuntimeCommand(args.slice(1), ctx);
243
+ return;
244
+ }
241
245
  const skillRegistry = registryFromContext(ctx);
242
246
  try {
243
247
  if (sub === 'bundle' || sub === 'bundles') {
@@ -356,7 +360,7 @@ export async function runAgentSkillsRuntimeCommand(args: readonly string[], ctx:
356
360
  export function registerAgentSkillsRuntimeCommands(registry: CommandRegistry): void {
357
361
  registry.register({
358
362
  name: 'agent-skills',
359
- aliases: ['askills', 'local-skills'],
363
+ aliases: ['askills', 'local-skills', 'skills', 'skill'],
360
364
  description: 'Manage local GoodVibes Agent skills',
361
365
  usage: '[list|enabled|search <query>|show <id>|create --name <name> --description <summary> --procedure <steps>|update <id> [--name ...] [--description ...] [--procedure ...]|enable <id>|disable <id>|review <id>|stale <id> <reason...>|delete <id> --yes|bundle ...]',
362
366
  handler: runAgentSkillsRuntimeCommand,
@@ -103,9 +103,9 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
103
103
  ` recent failures: ${settings.recentFailureCount}`,
104
104
  ` staged bundle: ${settings.hasStagedManagedBundle ? 'present' : 'none'}`,
105
105
  ...(issues.length > 0 ? issues.map((issue) => ` issue: ${issue}`) : [' no active settings-control issues detected']),
106
- ' next: /settingssync panel',
107
- ' next: /settingssync show <key>',
108
- ' next: /managed staged',
106
+ ' next: /settings',
107
+ ' next: /config <key>',
108
+ ' next: /health repair settings',
109
109
  ].join('\n'));
110
110
  return;
111
111
  }
@@ -131,8 +131,8 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
131
131
  ` active connections: ${snapshot.activeConnections}`,
132
132
  ` degraded: ${snapshot.degradedConnections}`,
133
133
  ...(issues.length > 0 ? issues.map((issue) => ` issue: ${issue}`) : [' no active remote recovery issues detected']),
134
- ' next: /remote supervisor',
135
- ' next: /remote recover <runnerId>',
134
+ ' next: /delegate <build/fix/review task> for explicit TUI build work',
135
+ ' next: use the external runtime host for remote worker repair',
136
136
  ].join('\n'));
137
137
  return;
138
138
  }
@@ -217,14 +217,14 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
217
217
  lines.push(' domain: settings');
218
218
  lines.push(...(
219
219
  settings.conflicts.length > 0
220
- ? [' /settingssync panel', ' /settingssync show <key>', ' /managed staged']
220
+ ? [' /settings', ' /config <key>', ' runtime-owned managed setting repair stays external']
221
221
  : [' no active settings repair actions suggested']
222
222
  ));
223
223
  lines.push(' verify: /health settings');
224
224
  } else if (domain === 'auth') {
225
225
  lines.push(' domain: auth');
226
226
  lines.push(' /auth review');
227
- lines.push(' /providers');
227
+ lines.push(' /provider');
228
228
  lines.push(' /subscription providers');
229
229
  lines.push(' runtime auth users/bootstrap cleanup: use the runtime-owning GoodVibes TUI or host tooling');
230
230
  lines.push(' verify: /health auth');
@@ -237,15 +237,13 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
237
237
  lines.push(' verify: /health accounts');
238
238
  } else if (domain === 'services') {
239
239
  lines.push(' domain: services');
240
- lines.push(' /services doctor');
241
- lines.push(' /services auth-review');
242
240
  lines.push(' /health services');
241
+ lines.push(' runtime service repair belongs to the external GoodVibes runtime host');
243
242
  lines.push(' verify: /health services');
244
243
  } else if (domain === 'remote') {
245
244
  lines.push(' domain: remote');
246
- lines.push(' /remote supervisor');
247
- lines.push(' /remote recover <runnerId>');
248
- lines.push(' /remote setup');
245
+ lines.push(' /delegate <build/fix/review task> for explicit TUI build work');
246
+ lines.push(' remote runner setup and recovery belong to the external runtime host');
249
247
  lines.push(' verify: /health remote');
250
248
  } else if (domain === 'mcp') {
251
249
  lines.push(' domain: mcp');
@@ -262,9 +260,8 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
262
260
  } else if (domain === 'maintenance') {
263
261
  lines.push(' domain: maintenance');
264
262
  lines.push(' /health maintenance');
265
- lines.push(' /guidance review');
263
+ lines.push(' /mode');
266
264
  lines.push(' /compact');
267
- lines.push(' /panel tokens');
268
265
  lines.push(' verify: /health maintenance');
269
266
  } else {
270
267
  lines.push(' domains: settings, auth, accounts, services, remote, mcp, continuity, maintenance');
@@ -329,7 +326,7 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
329
326
  ' /health remote',
330
327
  ' /health maintenance',
331
328
  ' /health repair <domain>',
332
- ' /setup onboarding',
329
+ ' /onboarding',
333
330
  ].join('\n'));
334
331
  },
335
332
  });
@@ -202,7 +202,7 @@ export function registerMcpRuntimeCommands(registry: CommandRegistry): void {
202
202
  ...needingAttention.map((server) => (
203
203
  ` ${server.name} connected=${server.connected ? 'yes' : 'no'} freshness=${server.schemaFreshness} trust=${server.trustMode}`
204
204
  )),
205
- ' next: /services auth-review',
205
+ ' next: /auth review',
206
206
  ' next: /mcp repair <server>',
207
207
  ].join('\n')
208
208
  : 'MCP Auth Review\n No MCP servers currently need auth or quarantine recovery.');
@@ -223,7 +223,7 @@ export function registerMcpRuntimeCommands(registry: CommandRegistry): void {
223
223
  selected.schemaFreshness === 'quarantined'
224
224
  ? `/mcp quarantine ${selected.name} approve operator --yes`
225
225
  : null,
226
- !selected.connected ? '/services auth-review' : null,
226
+ !selected.connected ? '/auth review' : null,
227
227
  '/mcp review',
228
228
  '/health review',
229
229
  ].filter((entry): entry is string => entry !== null);
@@ -264,7 +264,7 @@ export async function handleSessionWorkflowCommand(args: string[], ctx: CommandC
264
264
  ctx.print(` Reopened panels: ${reopenedPanels.join(', ')}`);
265
265
  }
266
266
  if ((meta.returnContext.remoteRunners?.length ?? 0) > 0) {
267
- ctx.print(` Remote re-entry: /remote recover ${meta.returnContext.remoteRunners![0]}`);
267
+ ctx.print(' Remote re-entry: use the external runtime host for remote runner recovery; delegate explicit build/fix/review recovery from Agent.');
268
268
  }
269
269
  if ((meta.returnContext.worktreePaths?.length ?? 0) > 0) {
270
270
  ctx.print(' Worktree re-entry: open GoodVibes TUI in the target workspace; delegate explicit build/fix/review recovery from Agent.');
@@ -20,7 +20,7 @@ const APPROVAL_ROWS = [
20
20
  ['network', 'why prompted: external hosts, fetch scope, egress policy', 'review via /approval review network'],
21
21
  ['delegate', 'why prompted: recursive agents, spawn ceilings, write-set inheritance', 'review via /approval review delegate'],
22
22
  ['mcp', 'why prompted: trust escalation, host scope, path scope, coherence mismatch', 'review via /mcp trust and /security'],
23
- ['remote', 'why prompted: runner trust, remote write scope, artifact requirements', 'review via /remote and delegated TUI execution context'],
23
+ ['remote', 'why prompted: runner trust, remote write scope, artifact requirements', 'review delegated TUI execution context'],
24
24
  ['hook', 'why prompted: deny/mutate authority, blocking behavior, runner provenance', 'review via /hooks and /security'],
25
25
  ['plugin', 'why prompted: install/update lifecycle, provenance, capability grants', 'review via /marketplace and /security'],
26
26
  ] as const;
@@ -88,7 +88,7 @@ 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 runtime-owned automation jobs from Agent' },
91
+ { command: '/schedule receipts', summary: 'review Agent routine promotion receipts' },
92
92
  ];
93
93
  }
94
94
 
@@ -217,7 +217,7 @@ export async function buildProviderAccountSnapshot(
217
217
  }
218
218
  if (hasServiceOAuth && !serviceOauth?.usable) {
219
219
  issues.push('Service OAuth is configured but missing a usable credential.');
220
- recommendedActions.push(`Repair service OAuth credentials for ${providerId} in /services or /settings.`);
220
+ recommendedActions.push(`Repair service OAuth credentials for ${providerId} in /settings or the external runtime host.`);
221
221
  }
222
222
 
223
223
  return {
@@ -55,8 +55,8 @@ export function buildProviderHealthDomainSummaries(
55
55
  auth.bootstrapCredentialPresent ? 'Runtime bootstrap cleanup must be done from the runtime-owning TUI or host tooling.' : '',
56
56
  ].filter(Boolean),
57
57
  nextSteps: auth.bootstrapCredentialPresent
58
- ? ['/auth review', '/providers', '/subscription providers']
59
- : ['/auth review', '/providers'],
58
+ ? ['/auth review', '/provider', '/subscription providers']
59
+ : ['/auth review', '/provider'],
60
60
  });
61
61
 
62
62
  const settingIssueCount = settings.conflictCount + settings.recentFailureCount + (settings.hasStagedManagedBundle ? 1 : 0);
@@ -68,7 +68,7 @@ export function buildProviderHealthDomainSummaries(
68
68
  : settingIssueCount > 0
69
69
  ? `${settings.conflictCount} conflicts / ${settings.recentFailureCount} failures${settings.hasStagedManagedBundle ? ' / staged bundle' : ''}`
70
70
  : 'settings runtime API clean',
71
- next: settingIssueCount > 0 ? '/settingssync panel' : '/settingssync show <key>',
71
+ next: settingIssueCount > 0 ? '/settings' : '/config <key>',
72
72
  details: [
73
73
  settings.conflictCount > 0 ? `${settings.conflictCount} unresolved import conflict(s)` : '',
74
74
  settings.recentFailureCount > 0 ? `${settings.recentFailureCount} recent sync or managed failure(s)` : '',
@@ -76,8 +76,8 @@ export function buildProviderHealthDomainSummaries(
76
76
  settings.managedLockCount > 0 ? `${settings.managedLockCount} managed lock(s) enforced` : '',
77
77
  ].filter(Boolean),
78
78
  nextSteps: settingIssueCount > 0
79
- ? ['/settingssync panel', '/settingssync show <key>', '/managed staged']
80
- : ['/settingssync show <key>'],
79
+ ? ['/settings', '/config <key>', '/health settings']
80
+ : ['/config <key>'],
81
81
  });
82
82
 
83
83
  summaries.push({
@@ -86,7 +86,7 @@ export function buildProviderHealthDomainSummaries(
86
86
  summary: remote.supervisor.sessions.length === 0
87
87
  ? 'no remote sessions tracked'
88
88
  : `${remote.supervisor.sessions.length} sessions / ${remote.supervisor.degradedConnections} degraded`,
89
- next: remote.supervisor.degradedConnections > 0 ? '/remote recover <workerId>' : '/remote supervisor',
89
+ next: remote.supervisor.degradedConnections > 0 ? '/delegate <build/fix/review task>' : '/health remote',
90
90
  details: remote.supervisor.sessions.length === 0
91
91
  ? ['no remote sessions have been attached yet']
92
92
  : remote.supervisor.sessions
@@ -99,8 +99,8 @@ export function buildProviderHealthDomainSummaries(
99
99
  .slice(0, 3)
100
100
  .map((entry) => `${entry.runnerId}: transport=${entry.transportState} heartbeat=${entry.heartbeat.status}${entry.lastError ? ` error=${entry.lastError}` : ''}`),
101
101
  nextSteps: remote.supervisor.degradedConnections > 0
102
- ? ['/remote supervisor', '/remote recover <workerId>', '/remote support']
103
- : ['/remote supervisor'],
102
+ ? ['/delegate <build/fix/review task>', '/health remote']
103
+ : ['/health remote'],
104
104
  });
105
105
 
106
106
  const degradedServers = security.mcpServers.filter((server) =>
@@ -141,7 +141,7 @@ export function buildProviderHealthDomainSummaries(
141
141
  ? 'warn'
142
142
  : 'good',
143
143
  summary: maintenance.summary,
144
- next: maintenance.nextSteps[0] ?? '/guidance review',
144
+ next: maintenance.nextSteps[0] ?? '/health maintenance',
145
145
  details: maintenance.reasons.slice(0, 3),
146
146
  nextSteps: maintenance.nextSteps,
147
147
  });
@@ -266,7 +266,7 @@ export class SessionBrowserPanel extends BasePanel {
266
266
  ...formatReturnContextLines(selected.returnContext).map((line) =>
267
267
  buildPanelLine(width, [[' ', DEFAULT_PANEL_PALETTE.dim], [truncateDisplay(line, Math.max(0, width - 2)), DEFAULT_PANEL_PALETTE.dim]])
268
268
  ),
269
- buildPanelLine(width, [[' Next ', DEFAULT_PANEL_PALETTE.label], [selected.returnContext?.remoteRunners?.length ? `/remote recover ${selected.returnContext.remoteRunners[0]}` : '/session resume', DEFAULT_PANEL_PALETTE.dim]]),
269
+ buildPanelLine(width, [[' Next ', DEFAULT_PANEL_PALETTE.label], ['/session resume', DEFAULT_PANEL_PALETTE.dim]]),
270
270
  ],
271
271
  }
272
272
  : { title: 'Selected', lines: [] };
@@ -76,13 +76,13 @@ export function evaluateSessionMaintenance(input: PanelSessionMaintenanceInput):
76
76
  level = 'needs-repair';
77
77
  summary = `Compact now to recover context headroom (${usagePct}% used).`;
78
78
  reasons.push(`Context pressure is high at ${usagePct}% usage.`);
79
- nextSteps.push('/compact', '/panel tokens');
79
+ nextSteps.push('/compact', '/context');
80
80
  compactRecommended = true;
81
81
  } else if (usagePct >= thresholdPct || remainingTokens <= 15_000) {
82
82
  level = 'suggest-compact';
83
83
  summary = `Watch context growth (${usagePct}% used).`;
84
84
  reasons.push(`Context pressure is climbing at ${usagePct}% usage.`);
85
- nextSteps.push('/panel tokens');
85
+ nextSteps.push('/context');
86
86
  compactRecommended = true;
87
87
  } else if (usagePct >= 70 || staleByMessageGrowth) {
88
88
  level = 'watch';
@@ -92,7 +92,7 @@ export function evaluateSessionMaintenance(input: PanelSessionMaintenanceInput):
92
92
  reasons.push(staleByMessageGrowth
93
93
  ? `Conversation has grown ${messageCount.toLocaleString()} messages since the last maintenance checkpoint.`
94
94
  : `Context usage is climbing toward the ${thresholdPct}% maintenance threshold.`);
95
- nextSteps.push('/panel tokens');
95
+ nextSteps.push('/context');
96
96
  } else {
97
97
  reasons.push('Context pressure is currently within the stable operating band.');
98
98
  }
@@ -80,7 +80,7 @@ export class SubscriptionPanel extends ScrollableListPanel<SubscriptionRow> {
80
80
  return [
81
81
  { command: '/subscription login openai start --yes', summary: 'start the first-class OpenAI subscription flow' },
82
82
  { command: '/login provider <name> start --yes', summary: 'use the front-door auth flow for supported providers' },
83
- { command: '/services auth-review', summary: 'inspect configured service auth posture and stored secrets' },
83
+ { command: '/auth review', summary: 'inspect runtime auth posture without exposing token values' },
84
84
  ];
85
85
  }
86
86
 
@@ -232,7 +232,7 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
232
232
  });
233
233
  }
234
234
  base.push({ text: 'Only config key names and readiness state are rendered here.', fg: PALETTE.muted });
235
- base.push({ text: 'Pairing: use /pair or /qrcode; inspect routed activity with /communication and /setup review.', fg: PALETTE.info });
235
+ base.push({ text: 'Pairing: use /pair or /qrcode; inspect notification targets with /notify list and health with /health review.', fg: PALETTE.info });
236
236
  } else if (category.id === 'knowledge') {
237
237
  base.push(
238
238
  { text: `Route family: ${snapshot.knowledgeRoute}/{status,ask,search}`, fg: PALETTE.info },
@@ -69,21 +69,23 @@ export function renderHelpOverlay(
69
69
  // Each entry is [commandName, subcommandOrArgHint, description].
70
70
  // Commands not registered in the live registry are omitted at render time.
71
71
  const FEATURED_COMMANDS: Array<[name: string, argHint: string, desc: string]> = [
72
- ['onboarding', '', 'Open the onboarding wizard with current settings preloaded'],
73
- ['cockpit', '', 'Unified runtime control room'],
74
- ['settings', '', 'Settings and config browser'],
72
+ ['agent', '', 'Open the Agent operator workspace'],
73
+ ['onboarding', '', 'Open Agent setup with current settings preloaded'],
74
+ ['knowledge', 'status', 'Inspect isolated Agent Knowledge readiness'],
75
+ ['memory', '', 'Manage local Agent memory records'],
76
+ ['personas', '', 'Manage serial Agent operating personas'],
77
+ ['agent-skills', '', 'Manage local Agent skills and bundles'],
78
+ ['routines', '', 'Manage reusable main-conversation routines'],
79
+ ['workplan', '', 'Inspect shared work-plan state'],
80
+ ['approval', '', 'Review and explicitly act on approvals'],
81
+ ['schedule', '', 'Inspect schedules and routine promotion receipts'],
82
+ ['delegate', '', 'Explicitly hand build/fix/review work to GoodVibes TUI'],
83
+ ['mcp', '', 'Inspect MCP servers and tool readiness'],
75
84
  ['provider', '', 'Choose provider or model family'],
85
+ ['model', '', 'Select the active model route'],
76
86
  ['subscription', '', 'Review provider logins and subscriptions'],
77
- ['marketplace', 'open', 'Browse plugins, skills, and packs'],
78
- ['remote', 'setup', 'Review remote, bridge, and tunnel flows'],
79
- ['security', '', 'Security review workspace'],
80
- ['policy', '', 'Simulation, lint, and preflight review'],
81
- ['incident', '', 'Incident workspace and export flows'],
82
- ['knowledge', '', 'Durable knowledge and review queue'],
83
- ['hooks', '', 'Hook workbench and runtime activity'],
84
- ['orchestration','', 'Graph and recursive-agent control room'],
85
- ['communication','', 'Structured agent communication workspace'],
86
- ['tasks', '', 'Read-only task view for list/show/pause/resume/output'],
87
+ ['secrets', '', 'Manage secret references without printing values'],
88
+ ['health', '', 'Run Agent runtime and setup diagnostics'],
87
89
  ];
88
90
 
89
91
  // Build command rows from featured list, filtering out unregistered commands.
@@ -115,7 +117,29 @@ export function renderHelpOverlay(
115
117
 
116
118
  if (commands && commands.length > 0) {
117
119
  commandRows.push('', ' Available Slash Commands', ' ' + '\u2500'.repeat(40));
118
- const preferred = ['setup', 'cockpit', 'settings', 'provider', 'subscription', 'marketplace', 'remote', 'security', 'policy', 'incident', 'knowledge', 'hooks', 'orchestration', 'communication', 'tasks'];
120
+ const preferred = [
121
+ 'agent',
122
+ 'onboarding',
123
+ 'knowledge',
124
+ 'memory',
125
+ 'personas',
126
+ 'agent-skills',
127
+ 'routines',
128
+ 'workplan',
129
+ 'approval',
130
+ 'schedule',
131
+ 'delegate',
132
+ 'mcp',
133
+ 'provider',
134
+ 'model',
135
+ 'subscription',
136
+ 'secrets',
137
+ 'health',
138
+ 'settings',
139
+ 'security',
140
+ 'policy',
141
+ 'tasks',
142
+ ];
119
143
  const seen = new Set<string>();
120
144
  for (const name of preferred) {
121
145
  const cmd = commands.find((entry) => entry.name === name);
@@ -148,7 +148,7 @@ function buildSettingContext(modal: SettingsModal, entry: SettingEntry): string[
148
148
  ];
149
149
 
150
150
  if (entry.locked) lines.push(`Locked: ${entry.lockReason ?? 'This setting is locked by a higher-priority layer.'}`);
151
- if (entry.conflict) lines.push(`Conflict: resolve with /settingssync resolve ${entry.setting.key} local|synced.`);
151
+ if (entry.conflict) lines.push(`Conflict: inspect with /settings and resolve runtime-owned sync state in the external host.`);
152
152
 
153
153
  lines.push('', entry.setting.description);
154
154
 
@@ -74,7 +74,7 @@ export function createResumeSessionHandler(options: ResumeSessionOptions): (sess
74
74
  options.conversation.log(`Resume: Reopened panels: ${reopenedPanels.join(', ')}`, { fg: '244' });
75
75
  }
76
76
  if ((meta.returnContext.remoteRunners?.length ?? 0) > 0) {
77
- options.conversation.log(`Resume: Remote re-entry -> /remote recover ${meta.returnContext.remoteRunners![0]}`, { fg: '244' });
77
+ options.conversation.log('Resume: Remote re-entry belongs to the external runtime host; delegate explicit build/fix/review recovery from Agent.', { fg: '244' });
78
78
  }
79
79
  if (returnContextMode === 'assisted') {
80
80
  const helperModel = new HelperModel({
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.88';
9
+ let _version = '0.1.90';
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 {