@pellux/goodvibes-agent 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/package.json +1 -1
  3. package/src/cli/agent-knowledge-command.ts +30 -3
  4. package/src/cli/help.ts +2 -2
  5. package/src/input/commands/cloudflare-runtime.ts +20 -5
  6. package/src/input/commands/confirmation.ts +24 -0
  7. package/src/input/commands/discovery-runtime.ts +16 -7
  8. package/src/input/commands/eval.ts +27 -14
  9. package/src/input/commands/experience-runtime.ts +65 -26
  10. package/src/input/commands/health-runtime.ts +1 -1
  11. package/src/input/commands/hooks-runtime.ts +50 -19
  12. package/src/input/commands/incident-runtime.ts +17 -6
  13. package/src/input/commands/integration-runtime.ts +93 -50
  14. package/src/input/commands/knowledge.ts +38 -12
  15. package/src/input/commands/local-auth-runtime.ts +36 -13
  16. package/src/input/commands/local-provider-runtime.ts +22 -11
  17. package/src/input/commands/local-runtime.ts +21 -11
  18. package/src/input/commands/local-setup.ts +35 -16
  19. package/src/input/commands/managed-runtime.ts +51 -20
  20. package/src/input/commands/marketplace-runtime.ts +31 -16
  21. package/src/input/commands/mcp-runtime.ts +65 -34
  22. package/src/input/commands/memory-product-runtime.ts +72 -35
  23. package/src/input/commands/memory.ts +9 -9
  24. package/src/input/commands/notify-runtime.ts +27 -8
  25. package/src/input/commands/operator-runtime.ts +85 -17
  26. package/src/input/commands/planning-runtime.ts +14 -2
  27. package/src/input/commands/platform-access-runtime.ts +88 -45
  28. package/src/input/commands/platform-services-runtime.ts +51 -25
  29. package/src/input/commands/product-runtime.ts +54 -27
  30. package/src/input/commands/profile-sync-runtime.ts +17 -6
  31. package/src/input/commands/recall-bundle.ts +38 -17
  32. package/src/input/commands/recall-query.ts +15 -4
  33. package/src/input/commands/recall-review.ts +9 -3
  34. package/src/input/commands/remote-runtime-setup.ts +45 -18
  35. package/src/input/commands/remote-runtime.ts +25 -9
  36. package/src/input/commands/replay-runtime.ts +9 -2
  37. package/src/input/commands/services-runtime.ts +21 -10
  38. package/src/input/commands/session-content.ts +53 -51
  39. package/src/input/commands/session-workflow.ts +10 -4
  40. package/src/input/commands/session.ts +1 -1
  41. package/src/input/commands/settings-sync-runtime.ts +40 -17
  42. package/src/input/commands/share-runtime.ts +12 -4
  43. package/src/input/commands/shell-core.ts +3 -3
  44. package/src/input/commands/subscription-runtime.ts +35 -20
  45. package/src/input/commands/teleport-runtime.ts +16 -5
  46. package/src/input/commands/work-plan-runtime.ts +23 -12
  47. package/src/input/handler-content-actions.ts +11 -62
  48. package/src/input/handler-interactions.ts +1 -1
  49. package/src/input/handler-onboarding-cloudflare.ts +48 -117
  50. package/src/input/keybindings.ts +1 -1
  51. package/src/input/mcp-workspace.ts +25 -49
  52. package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +8 -8
  53. package/src/input/onboarding/onboarding-wizard-cloudflare.ts +1 -6
  54. package/src/input/profile-picker-modal.ts +13 -31
  55. package/src/input/session-picker-modal.ts +4 -30
  56. package/src/input/settings-modal-subscriptions.ts +3 -3
  57. package/src/panels/incident-review-panel.ts +1 -1
  58. package/src/panels/local-auth-panel.ts +4 -4
  59. package/src/panels/provider-account-snapshot.ts +1 -1
  60. package/src/panels/provider-health-domains.ts +2 -2
  61. package/src/panels/settings-sync-panel.ts +2 -2
  62. package/src/panels/subscription-panel.ts +7 -7
  63. package/src/renderer/block-actions.ts +1 -1
  64. package/src/renderer/help-overlay.ts +2 -2
  65. package/src/renderer/mcp-workspace.ts +12 -12
  66. package/src/renderer/profile-picker-modal.ts +3 -11
  67. package/src/renderer/session-picker-modal.ts +2 -10
  68. package/src/version.ts +1 -1
@@ -209,7 +209,7 @@ export async function buildProviderAccountSnapshot(
209
209
  }
210
210
  if (pending) {
211
211
  issues.push('Provider has a pending OAuth login that has not been completed yet.');
212
- recommendedActions.push(`Finish /subscription login ${providerId} finish <code> or clear the pending login.`);
212
+ recommendedActions.push(`Finish /subscription login ${providerId} finish <code> --yes or clear the pending login.`);
213
213
  }
214
214
  if (hasSubscription && hasApiKey) {
215
215
  issues.push('Provider has both subscription and API-key auth paths; routing must remain explicit.');
@@ -54,13 +54,13 @@ export function buildProviderHealthDomainSummaries(
54
54
  summary: auth.bootstrapCredentialPresent
55
55
  ? 'bootstrap credential file still present'
56
56
  : `${auth.userCount} users / ${auth.sessionCount} sessions`,
57
- next: auth.bootstrapCredentialPresent ? '/auth local clear-bootstrap-file' : '/auth local review',
57
+ next: auth.bootstrapCredentialPresent ? '/auth local clear-bootstrap-file --yes' : '/auth local review',
58
58
  details: [
59
59
  auth.bootstrapCredentialPresent ? 'bootstrap credential file should be cleared after rotation' : `${auth.userCount} local auth users configured`,
60
60
  auth.userCount <= 1 ? 'only one local auth user configured' : `${auth.sessionCount} active local auth sessions`,
61
61
  ].filter(Boolean),
62
62
  nextSteps: auth.bootstrapCredentialPresent
63
- ? ['/auth local review', '/auth local rotate-password <user> <password>', '/auth local clear-bootstrap-file']
63
+ ? ['/auth local review', '/auth local rotate-password <user> <password> --yes', '/auth local clear-bootstrap-file --yes']
64
64
  : ['/auth local review'],
65
65
  });
66
66
 
@@ -86,7 +86,7 @@ export class SettingsSyncPanel extends ScrollableListPanel<ResolvedEntry> {
86
86
  : [buildPanelLine(width, [[' No recent sync or managed-setting failures.', C.dim]])]),
87
87
  // Conflicts
88
88
  ...(snapshot.conflicts.length > 0
89
- ? snapshot.conflicts.map((conflict) => buildPanelLine(width, [[` ${conflict.key}`.padEnd(30), C.value], [` ${conflict.source}`.padEnd(10), C.warn], [` resolve: /settingssync resolve ${conflict.key} local|synced`.slice(0, Math.max(0, width - 42)), C.dim]]))
89
+ ? snapshot.conflicts.map((conflict) => buildPanelLine(width, [[` ${conflict.key}`.padEnd(30), C.value], [` ${conflict.source}`.padEnd(10), C.warn], [` resolve: /settingssync resolve ${conflict.key} local|synced --yes`.slice(0, Math.max(0, width - 42)), C.dim]]))
90
90
  : [buildPanelLine(width, [[' No settings conflicts detected.', C.dim]])]),
91
91
  // Rollback History
92
92
  ...(snapshot.rollbackHistory.length > 0
@@ -108,7 +108,7 @@ export class SettingsSyncPanel extends ScrollableListPanel<ResolvedEntry> {
108
108
  buildPanelLine(width, [[' managed ', C.label], [String(selectedEntry.managedValue ?? '(unset)').slice(0, Math.max(0, width - 11)), C.warn]]),
109
109
  ], C)
110
110
  : []),
111
- buildPanelLine(width, [[' ↑/↓ browse /settingssync show <key> /settingssync resolve <key> <local|synced> /managed apply-staged [key...] ', C.dim]]),
111
+ buildPanelLine(width, [[' ↑/↓ browse /settingssync show <key> mutations require --yes: resolve/apply-staged ', C.dim]]),
112
112
  ];
113
113
 
114
114
  return this.renderList(width, height, {
@@ -78,8 +78,8 @@ export class SubscriptionPanel extends ScrollableListPanel<SubscriptionRow> {
78
78
  protected override getEmptyStateMessage() { return ' No provider subscriptions are active yet.'; }
79
79
  protected override getEmptyStateActions() {
80
80
  return [
81
- { command: '/subscription login openai start', summary: 'start the first-class OpenAI subscription flow' },
82
- { command: '/login provider <name> start', summary: 'use the front-door auth surface for supported providers' },
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' },
83
83
  { command: '/services auth-review', summary: 'inspect configured service auth posture and stored secrets' },
84
84
  ];
85
85
  }
@@ -187,7 +187,7 @@ export class SubscriptionPanel extends ScrollableListPanel<SubscriptionRow> {
187
187
  { label: 'selected', value: (this.rows[this.selectedIndex]?.provider ?? 'none'), valueColor: this.rows[this.selectedIndex] ? C.value : C.dim },
188
188
  { label: 'status', value: this.rows[this.selectedIndex] ? statusOf(this.rows[this.selectedIndex]!) : 'n/a', valueColor: this.rows[this.selectedIndex] ? statusColor(statusOf(this.rows[this.selectedIndex]!)) : C.dim },
189
189
  ], C),
190
- buildGuidanceLine(width, '/subscription login <provider> start', 'start or repair browser login for the selected provider route', C),
190
+ buildGuidanceLine(width, '/subscription login <provider> start --yes', 'start or repair browser login for the selected provider route', C),
191
191
  ];
192
192
 
193
193
  // Empty state: render posture + base empty state
@@ -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', '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 surface', C),
209
209
  buildPanelLine(width, [[' Up/Down move Enter/X sign out selected provider r refresh', C.dim]]),
210
210
  ],
211
211
  palette: C,
@@ -240,9 +240,9 @@ export class SubscriptionPanel extends ScrollableListPanel<SubscriptionRow> {
240
240
  detailRows.push(buildPanelLine(width, [[` Press Enter or X again to sign out ${selectedRow.provider}.`, C.warn]]));
241
241
  }
242
242
  } else if (selectedRow.pending) {
243
- detailRows.push(buildPanelLine(width, [[' Login is pending. Finish with /subscription login <provider> finish <code>.', C.warn]]));
243
+ detailRows.push(buildPanelLine(width, [[' Login is pending. Finish with /subscription login <provider> finish <code> --yes.', C.warn]]));
244
244
  } else if (selectedRow.hasOAuthConfig) {
245
- detailRows.push(buildPanelLine(width, [[' Ready for login. Start with /subscription login <provider> start.', C.dim]]));
245
+ detailRows.push(buildPanelLine(width, [[' Ready for login. Start with /subscription login <provider> start --yes.', C.dim]]));
246
246
  } else {
247
247
  detailRows.push(buildPanelLine(width, [[' Add a provider-specific OAuth config or enable a built-in subscription provider to use subscription login.', C.bad]]));
248
248
  }
@@ -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', '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 surface', C),
259
259
  buildPanelLine(width, [[' Up/Down move Enter/X sign out selected provider r refresh', C.dim]]),
260
260
  ],
261
261
  });
@@ -12,7 +12,7 @@ const ALL_ACTIONS: BlockAction[] = [
12
12
  { id: 'copy', label: 'Copy', key: 'c' },
13
13
  { id: 'bookmark', label: 'Bookmark', key: 'b' },
14
14
  { id: 'toggle', label: 'Collapse/Expand',key: 'Tab' },
15
- { id: 'apply', label: 'Apply diff', key: 'a' },
15
+ { id: 'apply', label: 'Diff apply blocked', key: 'a' },
16
16
  { id: 'rerun', label: 'Re-run tool', key: 'r' },
17
17
  ];
18
18
 
@@ -215,7 +215,7 @@ export function renderShortcutsOverlay(
215
215
  row(kb('clear-prompt'), 'Clear prompt'),
216
216
  row(kb('delete-word'), 'Delete word backward'),
217
217
  row(kb('kill-line'), 'Kill to end of line'),
218
- row(kb('apply-diff-line-start'), 'Apply diff / line start'),
218
+ row(kb('apply-diff-line-start'), 'Diff apply blocked / line start'),
219
219
  row(kb('next-error-line-end'), 'Next error / line end'),
220
220
  '',
221
221
  ' Actions',
@@ -223,7 +223,7 @@ export function renderShortcutsOverlay(
223
223
  row('Tab', 'Collapse/expand block'),
224
224
  row(kb('bookmark'), 'Bookmark block'),
225
225
  row(kb('block-copy'), 'Copy block to clipboard'),
226
- row(kb('block-save'), 'Save block to file'),
226
+ row(kb('block-save'), 'Block save blocked; use /share --yes'),
227
227
  row(kb('copy-selection'), 'Copy selection'),
228
228
  row('F2', 'Process monitor'),
229
229
  row('?', 'Help overlay'),
@@ -82,16 +82,16 @@ function selectedDetailLines(workspace: McpWorkspace, width: number): WorkspaceR
82
82
  if (workspace.mode === 'form') {
83
83
  const field = workspace.formFields[workspace.formIndex];
84
84
  lines.push(
85
- workspace.editingServerName ? `Editing server: ${workspace.editingServerName}` : 'Adding an MCP server',
86
- 'Write a server through the SDK MCP config manager, then reload the live runtime without restarting the TUI.',
85
+ workspace.editingServerName ? `Previewing server: ${workspace.editingServerName}` : 'Drafting an MCP server command',
86
+ 'Workspace writes/reloads are blocked. Use the generated /mcp add ... --yes command from the prompt.',
87
87
  field ? `${field.label}: ${field.help}` : '',
88
- 'Project scope writes to this workspace. Global scope writes to your user MCP config. External Claude/Desktop config files are shown but not edited here.',
88
+ 'Project/global config locations are shown for review. This workspace does not write or reload MCP config.',
89
89
  );
90
90
  } else if (workspace.mode === 'delete-confirm') {
91
91
  lines.push(
92
- `Remove configured server: ${workspace.editingServerName ?? '(unknown)'}`,
93
- 'This removes the selected writable project/global config entry and reloads MCP runtime state.',
94
- 'Press y to remove, n or Esc to cancel.',
92
+ `Removal blocked for server: ${workspace.editingServerName ?? '(unknown)'}`,
93
+ 'Use /mcp remove <server> --scope <project|global> --yes from the prompt for explicit removal.',
94
+ 'Press n or Esc to return.',
95
95
  );
96
96
  } else {
97
97
  const selected = workspace.selectedRow;
@@ -207,19 +207,19 @@ function buildControlRows(workspace: McpWorkspace, width: number, height: number
207
207
  }
208
208
 
209
209
  function footerText(workspace: McpWorkspace): string {
210
- if (workspace.mode === 'form') return 'Focus server form · Up/Down field · Left/Right cycle · Type edit · Enter save/cancel row · Esc back';
211
- if (workspace.mode === 'delete-confirm') return 'Focus remove confirmation · y confirm · n/Esc cancel';
212
- return 'Focus MCP workspace · Up/Down choose · Enter edit/action · a add · d remove · r reload · t tools · Esc close';
210
+ if (workspace.mode === 'form') return 'Focus server command preview · Up/Down field · Left/Right cycle · Type edit · Enter show command · Esc back';
211
+ if (workspace.mode === 'delete-confirm') return 'Focus remove guidance · n/Esc cancel';
212
+ return 'Focus MCP workspace · Up/Down choose · Enter view/action · a draft · d removal command · r reload command · t tools · Esc close';
213
213
  }
214
214
 
215
215
  export function renderMcpWorkspace(workspace: McpWorkspace, width: number, height: number): Line[] {
216
216
  const metrics = getFullscreenWorkspaceMetrics({ width, height });
217
217
  const connected = workspace.servers.filter((server) => server.connected).length;
218
- const stateLabel = workspace.mode === 'browse' ? 'Browse' : workspace.mode === 'form' ? 'Edit Server' : 'Confirm Remove';
218
+ const stateLabel = workspace.mode === 'browse' ? 'Browse' : workspace.mode === 'form' ? 'Command Preview' : 'Remove Guidance';
219
219
  const mainHeader = workspace.mode === 'form'
220
- ? 'MCP server form'
220
+ ? 'MCP server command preview'
221
221
  : workspace.mode === 'delete-confirm'
222
- ? 'Remove MCP server'
222
+ ? 'MCP remove command'
223
223
  : `Servers ${connected}/${workspace.servers.length} connected · Tools ${workspace.tools.length}`;
224
224
 
225
225
  return renderFullscreenWorkspace({
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Shows a list of saved profiles with:
6
6
  * - name, timestamp (formatted), settings preview
7
- * Footer hints: [Up/Down] Navigate [Enter] Load [d] Arm/Delete [s] Save current [Esc] Close
7
+ * Footer hints: [Up/Down] Navigate [Enter] Load [Esc] Close
8
8
  */
9
9
 
10
10
  import type { Line } from '../types/grid.ts';
@@ -51,7 +51,7 @@ export function renderProfilePickerModal(
51
51
  });
52
52
  sections.push({
53
53
  type: 'text',
54
- content: 'Press [s] to save the current settings as a profile.',
54
+ content: 'Use /profiles save <name> --yes to save the current settings as a profile.',
55
55
  style: { fg: '240', dim: true },
56
56
  });
57
57
  } else {
@@ -107,14 +107,6 @@ export function renderProfilePickerModal(
107
107
  style: { fg: '#00ffcc' },
108
108
  });
109
109
  }
110
- if (modal.deleteConfirmationTarget) {
111
- sections.push({
112
- type: 'text',
113
- content: `Press [d] again to permanently delete ${modal.deleteConfirmationTarget}.`,
114
- style: { fg: '#f59e0b', dim: true },
115
- });
116
- }
117
-
118
110
  return ModalFactory.createModal(
119
111
  {
120
112
  title: 'Profiles',
@@ -122,7 +114,7 @@ export function renderProfilePickerModal(
122
114
  margin: boxMargin,
123
115
  targetContentRows,
124
116
  sections,
125
- hints: ['[Up/Down] Navigate', '[Enter] Load', '[d] Arm/Delete', '[s] Save current', '[Esc] Close'],
117
+ hints: ['[Up/Down] Navigate', '[Enter] Load', '/profiles save|delete --yes', '[Esc] Close'],
126
118
  },
127
119
  width,
128
120
  );
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Shows a list of saved sessions with:
6
6
  * - name, timestamp (formatted), message count
7
- * Footer hints: [Enter] Load [d] Delete [Esc] Close
7
+ * Footer hints: [Enter] Load [Esc] Close
8
8
  */
9
9
 
10
10
  import type { Line } from '../types/grid.ts';
@@ -105,14 +105,6 @@ export function renderSessionPickerModal(
105
105
  });
106
106
  }
107
107
 
108
- if (modal.deleteConfirmationTarget) {
109
- sections.push({
110
- type: 'text',
111
- content: `Deletion is armed for ${modal.deleteConfirmationTarget}. Move selection or press Esc to cancel.`,
112
- style: { fg: '244', dim: true },
113
- });
114
- }
115
-
116
108
  return ModalFactory.createModal(
117
109
  {
118
110
  title: 'Sessions',
@@ -120,7 +112,7 @@ export function renderSessionPickerModal(
120
112
  margin: boxMargin,
121
113
  targetContentRows,
122
114
  sections,
123
- hints: ['[\u2191\u2193] Navigate', '[Enter] Load', '[d] Arm / Delete', '[Esc] Close'],
115
+ hints: ['[\u2191\u2193] Navigate', '[Enter] Load', 'Delete: /session delete <id> --yes', '[Esc] Close'],
124
116
  },
125
117
  width,
126
118
  );
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.10';
9
+ let _version = '0.1.11';
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 {